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/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..75b5248
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   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.

diff --git a/Readme.txt b/Readme.txt
deleted file mode 100644
index ecb2e62..0000000
--- a/Readme.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-This repository contains the SwiftShader source code. It was licensed from

-TransGaming Inc. for use in conjunction with Google products, and should be

-treated as internal closed source.

-

-SwiftShader is a pure software implementation of OpenGL and Direct3D.

-It is used by Chrome for WebGL support with a blacklisted GPU, and by Looking

-Glass for running Windows applications on a VM without GPU support for

-streaming to Chromebooks.

-

-Watermark free versions of the SwiftShader builds should not be deployed on

-consumer systems! The watermark allows people to evaluate SwiftShader and

-license it from TransGaming if it suits their needs. Chrome has SwiftShader

-DLLs which are installed on consumer systems, but Chrome issues a license key

-to disable the watermark, so that with any other application the logo pops up.

-

-                                                              - capn@google.com
\ No newline at end of file
diff --git a/src/Common/CPUID.cpp b/src/Common/CPUID.cpp
index e2879e2..23d76d6 100644
--- a/src/Common/CPUID.cpp
+++ b/src/Common/CPUID.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "CPUID.hpp"
 
@@ -164,7 +167,7 @@
 		#if defined(_WIN32)
 			__cpuid(registers, info);
 		#else
-            __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
+			__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
 		#endif
 	}
 
diff --git a/src/Common/CPUID.hpp b/src/Common/CPUID.hpp
index 43c9e69..73c8e94 100644
--- a/src/Common/CPUID.hpp
+++ b/src/Common/CPUID.hpp
@@ -1,130 +1,133 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_CPUID_hpp

-#define sw_CPUID_hpp

-

-namespace sw

-{

-	#if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))

-		#define __x86_64__ 1

-	#endif

-

-	class CPUID

-	{

-	public:

-		static bool supportsMMX();

-		static bool supportsCMOV();

-		static bool supportsMMX2();   // MMX instructions added by SSE: pshufw, pmulhuw, pmovmskb, pavgw/b, pextrw, pinsrw, pmaxsw/ub, etc.

-		static bool supportsSSE();

-		static bool supportsSSE2();

-		static bool supportsSSE3();

-		static bool supportsSSSE3();

-		static bool supportsSSE4_1();

-		static int coreCount();

-		static int processAffinity();

-

-		static void setEnableMMX(bool enable);

-		static void setEnableCMOV(bool enable);

-		static void setEnableSSE(bool enable);

-		static void setEnableSSE2(bool enable);

-		static void setEnableSSE3(bool enable);

-		static void setEnableSSSE3(bool enable);

-		static void setEnableSSE4_1(bool enable);

-

-		static void setFlushToZero(bool enable);        // Denormal results are written as zero

-		static void setDenormalsAreZero(bool enable);   // Denormal inputs are read as zero

-

-	private:

-		static bool MMX;

-		static bool CMOV;

-		static bool SSE;

-		static bool SSE2;

-		static bool SSE3;

-		static bool SSSE3;

-		static bool SSE4_1;

-		static int cores;

-		static int affinity;

-

-		static bool enableMMX;

-		static bool enableCMOV;

-		static bool enableSSE;

-		static bool enableSSE2;

-		static bool enableSSE3;

-		static bool enableSSSE3;

-		static bool enableSSE4_1;

-

-		static bool detectMMX();

-		static bool detectCMOV();

-		static bool detectSSE();

-		static bool detectSSE2();

-		static bool detectSSE3();

-		static bool detectSSSE3();

-		static bool detectSSE4_1();

-		static int detectCoreCount();

-		static int detectAffinity();

-	};

-}

-

-namespace sw

-{

-	inline bool CPUID::supportsMMX()

-	{

-		return MMX && enableMMX;

-	}

-

-	inline bool CPUID::supportsCMOV()

-	{

-		return CMOV && enableCMOV;

-	}

-

-	inline bool CPUID::supportsMMX2()

-	{

-		return supportsSSE();   // Coincides with 64-bit integer vector instructions supported by SSE

-	}

-

-	inline bool CPUID::supportsSSE()

-	{

-		return SSE && enableSSE;

-	}

-

-	inline bool CPUID::supportsSSE2()

-	{

-		return SSE2 && enableSSE2;

-	}

-

-	inline bool CPUID::supportsSSE3()

-	{

-		return SSE3 && enableSSE3;

-	}

-

-	inline bool CPUID::supportsSSSE3()

-	{

-		return SSSE3 && enableSSSE3;

-	}

-

-	inline bool CPUID::supportsSSE4_1()

-	{

-		return SSE4_1 && enableSSE4_1;

-	}

-

-	inline int CPUID::coreCount()

-	{

-		return cores;

-	}

-

-	inline int CPUID::processAffinity()

-	{

-		return affinity;

-	}

-}

-

-#endif   // sw_CPUID_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_CPUID_hpp
+#define sw_CPUID_hpp
+
+namespace sw
+{
+	#if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
+		#define __x86_64__ 1
+	#endif
+
+	class CPUID
+	{
+	public:
+		static bool supportsMMX();
+		static bool supportsCMOV();
+		static bool supportsMMX2();   // MMX instructions added by SSE: pshufw, pmulhuw, pmovmskb, pavgw/b, pextrw, pinsrw, pmaxsw/ub, etc.
+		static bool supportsSSE();
+		static bool supportsSSE2();
+		static bool supportsSSE3();
+		static bool supportsSSSE3();
+		static bool supportsSSE4_1();
+		static int coreCount();
+		static int processAffinity();
+
+		static void setEnableMMX(bool enable);
+		static void setEnableCMOV(bool enable);
+		static void setEnableSSE(bool enable);
+		static void setEnableSSE2(bool enable);
+		static void setEnableSSE3(bool enable);
+		static void setEnableSSSE3(bool enable);
+		static void setEnableSSE4_1(bool enable);
+
+		static void setFlushToZero(bool enable);        // Denormal results are written as zero
+		static void setDenormalsAreZero(bool enable);   // Denormal inputs are read as zero
+
+	private:
+		static bool MMX;
+		static bool CMOV;
+		static bool SSE;
+		static bool SSE2;
+		static bool SSE3;
+		static bool SSSE3;
+		static bool SSE4_1;
+		static int cores;
+		static int affinity;
+
+		static bool enableMMX;
+		static bool enableCMOV;
+		static bool enableSSE;
+		static bool enableSSE2;
+		static bool enableSSE3;
+		static bool enableSSSE3;
+		static bool enableSSE4_1;
+
+		static bool detectMMX();
+		static bool detectCMOV();
+		static bool detectSSE();
+		static bool detectSSE2();
+		static bool detectSSE3();
+		static bool detectSSSE3();
+		static bool detectSSE4_1();
+		static int detectCoreCount();
+		static int detectAffinity();
+	};
+}
+
+namespace sw
+{
+	inline bool CPUID::supportsMMX()
+	{
+		return MMX && enableMMX;
+	}
+
+	inline bool CPUID::supportsCMOV()
+	{
+		return CMOV && enableCMOV;
+	}
+
+	inline bool CPUID::supportsMMX2()
+	{
+		return supportsSSE();   // Coincides with 64-bit integer vector instructions supported by SSE
+	}
+
+	inline bool CPUID::supportsSSE()
+	{
+		return SSE && enableSSE;
+	}
+
+	inline bool CPUID::supportsSSE2()
+	{
+		return SSE2 && enableSSE2;
+	}
+
+	inline bool CPUID::supportsSSE3()
+	{
+		return SSE3 && enableSSE3;
+	}
+
+	inline bool CPUID::supportsSSSE3()
+	{
+		return SSSE3 && enableSSSE3;
+	}
+
+	inline bool CPUID::supportsSSE4_1()
+	{
+		return SSE4_1 && enableSSE4_1;
+	}
+
+	inline int CPUID::coreCount()
+	{
+		return cores;
+	}
+
+	inline int CPUID::processAffinity()
+	{
+		return affinity;
+	}
+}
+
+#endif   // sw_CPUID_hpp
diff --git a/src/Common/Configurator.cpp b/src/Common/Configurator.cpp
index 2a8ad16..994d105 100644
--- a/src/Common/Configurator.cpp
+++ b/src/Common/Configurator.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Configurator.hpp"
 
@@ -189,7 +192,7 @@
 		}
 
 		int valueID = findValue(keyID, valueName);
-		
+
 		if(valueID == -1)
 		{
 			sections[keyID].names.resize(sections[keyID].names.size() + 1, valueName);
@@ -217,7 +220,7 @@
 
 		sprintf(svalue, "%d", defaultValue);
 
-		return atoi(getValue(keyName, valueName, svalue).c_str()); 
+		return atoi(getValue(keyName, valueName, svalue).c_str());
 	}
 
 	bool Configurator::getBoolean(string keyName, string valueName, bool defaultValue) const
@@ -231,7 +234,7 @@
 
 		sprintf(svalue, "%f", defaultValue);
 
-		return atof(getValue(keyName, valueName, svalue).c_str()); 
+		return atof(getValue(keyName, valueName, svalue).c_str());
 	}
 
 	unsigned int Configurator::getFormatted(string keyName, string valueName, char *format,
diff --git a/src/Common/Configurator.hpp b/src/Common/Configurator.hpp
index a9bf156..6fd930c 100644
--- a/src/Common/Configurator.hpp
+++ b/src/Common/Configurator.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_Configurator_hpp
 #define sw_Configurator_hpp
@@ -19,22 +22,22 @@
 
 namespace sw
 {
-	class Configurator  
+	class Configurator
 	{
 	public:
 		Configurator(std::string iniPath = "");
 
 		~Configurator();
 
-		std::string getValue(std::string sectionName, std::string valueName, std::string defaultValue = "") const; 
+		std::string getValue(std::string sectionName, std::string valueName, std::string defaultValue = "") const;
 		int getInteger(std::string sectionName, std::string valueName, int defaultValue = 0) const;
 		bool getBoolean(std::string sectionName, std::string valueName, bool defaultValue = false) const;
 		double getFloat(std::string sectionName, std::string valueName, double defaultValue = 0.0) const;
 		unsigned int getFormatted(std::string sectionName, std::string valueName, char *format,
-								void *v1 = 0, void *v2 = 0, void *v3 = 0, void *v4 = 0,
-  								void *v5 = 0, void *v6 = 0, void *v7 = 0, void *v8 = 0,
-  								void *v9 = 0, void *v10 = 0, void *v11 = 0, void *v12 = 0,
-  								void *v13 = 0, void *v14 = 0, void *v15 = 0, void *v16 = 0);
+		                          void *v1 = 0, void *v2 = 0, void *v3 = 0, void *v4 = 0,
+		                          void *v5 = 0, void *v6 = 0, void *v7 = 0, void *v8 = 0,
+		                          void *v9 = 0, void *v10 = 0, void *v11 = 0, void *v12 = 0,
+		                          void *v13 = 0, void *v14 = 0, void *v15 = 0, void *v16 = 0);
 
 		void addValue(std::string sectionName, std::string valueName, std::string value);
 
@@ -52,7 +55,7 @@
 		struct Section
 		{
 			std::vector<std::string> names;
-			std::vector<std::string> values; 
+			std::vector<std::string> values;
 		};
 
 		std::vector<Section> sections;
diff --git a/src/Common/Debug.cpp b/src/Common/Debug.cpp
index a122c42..c3a1921 100644
--- a/src/Common/Debug.cpp
+++ b/src/Common/Debug.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Debug.hpp"
 
diff --git a/src/Common/Debug.hpp b/src/Common/Debug.hpp
index 569e9a3..0632743 100644
--- a/src/Common/Debug.hpp
+++ b/src/Common/Debug.hpp
@@ -1,46 +1,49 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef Debug_hpp

-#define Debug_hpp

-

-#ifdef __ANDROID__

-#include "DebugAndroid.hpp"

-#else

-

-#include <assert.h>

-#include <stdio.h>

-

-#undef min

-#undef max

-

-void trace(const char *format, ...);

-

-#ifndef NDEBUG

-	#define TRACE(format, ...) trace("[0x%0.8X]%s(" format ")\n", this, __FUNCTION__, ##__VA_ARGS__)

-#else

-	#define TRACE(...) ((void)0)

-#endif

-

-#ifndef NDEBUG

-	#define UNIMPLEMENTED() {trace("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); ASSERT(false);}

-#else

-	#define UNIMPLEMENTED() ((void)0)

-#endif

-

-#ifndef NDEBUG

-	#define ASSERT(expression) {if(!(expression)) trace("\t! Assert failed in %s(%d): " #expression "\n", __FUNCTION__, __LINE__); assert(expression);}

-#else

-	#define ASSERT assert

-#endif

-

-#endif   // __ANDROID__

-#endif   // Debug_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef Debug_hpp
+#define Debug_hpp
+
+#ifdef __ANDROID__
+#include "DebugAndroid.hpp"
+#else
+
+#include <assert.h>
+#include <stdio.h>
+
+#undef min
+#undef max
+
+void trace(const char *format, ...);
+
+#ifndef NDEBUG
+	#define TRACE(format, ...) trace("[0x%0.8X]%s(" format ")\n", this, __FUNCTION__, ##__VA_ARGS__)
+#else
+	#define TRACE(...) ((void)0)
+#endif
+
+#ifndef NDEBUG
+	#define UNIMPLEMENTED() {trace("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); ASSERT(false);}
+#else
+	#define UNIMPLEMENTED() ((void)0)
+#endif
+
+#ifndef NDEBUG
+	#define ASSERT(expression) {if(!(expression)) trace("\t! Assert failed in %s(%d): " #expression "\n", __FUNCTION__, __LINE__); assert(expression);}
+#else
+	#define ASSERT assert
+#endif
+
+#endif   // __ANDROID__
+#endif   // Debug_hpp
diff --git a/src/Common/DebugAndroid.cpp b/src/Common/DebugAndroid.cpp
index d8b616e..0d37c0f 100644
--- a/src/Common/DebugAndroid.cpp
+++ b/src/Common/DebugAndroid.cpp
@@ -7,31 +7,33 @@
 
 void AndroidEnterDebugger()
 {
-    ALOGE(__FUNCTION__);
+	ALOGE(__FUNCTION__);
 #ifndef NDEBUG
-    static volatile int * const makefault = nullptr;
-    char value[PROPERTY_VALUE_MAX];
-    property_get("debug.db.uid", value, "-1");
-    int debug_uid = atoi(value);
-    if ((debug_uid >= 0) && (geteuid() < static_cast<uid_t>(debug_uid)))
-    {
-        ALOGE("Waiting for debugger: gdbserver :${PORT} --attach %u. Look for thread %u", getpid(), gettid());
-        volatile int waiting = 1;
-        while (waiting) {
-            sleep(1);
-        }
-    } else {
-        ALOGE("No debugger");
-    }
+	static volatile int * const makefault = nullptr;
+	char value[PROPERTY_VALUE_MAX];
+	property_get("debug.db.uid", value, "-1");
+	int debug_uid = atoi(value);
+	if((debug_uid >= 0) && (geteuid() < static_cast<uid_t>(debug_uid)))
+	{
+		ALOGE("Waiting for debugger: gdbserver :${PORT} --attach %u. Look for thread %u", getpid(), gettid());
+		volatile int waiting = 1;
+		while (waiting) {
+			sleep(1);
+		}
+	}
+	else
+	{
+		ALOGE("No debugger");
+	}
 #endif
 }
 
 void trace(const char *format, ...)
 {
 #ifndef NDEBUG
-    va_list vararg;
-    va_start(vararg, format);
-    android_vprintLog(ANDROID_LOG_VERBOSE, NULL, LOG_TAG, format, vararg);
-    va_end(vararg);
+	va_list vararg;
+	va_start(vararg, format);
+	android_vprintLog(ANDROID_LOG_VERBOSE, NULL, LOG_TAG, format, vararg);
+	va_end(vararg);
 #endif
 }
diff --git a/src/Common/GrallocAndroid.cpp b/src/Common/GrallocAndroid.cpp
index f96d62a..ae5fc09 100644
--- a/src/Common/GrallocAndroid.cpp
+++ b/src/Common/GrallocAndroid.cpp
@@ -1,22 +1,36 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #include "GrallocAndroid.hpp"
 
 #include <cutils/log.h>
 
 GrallocModule *GrallocModule::getInstance()
 {
-    static GrallocModule instance;
-    return &instance;
+	static GrallocModule instance;
+	return &instance;
 }
 
 GrallocModule::GrallocModule()
 {
-    const hw_module_t *module = nullptr;
-    hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+	const hw_module_t *module = nullptr;
+	hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
 
-    if(!module)
-    {
-        ALOGE("Failed to load standard gralloc");
-    }
+	if(!module)
+	{
+		ALOGE("Failed to load standard gralloc");
+	}
 
-    m_module = reinterpret_cast<const gralloc_module_t*>(module);
+	m_module = reinterpret_cast<const gralloc_module_t*>(module);
 }
diff --git a/src/Common/GrallocAndroid.hpp b/src/Common/GrallocAndroid.hpp
index 805850d..ffc8fc6 100644
--- a/src/Common/GrallocAndroid.hpp
+++ b/src/Common/GrallocAndroid.hpp
@@ -6,20 +6,20 @@
 class GrallocModule
 {
 public:
-    static GrallocModule *getInstance();
-    int lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
+	static GrallocModule *getInstance();
+	int lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
 	{
-        return m_module->lock(m_module, handle, usage, left, top, width, height, vaddr);
-    }
+		return m_module->lock(m_module, handle, usage, left, top, width, height, vaddr);
+	}
 
-    int unlock(buffer_handle_t handle)
-    {
-        return m_module->unlock(m_module, handle);
-    }
+	int unlock(buffer_handle_t handle)
+	{
+		return m_module->unlock(m_module, handle);
+	}
 
 private:
-    GrallocModule();
-    const gralloc_module_t *m_module;
+	GrallocModule();
+	const gralloc_module_t *m_module;
 };
 
 #endif  // GRALLOC_ANDROID
diff --git a/src/Common/Half.cpp b/src/Common/Half.cpp
index fea54ac..cde8190 100644
--- a/src/Common/Half.cpp
+++ b/src/Common/Half.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Half.hpp"
 
@@ -15,34 +18,34 @@
 {
 	half::half(float fp32)
 	{
-        unsigned int fp32i = *(unsigned int*)&fp32;
-        unsigned int sign = (fp32i & 0x80000000) >> 16;
-        unsigned int abs = fp32i & 0x7FFFFFFF;
+		unsigned int fp32i = *(unsigned int*)&fp32;
+		unsigned int sign = (fp32i & 0x80000000) >> 16;
+		unsigned int abs = fp32i & 0x7FFFFFFF;
 
-        if(abs > 0x47FFEFFF)   // Infinity
-        {
-            fp16i = sign | 0x7FFF;
-        }
-        else if(abs < 0x38800000)   // Denormal
-        {
-            unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;   
-            int e = 113 - (abs >> 23);
+		if(abs > 0x47FFEFFF)   // Infinity
+		{
+			fp16i = sign | 0x7FFF;
+		}
+		else if(abs < 0x38800000)   // Denormal
+		{
+			unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
+			int e = 113 - (abs >> 23);
 
-            if(e < 24)
-            {
-                abs = mantissa >> e;
-            }
-            else
-            {
-                abs = 0;
-            }
+			if(e < 24)
+			{
+				abs = mantissa >> e;
+			}
+			else
+			{
+				abs = 0;
+			}
 
-            fp16i = sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13;
-        }
-        else
-        {
-            fp16i = sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13;
-        }
+			fp16i = sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13;
+		}
+		else
+		{
+			fp16i = sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13;
+		}
 	}
 
 	half::operator float() const
@@ -58,7 +61,7 @@
 			if(m == 0)
 			{
 				fp32i = s << 31;
-			
+
 				return (float&)fp32i;
 			}
 			else
@@ -85,7 +88,7 @@
 	half &half::operator=(half h)
 	{
 		fp16i = h.fp16i;
-		
+
 		return *this;
 	}
 
diff --git a/src/Common/Half.hpp b/src/Common/Half.hpp
index fc412c9..f62ea27 100644
--- a/src/Common/Half.hpp
+++ b/src/Common/Half.hpp
@@ -1,32 +1,35 @@
-// 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.

-//

-

-#ifndef sw_Half_hpp

-#define sw_Half_hpp

-

-namespace sw

-{

-	class half

-	{

-	public:

-		explicit half(float f);

-

-		operator float() const;

-

-		half &operator=(half h);

-		half &operator=(float f);

-

-	private:

-		unsigned short fp16i;

-	};

-}

-

-#endif   // sw_Half_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Half_hpp
+#define sw_Half_hpp
+
+namespace sw
+{
+	class half
+	{
+	public:
+		explicit half(float f);
+
+		operator float() const;
+
+		half &operator=(half h);
+		half &operator=(float f);
+
+	private:
+		unsigned short fp16i;
+	};
+}
+
+#endif   // sw_Half_hpp
diff --git a/src/Common/Math.cpp b/src/Common/Math.cpp
index e8ae3d2..fcf7eca 100644
--- a/src/Common/Math.cpp
+++ b/src/Common/Math.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Math.hpp"
 
diff --git a/src/Common/Math.hpp b/src/Common/Math.hpp
index 9e51850..0b4abe6 100644
--- a/src/Common/Math.hpp
+++ b/src/Common/Math.hpp
@@ -1,477 +1,480 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Math_hpp

-#define sw_Math_hpp

-

-#include "Types.hpp"

-

-#include <cmath>

-#if defined(_MSC_VER)

-	#include <intrin.h>

-#endif

-

-namespace sw

-{

-	using std::abs;

-

-	#undef min

-	#undef max

-

-	template<class T>

-	inline T max(T a, T b)

-	{

-		return a > b ? a : b;

-	}

-

-	template<class T>

-	inline T min(T a, T b)

-	{

-		return a < b ? a : b;

-	}

-

-	template<class T>

-	inline T max(T a, T b, T c)

-	{

-		return max(max(a, b), c);

-	}

-

-	template<class T>

-	inline T min(T a, T b, T c)

-	{

-		return min(min(a, b), c);

-	}

-

-	template<class T>

-	inline T max(T a, T b, T c, T d)

-	{

-		return max(max(a, b), max(c, d));

-	}

-

-	template<class T>

-	inline T min(T a, T b, T c, T d)

-	{

-		return min(min(a, b), min(c, d));

-	}

-

-	template<class T>

-	inline void swap(T &a, T &b)

-	{

-		T t = a;

-		a = b;

-		b = t;

-	}

-

-	inline int iround(float x)

-	{

-		return (int)floor(x + 0.5f);

-	//	return _mm_cvtss_si32(_mm_load_ss(&x));   // FIXME: Demands SSE support

-	}

-

-	inline int ifloor(float x)

-	{

-		return (int)floor(x);

-	}

-

-	inline int ceilFix4(int x)

-	{

-		return (x + 0xF) & 0xFFFFFFF0;

-	}

-

-	inline int ceilInt4(int x)

-	{

-		return (x + 0xF) >> 4;

-	}

-

-	#define BITS(x)    ( \

-	!!((x) & 0x80000000) + \

-	!!((x) & 0xC0000000) + \

-	!!((x) & 0xE0000000) + \

-	!!((x) & 0xF0000000) + \

-	!!((x) & 0xF8000000) + \

-	!!((x) & 0xFC000000) + \

-	!!((x) & 0xFE000000) + \

-	!!((x) & 0xFF000000) + \

-	!!((x) & 0xFF800000) + \

-	!!((x) & 0xFFC00000) + \

-	!!((x) & 0xFFE00000) + \

-	!!((x) & 0xFFF00000) + \

-	!!((x) & 0xFFF80000) + \

-	!!((x) & 0xFFFC0000) + \

-	!!((x) & 0xFFFE0000) + \

-	!!((x) & 0xFFFF0000) + \

-	!!((x) & 0xFFFF8000) + \

-	!!((x) & 0xFFFFC000) + \

-	!!((x) & 0xFFFFE000) + \

-	!!((x) & 0xFFFFF000) + \

-	!!((x) & 0xFFFFF800) + \

-	!!((x) & 0xFFFFFC00) + \

-	!!((x) & 0xFFFFFE00) + \

-	!!((x) & 0xFFFFFF00) + \

-	!!((x) & 0xFFFFFF80) + \

-	!!((x) & 0xFFFFFFC0) + \

-	!!((x) & 0xFFFFFFE0) + \

-	!!((x) & 0xFFFFFFF0) + \

-	!!((x) & 0xFFFFFFF8) + \

-	!!((x) & 0xFFFFFFFC) + \

-	!!((x) & 0xFFFFFFFE) + \

-	!!((x) & 0xFFFFFFFF))

-

-	#define MAX(x, y) ((x) > (y) ? (x) : (y))

-	#define MIN(x, y) ((x) < (y) ? (x) : (y))

-

-	inline float exp2(float x)

-	{

-		return exp2f(x);

-	}

-

-	inline int exp2(int x)

-	{

-		return 1 << x;

-	}

-

-	inline unsigned long log2(int x)

-	{

-		#if defined(_MSC_VER)

-			unsigned long y;

-			_BitScanReverse(&y, x);

-			return y;

-		#else

-			return 31 - __builtin_clz(x);

-		#endif

-	}

-

-	inline int ilog2(float x)

-	{

-		unsigned int y = *(unsigned int*)&x;

-

-		return ((y & 0x7F800000) >> 23) - 127;

-	}

-

-	inline float log2(float x)

-	{

-		return logf(x) * 1.44269504f;   // 1.0 / log[e](2)

-	}

-

-	inline bool isPow2(int x)

-	{

-		return (x & -x) == x;

-	}

-

-	template<class T>

-	inline T clamp(T x, T a, T b)

-	{

-		if(x < a) x = a;

-		if(x > b) x = b;

-

-		return x;

-	}

-

-	inline float clamp01(float x)

-	{

-		return clamp(x, 0.0f, 1.0f);

-	}

-

-	inline int ceilPow2(int x)

-	{

-		int i = 1;

-

-		while(i < x)

-		{

-			i <<= 1;

-		}

-

-		return i;

-	}

-

-	inline int floorDiv(int a, int b)

-	{

-		return a / b + ((a % b) >> 31);

-	}

-

-	inline int floorMod(int a, int b)

-	{

-		int r = a % b;

-		return r + ((r >> 31) & b);

-	}

-

-	inline int ceilDiv(int a, int b)

-	{

-		return a / b - (-(a % b) >> 31);

-	}

-

-	inline int ceilMod(int a, int b)

-	{

-		int r = a % b;

-		return r - ((-r >> 31) & b);

-	}

-

-	template<const int n>

-	inline unsigned int unorm(float x)

-	{

-		static const unsigned int max = 0xFFFFFFFF >> (32 - n);

-		static const float maxf = static_cast<float>(max);

-

-		if(x >= 1.0f)

-		{

-			return max;

-		}

-		else if(x <= 0.0f)

-		{

-			return 0;

-		}

-		else

-		{

-			return static_cast<unsigned int>(maxf * x + 0.5f);

-		}

-	}

-

-	template<const int n>

-	inline int snorm(float x)

-	{

-		static const unsigned int min = 0x80000000 >> (32 - n);

-		static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);

-		static const float maxf = static_cast<float>(max);

-		static const unsigned int range = 0xFFFFFFFF >> (32 - n);

-

-		if(x >= 0.0f)

-		{

-			if(x >= 1.0f)

-			{

-				return max;

-			}

-			else

-			{

-				return static_cast<int>(maxf * x + 0.5f);

-			}

-		}

-		else

-		{

-			if(x <= -1.0f)

-			{

-				return min;

-			}

-			else

-			{

-				return static_cast<int>(maxf * x - 0.5f) & range;

-			}

-		}

-	}

-

-	template<const int n>

-	inline unsigned int ucast(float x)

-	{

-		static const unsigned int max = 0xFFFFFFFF >> (32 - n);

-		static const float maxf = static_cast<float>(max);

-

-		if(x >= maxf)

-		{

-			return max;

-		}

-		else if(x <= 0.0f)

-		{

-			return 0;

-		}

-		else

-		{

-			return static_cast<unsigned int>(x + 0.5f);

-		}

-	}

-

-	template<const int n>

-	inline int scast(float x)

-	{

-		static const unsigned int min = 0x80000000 >> (32 - n);

-		static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);

-		static const float maxf = static_cast<float>(max);

-		static const unsigned int range = 0xFFFFFFFF >> (32 - n);

-

-		if(x > 0.0f)

-		{

-			if(x >= maxf)

-			{

-				return max;

-			}

-			else

-			{

-				return static_cast<int>(maxf * x + 0.5f);

-			}

-		}

-		else

-		{

-			if(x <= -1.0f)

-			{

-				return min;

-			}

-			else

-			{

-				return static_cast<int>(maxf * x - 0.5f) & range;

-			}

-		}

-	}

-

-	inline float sRGBtoLinear(float c)

-	{

-		if(c <= 0.04045f)

-		{

-			return c * 0.07739938f;   // 1.0f / 12.92f;

-		}

-		else

-		{

-			return powf((c + 0.055f) * 0.9478673f, 2.4f);   // 1.0f / 1.055f

-		}

-	}

-

-	inline float linearToSRGB(float c)

-	{

-		if(c <= 0.0031308f)

-		{

-			return c * 12.92f;

-		}

-		else

-		{

-			return 1.055f * powf(c, 0.4166667f) - 0.055f;   // 1.0f / 2.4f

-		}

-	}

-

-	unsigned char sRGB8toLinear8(unsigned char value);

-

-	uint64_t FNV_1a(const unsigned char *data, int size);   // Fowler-Noll-Vo hash function

-

-	// Round up to the next multiple of alignment

-	inline unsigned int align(unsigned int value, unsigned int alignment)

-	{

-		return ((value + alignment - 1) / alignment) * alignment;

-	}

-

-	inline int clampToSignedInt(unsigned int x)

-	{

-		return static_cast<int>(min(x, 0x7FFFFFFFu));

-	}

-

-	class RGB9E5Data

-	{

-		unsigned int R : 9;

-		unsigned int G : 9;

-		unsigned int B : 9;

-		unsigned int E : 5;

-

-	public:

-		void toRGBFloats(float* rgb) const

-		{

-			static const float Offset = -24.0f; // Exponent Bias (15) + Number of mantissa bits per component (9) = 24

-

-			const float factor = powf(2.0f, static_cast<float>(E) + Offset);

-			rgb[0] = static_cast<float>(R) * factor;

-			rgb[1] = static_cast<float>(G) * factor;

-			rgb[2] = static_cast<float>(B) * factor;

-		}

-	};

-

-	class R11G11B10FData

-	{

-		unsigned int R : 11;

-		unsigned int G : 11;

-		unsigned int B : 10;

-

-		static inline float float11ToFloat32(unsigned short fp11)

-		{

-			unsigned short exponent = (fp11 >> 6) & 0x1F;

-			unsigned short mantissa = fp11 & 0x3F;

-

-			unsigned int output;

-			if(exponent == 0x1F)

-			{

-				// INF or NAN

-				output = 0x7f800000 | (mantissa << 17);

-			}

-			else

-			{

-				if(exponent != 0)

-				{

-					// normalized

-				}

-				else if(mantissa != 0)

-				{

-					// The value is denormalized

-					exponent = 1;

-

-					do

-					{

-						exponent--;

-						mantissa <<= 1;

-					} while((mantissa & 0x40) == 0);

-

-					mantissa = mantissa & 0x3F;

-				}

-				else // The value is zero

-				{

-					exponent = static_cast<unsigned short>(-112);

-				}

-

-				output = ((exponent + 112) << 23) | (mantissa << 17);

-			}

-

-			return *(float*)(&output);

-		}

-

-		static inline float float10ToFloat32(unsigned short fp10)

-		{

-			unsigned short exponent = (fp10 >> 5) & 0x1F;

-			unsigned short mantissa = fp10 & 0x1F;

-

-			unsigned int output;

-			if(exponent == 0x1F)

-			{

-				// INF or NAN

-				output = 0x7f800000 | (mantissa << 17);

-			}

-			else

-			{

-				if(exponent != 0)

-				{

-					// normalized

-				}

-				else if(mantissa != 0)

-				{

-					// The value is denormalized

-					exponent = 1;

-

-					do

-					{

-						exponent--;

-						mantissa <<= 1;

-					} while((mantissa & 0x20) == 0);

-

-					mantissa = mantissa & 0x1F;

-				}

-				else // The value is zero

-				{

-					exponent = static_cast<unsigned short>(-112);

-				}

-

-				output = ((exponent + 112) << 23) | (mantissa << 18);

-			}

-

-			return *(float*)(&output);

-		}

-

-	public:

-		void toRGBFloats(float* rgb) const

-		{

-			rgb[0] = float11ToFloat32(R);

-			rgb[1] = float11ToFloat32(G);

-			rgb[2] = float10ToFloat32(B);

-		}

-	};

-}

-

-#endif   // sw_Math_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Math_hpp
+#define sw_Math_hpp
+
+#include "Types.hpp"
+
+#include <cmath>
+#if defined(_MSC_VER)
+	#include <intrin.h>
+#endif
+
+namespace sw
+{
+	using std::abs;
+
+	#undef min
+	#undef max
+
+	template<class T>
+	inline T max(T a, T b)
+	{
+		return a > b ? a : b;
+	}
+
+	template<class T>
+	inline T min(T a, T b)
+	{
+		return a < b ? a : b;
+	}
+
+	template<class T>
+	inline T max(T a, T b, T c)
+	{
+		return max(max(a, b), c);
+	}
+
+	template<class T>
+	inline T min(T a, T b, T c)
+	{
+		return min(min(a, b), c);
+	}
+
+	template<class T>
+	inline T max(T a, T b, T c, T d)
+	{
+		return max(max(a, b), max(c, d));
+	}
+
+	template<class T>
+	inline T min(T a, T b, T c, T d)
+	{
+		return min(min(a, b), min(c, d));
+	}
+
+	template<class T>
+	inline void swap(T &a, T &b)
+	{
+		T t = a;
+		a = b;
+		b = t;
+	}
+
+	inline int iround(float x)
+	{
+		return (int)floor(x + 0.5f);
+	//	return _mm_cvtss_si32(_mm_load_ss(&x));   // FIXME: Demands SSE support
+	}
+
+	inline int ifloor(float x)
+	{
+		return (int)floor(x);
+	}
+
+	inline int ceilFix4(int x)
+	{
+		return (x + 0xF) & 0xFFFFFFF0;
+	}
+
+	inline int ceilInt4(int x)
+	{
+		return (x + 0xF) >> 4;
+	}
+
+	#define BITS(x)    ( \
+	!!((x) & 0x80000000) + \
+	!!((x) & 0xC0000000) + \
+	!!((x) & 0xE0000000) + \
+	!!((x) & 0xF0000000) + \
+	!!((x) & 0xF8000000) + \
+	!!((x) & 0xFC000000) + \
+	!!((x) & 0xFE000000) + \
+	!!((x) & 0xFF000000) + \
+	!!((x) & 0xFF800000) + \
+	!!((x) & 0xFFC00000) + \
+	!!((x) & 0xFFE00000) + \
+	!!((x) & 0xFFF00000) + \
+	!!((x) & 0xFFF80000) + \
+	!!((x) & 0xFFFC0000) + \
+	!!((x) & 0xFFFE0000) + \
+	!!((x) & 0xFFFF0000) + \
+	!!((x) & 0xFFFF8000) + \
+	!!((x) & 0xFFFFC000) + \
+	!!((x) & 0xFFFFE000) + \
+	!!((x) & 0xFFFFF000) + \
+	!!((x) & 0xFFFFF800) + \
+	!!((x) & 0xFFFFFC00) + \
+	!!((x) & 0xFFFFFE00) + \
+	!!((x) & 0xFFFFFF00) + \
+	!!((x) & 0xFFFFFF80) + \
+	!!((x) & 0xFFFFFFC0) + \
+	!!((x) & 0xFFFFFFE0) + \
+	!!((x) & 0xFFFFFFF0) + \
+	!!((x) & 0xFFFFFFF8) + \
+	!!((x) & 0xFFFFFFFC) + \
+	!!((x) & 0xFFFFFFFE) + \
+	!!((x) & 0xFFFFFFFF))
+
+	#define MAX(x, y) ((x) > (y) ? (x) : (y))
+	#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+	inline float exp2(float x)
+	{
+		return exp2f(x);
+	}
+
+	inline int exp2(int x)
+	{
+		return 1 << x;
+	}
+
+	inline unsigned long log2(int x)
+	{
+		#if defined(_MSC_VER)
+			unsigned long y;
+			_BitScanReverse(&y, x);
+			return y;
+		#else
+			return 31 - __builtin_clz(x);
+		#endif
+	}
+
+	inline int ilog2(float x)
+	{
+		unsigned int y = *(unsigned int*)&x;
+
+		return ((y & 0x7F800000) >> 23) - 127;
+	}
+
+	inline float log2(float x)
+	{
+		return logf(x) * 1.44269504f;   // 1.0 / log[e](2)
+	}
+
+	inline bool isPow2(int x)
+	{
+		return (x & -x) == x;
+	}
+
+	template<class T>
+	inline T clamp(T x, T a, T b)
+	{
+		if(x < a) x = a;
+		if(x > b) x = b;
+
+		return x;
+	}
+
+	inline float clamp01(float x)
+	{
+		return clamp(x, 0.0f, 1.0f);
+	}
+
+	inline int ceilPow2(int x)
+	{
+		int i = 1;
+
+		while(i < x)
+		{
+			i <<= 1;
+		}
+
+		return i;
+	}
+
+	inline int floorDiv(int a, int b)
+	{
+		return a / b + ((a % b) >> 31);
+	}
+
+	inline int floorMod(int a, int b)
+	{
+		int r = a % b;
+		return r + ((r >> 31) & b);
+	}
+
+	inline int ceilDiv(int a, int b)
+	{
+		return a / b - (-(a % b) >> 31);
+	}
+
+	inline int ceilMod(int a, int b)
+	{
+		int r = a % b;
+		return r - ((-r >> 31) & b);
+	}
+
+	template<const int n>
+	inline unsigned int unorm(float x)
+	{
+		static const unsigned int max = 0xFFFFFFFF >> (32 - n);
+		static const float maxf = static_cast<float>(max);
+
+		if(x >= 1.0f)
+		{
+			return max;
+		}
+		else if(x <= 0.0f)
+		{
+			return 0;
+		}
+		else
+		{
+			return static_cast<unsigned int>(maxf * x + 0.5f);
+		}
+	}
+
+	template<const int n>
+	inline int snorm(float x)
+	{
+		static const unsigned int min = 0x80000000 >> (32 - n);
+		static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
+		static const float maxf = static_cast<float>(max);
+		static const unsigned int range = 0xFFFFFFFF >> (32 - n);
+
+		if(x >= 0.0f)
+		{
+			if(x >= 1.0f)
+			{
+				return max;
+			}
+			else
+			{
+				return static_cast<int>(maxf * x + 0.5f);
+			}
+		}
+		else
+		{
+			if(x <= -1.0f)
+			{
+				return min;
+			}
+			else
+			{
+				return static_cast<int>(maxf * x - 0.5f) & range;
+			}
+		}
+	}
+
+	template<const int n>
+	inline unsigned int ucast(float x)
+	{
+		static const unsigned int max = 0xFFFFFFFF >> (32 - n);
+		static const float maxf = static_cast<float>(max);
+
+		if(x >= maxf)
+		{
+			return max;
+		}
+		else if(x <= 0.0f)
+		{
+			return 0;
+		}
+		else
+		{
+			return static_cast<unsigned int>(x + 0.5f);
+		}
+	}
+
+	template<const int n>
+	inline int scast(float x)
+	{
+		static const unsigned int min = 0x80000000 >> (32 - n);
+		static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
+		static const float maxf = static_cast<float>(max);
+		static const unsigned int range = 0xFFFFFFFF >> (32 - n);
+
+		if(x > 0.0f)
+		{
+			if(x >= maxf)
+			{
+				return max;
+			}
+			else
+			{
+				return static_cast<int>(maxf * x + 0.5f);
+			}
+		}
+		else
+		{
+			if(x <= -1.0f)
+			{
+				return min;
+			}
+			else
+			{
+				return static_cast<int>(maxf * x - 0.5f) & range;
+			}
+		}
+	}
+
+	inline float sRGBtoLinear(float c)
+	{
+		if(c <= 0.04045f)
+		{
+			return c * 0.07739938f;   // 1.0f / 12.92f;
+		}
+		else
+		{
+			return powf((c + 0.055f) * 0.9478673f, 2.4f);   // 1.0f / 1.055f
+		}
+	}
+
+	inline float linearToSRGB(float c)
+	{
+		if(c <= 0.0031308f)
+		{
+			return c * 12.92f;
+		}
+		else
+		{
+			return 1.055f * powf(c, 0.4166667f) - 0.055f;   // 1.0f / 2.4f
+		}
+	}
+
+	unsigned char sRGB8toLinear8(unsigned char value);
+
+	uint64_t FNV_1a(const unsigned char *data, int size);   // Fowler-Noll-Vo hash function
+
+	// Round up to the next multiple of alignment
+	inline unsigned int align(unsigned int value, unsigned int alignment)
+	{
+		return ((value + alignment - 1) / alignment) * alignment;
+	}
+
+	inline int clampToSignedInt(unsigned int x)
+	{
+		return static_cast<int>(min(x, 0x7FFFFFFFu));
+	}
+
+	class RGB9E5Data
+	{
+		unsigned int R : 9;
+		unsigned int G : 9;
+		unsigned int B : 9;
+		unsigned int E : 5;
+
+	public:
+		void toRGBFloats(float* rgb) const
+		{
+			static const float Offset = -24.0f; // Exponent Bias (15) + Number of mantissa bits per component (9) = 24
+
+			const float factor = powf(2.0f, static_cast<float>(E) + Offset);
+			rgb[0] = static_cast<float>(R) * factor;
+			rgb[1] = static_cast<float>(G) * factor;
+			rgb[2] = static_cast<float>(B) * factor;
+		}
+	};
+
+	class R11G11B10FData
+	{
+		unsigned int R : 11;
+		unsigned int G : 11;
+		unsigned int B : 10;
+
+		static inline float float11ToFloat32(unsigned short fp11)
+		{
+			unsigned short exponent = (fp11 >> 6) & 0x1F;
+			unsigned short mantissa = fp11 & 0x3F;
+
+			unsigned int output;
+			if(exponent == 0x1F)
+			{
+				// INF or NAN
+				output = 0x7f800000 | (mantissa << 17);
+			}
+			else
+			{
+				if(exponent != 0)
+				{
+					// normalized
+				}
+				else if(mantissa != 0)
+				{
+					// The value is denormalized
+					exponent = 1;
+
+					do
+					{
+						exponent--;
+						mantissa <<= 1;
+					} while((mantissa & 0x40) == 0);
+
+					mantissa = mantissa & 0x3F;
+				}
+				else // The value is zero
+				{
+					exponent = static_cast<unsigned short>(-112);
+				}
+
+				output = ((exponent + 112) << 23) | (mantissa << 17);
+			}
+
+			return *(float*)(&output);
+		}
+
+		static inline float float10ToFloat32(unsigned short fp10)
+		{
+			unsigned short exponent = (fp10 >> 5) & 0x1F;
+			unsigned short mantissa = fp10 & 0x1F;
+
+			unsigned int output;
+			if(exponent == 0x1F)
+			{
+				// INF or NAN
+				output = 0x7f800000 | (mantissa << 17);
+			}
+			else
+			{
+				if(exponent != 0)
+				{
+					// normalized
+				}
+				else if(mantissa != 0)
+				{
+					// The value is denormalized
+					exponent = 1;
+
+					do
+					{
+						exponent--;
+						mantissa <<= 1;
+					} while((mantissa & 0x20) == 0);
+
+					mantissa = mantissa & 0x1F;
+				}
+				else // The value is zero
+				{
+					exponent = static_cast<unsigned short>(-112);
+				}
+
+				output = ((exponent + 112) << 23) | (mantissa << 18);
+			}
+
+			return *(float*)(&output);
+		}
+
+	public:
+		void toRGBFloats(float* rgb) const
+		{
+			rgb[0] = float11ToFloat32(R);
+			rgb[1] = float11ToFloat32(G);
+			rgb[2] = float10ToFloat32(B);
+		}
+	};
+}
+
+#endif   // sw_Math_hpp
diff --git a/src/Common/Memory.cpp b/src/Common/Memory.cpp
index 12f21b3..d87575c 100644
--- a/src/Common/Memory.cpp
+++ b/src/Common/Memory.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Memory.hpp"
 
diff --git a/src/Common/Memory.hpp b/src/Common/Memory.hpp
index 36b84e5..3cf4be1 100644
--- a/src/Common/Memory.hpp
+++ b/src/Common/Memory.hpp
@@ -1,30 +1,33 @@
-// 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.

-//

-

-#ifndef Memory_hpp

-#define Memory_hpp

-

-#include <stddef.h>

-

-namespace sw

-{

-size_t memoryPageSize();

-

-void *allocate(size_t bytes, size_t alignment = 16);

-void *allocateZero(size_t bytes, size_t alignment = 16);

-void deallocate(void *memory);

-

-void *allocateExecutable(size_t bytes);   // Allocates memory that can be made executable using markExecutable()

-void markExecutable(void *memory, size_t bytes);

-void deallocateExecutable(void *memory, size_t bytes);

-}

-

-#endif   // Memory_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef Memory_hpp
+#define Memory_hpp
+
+#include <stddef.h>
+
+namespace sw
+{
+size_t memoryPageSize();
+
+void *allocate(size_t bytes, size_t alignment = 16);
+void *allocateZero(size_t bytes, size_t alignment = 16);
+void deallocate(void *memory);
+
+void *allocateExecutable(size_t bytes);   // Allocates memory that can be made executable using markExecutable()
+void markExecutable(void *memory, size_t bytes);
+void deallocateExecutable(void *memory, size_t bytes);
+}
+
+#endif   // Memory_hpp
diff --git a/src/Common/MetaMacro.hpp b/src/Common/MetaMacro.hpp
index 1ceb70c..f717d75 100644
--- a/src/Common/MetaMacro.hpp
+++ b/src/Common/MetaMacro.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_MetaMacro_hpp
 #define sw_MetaMacro_hpp
diff --git a/src/Common/MutexLock.hpp b/src/Common/MutexLock.hpp
index 31e5189..16835ed 100644
--- a/src/Common/MutexLock.hpp
+++ b/src/Common/MutexLock.hpp
@@ -1,126 +1,129 @@
-// 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.

-//

-

-#ifndef sw_MutexLock_hpp

-#define sw_MutexLock_hpp

-

-#include "Thread.hpp"

-

-namespace sw

-{

-	class BackoffLock

-	{

-	public:

-		BackoffLock()

-		{

-			mutex = 0;

-		}

-

-		bool attemptLock()

-		{

-			if(!isLocked())

-			{

-				if(atomicExchange(&mutex, 1) == 0)

-				{

-					return true;

-				}

-			}

-

-			return false;

-		}

-

-		void lock()

-		{

-			int backoff = 1;

-

-			while(!attemptLock())

-			{

-				if(backoff <= 64)

-				{

-					for(int i = 0; i < backoff; i++)

-					{

-						nop();

-						nop();

-						nop();

-						nop();

-						nop();

-

-						nop();

-						nop();

-						nop();

-						nop();

-						nop();

-

-						nop();

-						nop();

-						nop();

-						nop();

-						nop();

-

-						nop();

-						nop();

-						nop();

-						nop();

-						nop();

-

-						nop();

-						nop();

-						nop();

-						nop();

-						nop();

-

-						nop();

-						nop();

-						nop();

-						nop();

-						nop();

-

-						nop();

-						nop();

-						nop();

-						nop();

-						nop();

-					}

-

-					backoff *= 2;

-				}

-				else

-				{

-					Thread::yield();

-

-					backoff = 1;

-				}

-			};

-		}

-

-		void unlock()

-		{

-			mutex = 0;

-		}

-

-		bool isLocked()

-		{

-			return mutex != 0;

-		}

-

-	private:

-		struct

-		{

-			// Ensure that the mutex variable is on its own 64-byte cache line to avoid false sharing

-			// Padding must be public to avoid compiler warnings

-			volatile int padding1[16];

-			volatile int mutex;

-			volatile int padding2[15];

-		};

-	};

-}

-

-#endif   // sw_MutexLock_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_MutexLock_hpp
+#define sw_MutexLock_hpp
+
+#include "Thread.hpp"
+
+namespace sw
+{
+	class BackoffLock
+	{
+	public:
+		BackoffLock()
+		{
+			mutex = 0;
+		}
+
+		bool attemptLock()
+		{
+			if(!isLocked())
+			{
+				if(atomicExchange(&mutex, 1) == 0)
+				{
+					return true;
+				}
+			}
+
+			return false;
+		}
+
+		void lock()
+		{
+			int backoff = 1;
+
+			while(!attemptLock())
+			{
+				if(backoff <= 64)
+				{
+					for(int i = 0; i < backoff; i++)
+					{
+						nop();
+						nop();
+						nop();
+						nop();
+						nop();
+
+						nop();
+						nop();
+						nop();
+						nop();
+						nop();
+
+						nop();
+						nop();
+						nop();
+						nop();
+						nop();
+
+						nop();
+						nop();
+						nop();
+						nop();
+						nop();
+
+						nop();
+						nop();
+						nop();
+						nop();
+						nop();
+
+						nop();
+						nop();
+						nop();
+						nop();
+						nop();
+
+						nop();
+						nop();
+						nop();
+						nop();
+						nop();
+					}
+
+					backoff *= 2;
+				}
+				else
+				{
+					Thread::yield();
+
+					backoff = 1;
+				}
+			};
+		}
+
+		void unlock()
+		{
+			mutex = 0;
+		}
+
+		bool isLocked()
+		{
+			return mutex != 0;
+		}
+
+	private:
+		struct
+		{
+			// Ensure that the mutex variable is on its own 64-byte cache line to avoid false sharing
+			// Padding must be public to avoid compiler warnings
+			volatile int padding1[16];
+			volatile int mutex;
+			volatile int padding2[15];
+		};
+	};
+}
+
+#endif   // sw_MutexLock_hpp
diff --git a/src/Common/Resource.cpp b/src/Common/Resource.cpp
index e96d7d0..b016c95 100644
--- a/src/Common/Resource.cpp
+++ b/src/Common/Resource.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Resource.hpp"
 
@@ -28,7 +31,7 @@
 
 	Resource::~Resource()
 	{
- 		deallocate(buffer);
+		deallocate(buffer);
 	}
 
 	void *Resource::lock(Accessor claimer)
diff --git a/src/Common/Resource.hpp b/src/Common/Resource.hpp
index 6a275f1..6d2577e 100644
--- a/src/Common/Resource.hpp
+++ b/src/Common/Resource.hpp
@@ -1,57 +1,60 @@
-// 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.

-//

-

-#ifndef sw_Resource_hpp

-#define sw_Resource_hpp

-

-#include "MutexLock.hpp"

-

-namespace sw

-{

-	enum Accessor

-	{

-		PUBLIC,    // Application/API access

-		PRIVATE,   // Renderer access, shared by multiple threads if read-only

-		MANAGED,   // Renderer access, shared read/write access if partitioned

-		DESTRUCT

-	};

-

-	class Resource

-	{

-	public:

-		Resource(size_t bytes);

-

-		void destruct();   // Asynchronous destructor

-

-		void *lock(Accessor claimer);

-		void *lock(Accessor relinquisher, Accessor claimer);

-		void unlock();

-		void unlock(Accessor relinquisher);

-

-		const void *data() const;

-		const size_t size;

-

-	private:

-		~Resource();   // Always call destruct() instead

-

-		BackoffLock criticalSection;

-		Event unblock;

-		volatile int blocked;

-

-		volatile Accessor accessor;

-		volatile int count;

-		bool orphaned;

-

-		void *buffer;

-	};

-}

-

-#endif   // sw_Resource_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Resource_hpp
+#define sw_Resource_hpp
+
+#include "MutexLock.hpp"
+
+namespace sw
+{
+	enum Accessor
+	{
+		PUBLIC,    // Application/API access
+		PRIVATE,   // Renderer access, shared by multiple threads if read-only
+		MANAGED,   // Renderer access, shared read/write access if partitioned
+		DESTRUCT
+	};
+
+	class Resource
+	{
+	public:
+		Resource(size_t bytes);
+
+		void destruct();   // Asynchronous destructor
+
+		void *lock(Accessor claimer);
+		void *lock(Accessor relinquisher, Accessor claimer);
+		void unlock();
+		void unlock(Accessor relinquisher);
+
+		const void *data() const;
+		const size_t size;
+
+	private:
+		~Resource();   // Always call destruct() instead
+
+		BackoffLock criticalSection;
+		Event unblock;
+		volatile int blocked;
+
+		volatile Accessor accessor;
+		volatile int count;
+		bool orphaned;
+
+		void *buffer;
+	};
+}
+
+#endif   // sw_Resource_hpp
diff --git a/src/Common/SharedLibrary.hpp b/src/Common/SharedLibrary.hpp
index 1046d64..8d881c1 100644
--- a/src/Common/SharedLibrary.hpp
+++ b/src/Common/SharedLibrary.hpp
@@ -1,129 +1,132 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef SharedLibrary_hpp

-#define SharedLibrary_hpp

-

-#if defined(_WIN32)

-	#include <Windows.h>

-#else

-	#include <dlfcn.h>

-#endif

-

-void *getLibraryHandle(const char *path);

-void *loadLibrary(const char *path);

-void freeLibrary(void *library);

-void *getProcAddress(void *library, const char *name);

-

-template<int n>

-void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullptr)

-{

-	for(int i = 0; i < n; i++)

-	{

-		void *library = getLibraryHandle(names[i]);

-

-		if(library)

-		{

-			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))

-			{

-				return library;

-			}

-

-			freeLibrary(library);

-		}

-	}

-

-	for(int i = 0; i < n; i++)

-	{

-		void *library = loadLibrary(names[i]);

-

-		if(library)

-		{

-			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))

-			{

-				return library;

-			}

-

-			freeLibrary(library);

-		}

-	}

-

-	return 0;

-}

-

-#if defined(_WIN32)

-	inline void *loadLibrary(const char *path)

-	{

-		return (void*)LoadLibrary(path);

-	}

-

-	inline void *getLibraryHandle(const char *path)

-	{

-		HMODULE module = 0;

-		GetModuleHandleEx(0, path, &module);

-		return (void*)module;

-	}

-

-	inline void freeLibrary(void *library)

-	{

-		FreeLibrary((HMODULE)library);

-	}

-

-	inline void *getProcAddress(void *library, const char *name)

-	{

-		return (void*)GetProcAddress((HMODULE)library, name);

-	}

-#else

-	inline void *loadLibrary(const char *path)

-	{

-		return dlopen(path, RTLD_LAZY | RTLD_LOCAL);

-	}

-

-	inline void *getLibraryHandle(const char *path)

-	{

-		#ifdef __ANDROID__

-			// bionic doesn't support RTLD_NOLOAD before L

-			return dlopen(path, RTLD_NOW | RTLD_LOCAL);

-		#else

-			void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD | RTLD_LOCAL);

-

-			if(resident)

-			{

-				return dlopen(path, RTLD_LAZY | RTLD_LOCAL);   // Increment reference count

-			}

-

-			return 0;

-		#endif

-	}

-

-    inline void freeLibrary(void *library)

-    {

-        if(library)

-        {

-            dlclose(library);

-        }

-    }

-

-	inline void *getProcAddress(void *library, const char *name)

-	{

-		void *symbol = dlsym(library, name);

-

-		if(!symbol)

-		{

-			const char *reason = dlerror();   // Silence the error

-			(void)reason;

-		}

-

-		return symbol;

-    }

-#endif

-

-#endif   // SharedLibrary_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SharedLibrary_hpp
+#define SharedLibrary_hpp
+
+#if defined(_WIN32)
+	#include <Windows.h>
+#else
+	#include <dlfcn.h>
+#endif
+
+void *getLibraryHandle(const char *path);
+void *loadLibrary(const char *path);
+void freeLibrary(void *library);
+void *getProcAddress(void *library, const char *name);
+
+template<int n>
+void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullptr)
+{
+	for(int i = 0; i < n; i++)
+	{
+		void *library = getLibraryHandle(names[i]);
+
+		if(library)
+		{
+			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+			{
+				return library;
+			}
+
+			freeLibrary(library);
+		}
+	}
+
+	for(int i = 0; i < n; i++)
+	{
+		void *library = loadLibrary(names[i]);
+
+		if(library)
+		{
+			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+			{
+				return library;
+			}
+
+			freeLibrary(library);
+		}
+	}
+
+	return 0;
+}
+
+#if defined(_WIN32)
+	inline void *loadLibrary(const char *path)
+	{
+		return (void*)LoadLibrary(path);
+	}
+
+	inline void *getLibraryHandle(const char *path)
+	{
+		HMODULE module = 0;
+		GetModuleHandleEx(0, path, &module);
+		return (void*)module;
+	}
+
+	inline void freeLibrary(void *library)
+	{
+		FreeLibrary((HMODULE)library);
+	}
+
+	inline void *getProcAddress(void *library, const char *name)
+	{
+		return (void*)GetProcAddress((HMODULE)library, name);
+	}
+#else
+	inline void *loadLibrary(const char *path)
+	{
+		return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
+	}
+
+	inline void *getLibraryHandle(const char *path)
+	{
+		#ifdef __ANDROID__
+			// bionic doesn't support RTLD_NOLOAD before L
+			return dlopen(path, RTLD_NOW | RTLD_LOCAL);
+		#else
+			void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD | RTLD_LOCAL);
+
+			if(resident)
+			{
+				return dlopen(path, RTLD_LAZY | RTLD_LOCAL);   // Increment reference count
+			}
+
+			return 0;
+		#endif
+	}
+
+	inline void freeLibrary(void *library)
+	{
+		if(library)
+		{
+			dlclose(library);
+		}
+	}
+
+	inline void *getProcAddress(void *library, const char *name)
+	{
+		void *symbol = dlsym(library, name);
+
+		if(!symbol)
+		{
+			const char *reason = dlerror();   // Silence the error
+			(void)reason;
+		}
+
+		return symbol;
+	}
+#endif
+
+#endif   // SharedLibrary_hpp
diff --git a/src/Common/Socket.cpp b/src/Common/Socket.cpp
index a0ac3f4..a19f574 100644
--- a/src/Common/Socket.cpp
+++ b/src/Common/Socket.cpp
@@ -1,106 +1,109 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 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 "Socket.hpp"

-

-#if defined(_WIN32)

-	#include <ws2tcpip.h>

-#else

-	#include <unistd.h>

-	#include <netdb.h>

-	#include <netinet/in.h>

-#endif

-

-namespace sw

-{

-	Socket::Socket(SOCKET socket) : socket(socket)

-	{

-	}

-

-	Socket::Socket(const char *address, const char *port)

-	{

-		#if defined(_WIN32)

-			socket = INVALID_SOCKET;

-		#else

-			socket = -1;

-		#endif

-

-		addrinfo hints = {};

-		hints.ai_family = AF_INET;

-		hints.ai_socktype = SOCK_STREAM;

-		hints.ai_protocol = IPPROTO_TCP;

-		hints.ai_flags = AI_PASSIVE;

-

-		addrinfo *info = 0;

-		getaddrinfo(address, port, &hints, &info);

-

-		if(info)

-		{

-			socket = ::socket(info->ai_family, info->ai_socktype, info->ai_protocol);

-			bind(socket, info->ai_addr, (int)info->ai_addrlen);

-		}

-	}

-

-	Socket::~Socket()

-	{

-		#if defined(_WIN32)

-			closesocket(socket);

-		#else

-			close(socket);

-		#endif

-	}

-

-	void Socket::listen(int backlog)

-	{

-		::listen(socket, backlog);

-	}

-

-	bool Socket::select(int us)

-	{

-		fd_set sockets;

-		FD_ZERO(&sockets);

-		FD_SET(socket, &sockets);

-		

-		timeval timeout = {us / 1000000, us % 1000000};

-

-		return ::select(FD_SETSIZE, &sockets, 0, 0, &timeout) >= 1;

-	}

-

-	Socket *Socket::accept()

-	{

-		return new Socket(::accept(socket, 0, 0));

-	}

-

-	int Socket::receive(char *buffer, int length)

-	{

-		return recv(socket, buffer, length, 0);

-	}

-

-	void Socket::send(const char *buffer, int length)

-	{

-		::send(socket, buffer, length, 0);

-	}

-

-	void Socket::startup()

-	{

-		#if defined(_WIN32)

-			WSADATA winsockData;

-			WSAStartup(MAKEWORD(2, 2), &winsockData);

-		#endif

-	}

-

-	void Socket::cleanup()

-	{

-		#if defined(_WIN32)

-			WSACleanup();

-		#endif

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Socket.hpp"
+
+#if defined(_WIN32)
+	#include <ws2tcpip.h>
+#else
+	#include <unistd.h>
+	#include <netdb.h>
+	#include <netinet/in.h>
+#endif
+
+namespace sw
+{
+	Socket::Socket(SOCKET socket) : socket(socket)
+	{
+	}
+
+	Socket::Socket(const char *address, const char *port)
+	{
+		#if defined(_WIN32)
+			socket = INVALID_SOCKET;
+		#else
+			socket = -1;
+		#endif
+
+		addrinfo hints = {};
+		hints.ai_family = AF_INET;
+		hints.ai_socktype = SOCK_STREAM;
+		hints.ai_protocol = IPPROTO_TCP;
+		hints.ai_flags = AI_PASSIVE;
+
+		addrinfo *info = 0;
+		getaddrinfo(address, port, &hints, &info);
+
+		if(info)
+		{
+			socket = ::socket(info->ai_family, info->ai_socktype, info->ai_protocol);
+			bind(socket, info->ai_addr, (int)info->ai_addrlen);
+		}
+	}
+
+	Socket::~Socket()
+	{
+		#if defined(_WIN32)
+			closesocket(socket);
+		#else
+			close(socket);
+		#endif
+	}
+
+	void Socket::listen(int backlog)
+	{
+		::listen(socket, backlog);
+	}
+
+	bool Socket::select(int us)
+	{
+		fd_set sockets;
+		FD_ZERO(&sockets);
+		FD_SET(socket, &sockets);
+
+		timeval timeout = {us / 1000000, us % 1000000};
+
+		return ::select(FD_SETSIZE, &sockets, 0, 0, &timeout) >= 1;
+	}
+
+	Socket *Socket::accept()
+	{
+		return new Socket(::accept(socket, 0, 0));
+	}
+
+	int Socket::receive(char *buffer, int length)
+	{
+		return recv(socket, buffer, length, 0);
+	}
+
+	void Socket::send(const char *buffer, int length)
+	{
+		::send(socket, buffer, length, 0);
+	}
+
+	void Socket::startup()
+	{
+		#if defined(_WIN32)
+			WSADATA winsockData;
+			WSAStartup(MAKEWORD(2, 2), &winsockData);
+		#endif
+	}
+
+	void Socket::cleanup()
+	{
+		#if defined(_WIN32)
+			WSACleanup();
+		#endif
+	}
+}
diff --git a/src/Common/Socket.hpp b/src/Common/Socket.hpp
index b712cd3..b6b9abd 100644
--- a/src/Common/Socket.hpp
+++ b/src/Common/Socket.hpp
@@ -1,46 +1,49 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Socket_hpp

-#define sw_Socket_hpp

-

-#if defined(_WIN32)

-	#include <winsock2.h>

-#else

-	#include <sys/socket.h>

-	typedef int SOCKET;

-#endif

-

-namespace sw

-{

-	class Socket

-	{

-	public:

-		Socket(SOCKET socket);

-		Socket(const char *address, const char *port);

-		~Socket();

-

-		void listen(int backlog = 1);

-		bool select(int us);

-		Socket *accept();

-		

-		int receive(char *buffer, int length);

-		void send(const char *buffer, int length);

-

-		static void startup();

-		static void cleanup();

-

-	private:

-		SOCKET socket;

-	};

-}

-

-#endif   // sw_Socket_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Socket_hpp
+#define sw_Socket_hpp
+
+#if defined(_WIN32)
+	#include <winsock2.h>
+#else
+	#include <sys/socket.h>
+	typedef int SOCKET;
+#endif
+
+namespace sw
+{
+	class Socket
+	{
+	public:
+		Socket(SOCKET socket);
+		Socket(const char *address, const char *port);
+		~Socket();
+
+		void listen(int backlog = 1);
+		bool select(int us);
+		Socket *accept();
+		
+		int receive(char *buffer, int length);
+		void send(const char *buffer, int length);
+
+		static void startup();
+		static void cleanup();
+
+	private:
+		SOCKET socket;
+	};
+}
+
+#endif   // sw_Socket_hpp
diff --git a/src/Common/Thread.cpp b/src/Common/Thread.cpp
index 9db3b48..9a7b342 100644
--- a/src/Common/Thread.cpp
+++ b/src/Common/Thread.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Thread.hpp"
 
diff --git a/src/Common/Thread.hpp b/src/Common/Thread.hpp
index d57dd41..deb8b29 100644
--- a/src/Common/Thread.hpp
+++ b/src/Common/Thread.hpp
@@ -1,250 +1,253 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Thread_hpp

-#define sw_Thread_hpp

-

-#if defined(_WIN32)

-	#ifndef WIN32_LEAN_AND_MEAN

-		#define WIN32_LEAN_AND_MEAN

-	#endif

-	#include <windows.h>

-	#include <intrin.h>

-#else

-	#include <pthread.h>

-	#include <sched.h>

-	#include <unistd.h>

-	#define TLS_OUT_OF_INDEXES (~0)

-#endif

-

-namespace sw

-{

-	class Event;

-

-	class Thread

-	{

-	public:

-		Thread(void (*threadFunction)(void *parameters), void *parameters);

-

-		~Thread();

-

-		void join();

-

-		static void yield();

-		static void sleep(int milliseconds);

-

-		#if defined(_WIN32)

-			typedef DWORD LocalStorageKey;

-		#else

-			typedef pthread_key_t LocalStorageKey;

-		#endif

-

-		static LocalStorageKey allocateLocalStorageKey();

-		static void freeLocalStorageKey(LocalStorageKey key);

-		static void setLocalStorage(LocalStorageKey key, void *value);

-		static void *getLocalStorage(LocalStorageKey key);

-

-	private:

-		struct Entry

-		{

-			void (*const threadFunction)(void *parameters);

-			void *threadParameters;

-			Event *init;

-		};

-

-		#if defined(_WIN32)

-			static unsigned long __stdcall startFunction(void *parameters);

-			HANDLE handle;

-		#else

-			static void *startFunction(void *parameters);

-			pthread_t handle;

-		#endif

-	};

-

-	class Event

-	{

-		friend class Thread;

-

-	public:

-		Event();

-

-		~Event();

-

-		void signal();

-		void wait();

-

-	private:

-		#if defined(_WIN32)

-			HANDLE handle;

-		#else

-			pthread_cond_t handle;

-			pthread_mutex_t mutex;

-			volatile bool signaled;

-		#endif

-	};

-

-	#if PERF_PROFILE

-	int64_t atomicExchange(int64_t volatile *target, int64_t value);

-	#endif

-

-	int atomicExchange(int volatile *target, int value);

-	int atomicIncrement(int volatile *value);

-	int atomicDecrement(int volatile *value);

-	int atomicAdd(int volatile *target, int value);

-	void nop();

-}

-

-namespace sw

-{

-	inline void Thread::yield()

-	{

-		#if defined(_WIN32)

-			Sleep(0);

-		#elif defined(__APPLE__)

-			pthread_yield_np();

-		#else

-			sched_yield();

-		#endif

-	}

-

-	inline void Thread::sleep(int milliseconds)

-	{

-		#if defined(_WIN32)

-			Sleep(milliseconds);

-		#else

-			usleep(1000 * milliseconds);

-		#endif

-	}

-

-	inline Thread::LocalStorageKey Thread::allocateLocalStorageKey()

-	{

-		#if defined(_WIN32)

-			return TlsAlloc();

-		#else

-			LocalStorageKey key;

-			pthread_key_create(&key, 0);

-			return key;

-		#endif

-	}

-	

-	inline void Thread::freeLocalStorageKey(LocalStorageKey key)

-	{

-		#if defined(_WIN32)

-			TlsFree(key);

-		#else

-			pthread_key_delete(key);

-		#endif

-	}

-

-	inline void Thread::setLocalStorage(LocalStorageKey key, void *value)

-	{

-		#if defined(_WIN32)

-			TlsSetValue(key, value);

-		#else

-			pthread_setspecific(key, value);

-		#endif

-	}

-

-	inline void *Thread::getLocalStorage(LocalStorageKey key)

-	{

-		#if defined(_WIN32)

-			return TlsGetValue(key);

-		#else

-			return pthread_getspecific(key);

-		#endif

-	}

-

-	inline void Event::signal()

-	{

-		#if defined(_WIN32)

-			SetEvent(handle);

-		#else

-			pthread_mutex_lock(&mutex);

-			signaled = true;

-			pthread_cond_signal(&handle);

-			pthread_mutex_unlock(&mutex);

-		#endif

-	}

-

-	inline void Event::wait()

-	{

-		#if defined(_WIN32)

-			WaitForSingleObject(handle, INFINITE);

-		#else

-			pthread_mutex_lock(&mutex);

-			while(!signaled) pthread_cond_wait(&handle, &mutex);

-			signaled = false;

-			pthread_mutex_unlock(&mutex);

-		#endif

-	}

-

-	#if PERF_PROFILE

-	inline int64_t atomicExchange(volatile int64_t *target, int64_t value)

-	{

-		#if defined(_WIN32)

-			return InterlockedExchange64(target, value);

-		#else

-			int ret;

-			__asm__ __volatile__("lock; xchg8 %0,(%1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );

-			return ret;

-		#endif

-	}

-	#endif

-

-	inline int atomicExchange(volatile int *target, int value)

-	{

-		#if defined(_WIN32)

-			return InterlockedExchange((volatile long*)target, (long)value);

-		#else

-			int ret;

-			__asm__ __volatile__("lock; xchgl %0,(%1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );

-			return ret;

-		#endif

-	}

-

-	inline int atomicIncrement(volatile int *value)

-	{

-		#if defined(_WIN32)

-			return InterlockedIncrement((volatile long*)value);

-		#else

-			return __sync_add_and_fetch(value, 1);

-		#endif

-	}

-

-	inline int atomicDecrement(volatile int *value)

-	{

-		#if defined(_WIN32)

-			return InterlockedDecrement((volatile long*)value);

-		#else

-			return __sync_sub_and_fetch(value, 1);

-		#endif

-	}

-

-	inline int atomicAdd(volatile int* target, int value)

-	{

-		#if defined(_MSC_VER)

-			return InterlockedExchangeAdd((volatile long*)target, value) + value;

-		#else

-			return __sync_add_and_fetch(target, value);

-		#endif

-	}

-

-	inline void nop()

-	{

-		#if defined(_WIN32)

-			__nop();

-		#else

-			__asm__ __volatile__ ("nop");

-		#endif

-	}

-}

-

-#endif   // sw_Thread_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Thread_hpp
+#define sw_Thread_hpp
+
+#if defined(_WIN32)
+	#ifndef WIN32_LEAN_AND_MEAN
+		#define WIN32_LEAN_AND_MEAN
+	#endif
+	#include <windows.h>
+	#include <intrin.h>
+#else
+	#include <pthread.h>
+	#include <sched.h>
+	#include <unistd.h>
+	#define TLS_OUT_OF_INDEXES (~0)
+#endif
+
+namespace sw
+{
+	class Event;
+
+	class Thread
+	{
+	public:
+		Thread(void (*threadFunction)(void *parameters), void *parameters);
+
+		~Thread();
+
+		void join();
+
+		static void yield();
+		static void sleep(int milliseconds);
+
+		#if defined(_WIN32)
+			typedef DWORD LocalStorageKey;
+		#else
+			typedef pthread_key_t LocalStorageKey;
+		#endif
+
+		static LocalStorageKey allocateLocalStorageKey();
+		static void freeLocalStorageKey(LocalStorageKey key);
+		static void setLocalStorage(LocalStorageKey key, void *value);
+		static void *getLocalStorage(LocalStorageKey key);
+
+	private:
+		struct Entry
+		{
+			void (*const threadFunction)(void *parameters);
+			void *threadParameters;
+			Event *init;
+		};
+
+		#if defined(_WIN32)
+			static unsigned long __stdcall startFunction(void *parameters);
+			HANDLE handle;
+		#else
+			static void *startFunction(void *parameters);
+			pthread_t handle;
+		#endif
+	};
+
+	class Event
+	{
+		friend class Thread;
+
+	public:
+		Event();
+
+		~Event();
+
+		void signal();
+		void wait();
+
+	private:
+		#if defined(_WIN32)
+			HANDLE handle;
+		#else
+			pthread_cond_t handle;
+			pthread_mutex_t mutex;
+			volatile bool signaled;
+		#endif
+	};
+
+	#if PERF_PROFILE
+	int64_t atomicExchange(int64_t volatile *target, int64_t value);
+	#endif
+
+	int atomicExchange(int volatile *target, int value);
+	int atomicIncrement(int volatile *value);
+	int atomicDecrement(int volatile *value);
+	int atomicAdd(int volatile *target, int value);
+	void nop();
+}
+
+namespace sw
+{
+	inline void Thread::yield()
+	{
+		#if defined(_WIN32)
+			Sleep(0);
+		#elif defined(__APPLE__)
+			pthread_yield_np();
+		#else
+			sched_yield();
+		#endif
+	}
+
+	inline void Thread::sleep(int milliseconds)
+	{
+		#if defined(_WIN32)
+			Sleep(milliseconds);
+		#else
+			usleep(1000 * milliseconds);
+		#endif
+	}
+
+	inline Thread::LocalStorageKey Thread::allocateLocalStorageKey()
+	{
+		#if defined(_WIN32)
+			return TlsAlloc();
+		#else
+			LocalStorageKey key;
+			pthread_key_create(&key, 0);
+			return key;
+		#endif
+	}
+
+	inline void Thread::freeLocalStorageKey(LocalStorageKey key)
+	{
+		#if defined(_WIN32)
+			TlsFree(key);
+		#else
+			pthread_key_delete(key);
+		#endif
+	}
+
+	inline void Thread::setLocalStorage(LocalStorageKey key, void *value)
+	{
+		#if defined(_WIN32)
+			TlsSetValue(key, value);
+		#else
+			pthread_setspecific(key, value);
+		#endif
+	}
+
+	inline void *Thread::getLocalStorage(LocalStorageKey key)
+	{
+		#if defined(_WIN32)
+			return TlsGetValue(key);
+		#else
+			return pthread_getspecific(key);
+		#endif
+	}
+
+	inline void Event::signal()
+	{
+		#if defined(_WIN32)
+			SetEvent(handle);
+		#else
+			pthread_mutex_lock(&mutex);
+			signaled = true;
+			pthread_cond_signal(&handle);
+			pthread_mutex_unlock(&mutex);
+		#endif
+	}
+
+	inline void Event::wait()
+	{
+		#if defined(_WIN32)
+			WaitForSingleObject(handle, INFINITE);
+		#else
+			pthread_mutex_lock(&mutex);
+			while(!signaled) pthread_cond_wait(&handle, &mutex);
+			signaled = false;
+			pthread_mutex_unlock(&mutex);
+		#endif
+	}
+
+	#if PERF_PROFILE
+	inline int64_t atomicExchange(volatile int64_t *target, int64_t value)
+	{
+		#if defined(_WIN32)
+			return InterlockedExchange64(target, value);
+		#else
+			int ret;
+			__asm__ __volatile__("lock; xchg8 %0,(%1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );
+			return ret;
+		#endif
+	}
+	#endif
+
+	inline int atomicExchange(volatile int *target, int value)
+	{
+		#if defined(_WIN32)
+			return InterlockedExchange((volatile long*)target, (long)value);
+		#else
+			int ret;
+			__asm__ __volatile__("lock; xchgl %0,(%1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );
+			return ret;
+		#endif
+	}
+
+	inline int atomicIncrement(volatile int *value)
+	{
+		#if defined(_WIN32)
+			return InterlockedIncrement((volatile long*)value);
+		#else
+			return __sync_add_and_fetch(value, 1);
+		#endif
+	}
+
+	inline int atomicDecrement(volatile int *value)
+	{
+		#if defined(_WIN32)
+			return InterlockedDecrement((volatile long*)value);
+		#else
+			return __sync_sub_and_fetch(value, 1);
+		#endif
+	}
+
+	inline int atomicAdd(volatile int* target, int value)
+	{
+		#if defined(_MSC_VER)
+			return InterlockedExchangeAdd((volatile long*)target, value) + value;
+		#else
+			return __sync_add_and_fetch(target, value);
+		#endif
+	}
+
+	inline void nop()
+	{
+		#if defined(_WIN32)
+			__nop();
+		#else
+			__asm__ __volatile__ ("nop");
+		#endif
+	}
+}
+
+#endif   // sw_Thread_hpp
diff --git a/src/Common/Timer.cpp b/src/Common/Timer.cpp
index b2bbd1b..a147c8b 100644
--- a/src/Common/Timer.cpp
+++ b/src/Common/Timer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Timer.hpp"
 
diff --git a/src/Common/Timer.hpp b/src/Common/Timer.hpp
index 0b8b6c4..977c877 100644
--- a/src/Common/Timer.hpp
+++ b/src/Common/Timer.hpp
@@ -1,34 +1,37 @@
-// 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.

-//

-

-#ifndef sw_Timer_hpp

-#define sw_Timer_hpp

-

-#include "Types.hpp"

-

-namespace sw

-{

-	class Timer

-	{

-	public:

-		Timer();

-

-		~Timer();

-

-		static double seconds();

-		static int64_t ticks();

-

-		static int64_t counter();

-		static int64_t frequency();

-	};

-}

-

-#endif   // sw_Timer_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Timer_hpp
+#define sw_Timer_hpp
+
+#include "Types.hpp"
+
+namespace sw
+{
+	class Timer
+	{
+	public:
+		Timer();
+
+		~Timer();
+
+		static double seconds();
+		static int64_t ticks();
+
+		static int64_t counter();
+		static int64_t frequency();
+	};
+}
+
+#endif   // sw_Timer_hpp
diff --git a/src/Common/Types.hpp b/src/Common/Types.hpp
index 1337f4d..5675ccb 100644
--- a/src/Common/Types.hpp
+++ b/src/Common/Types.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_Types_hpp
 #define sw_Types_hpp
@@ -123,7 +126,7 @@
 
 		return v;
 	}
-	
+
 	inline float4 replicate(float f)
 	{
 		float4 v;
diff --git a/src/D3D9/Capabilities.cpp b/src/D3D9/Capabilities.cpp
index d6f3cf4..2449045 100644
--- a/src/D3D9/Capabilities.cpp
+++ b/src/D3D9/Capabilities.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Capabilities.hpp"
 
diff --git a/src/D3D9/Capabilities.hpp b/src/D3D9/Capabilities.hpp
index dc16fce..321160b 100644
--- a/src/D3D9/Capabilities.hpp
+++ b/src/D3D9/Capabilities.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Capabilities_hpp
 #define D3D9_Capabilities_hpp
diff --git a/src/D3D9/D3D9.cpp b/src/D3D9/D3D9.cpp
index 6a37094..156f544 100644
--- a/src/D3D9/D3D9.cpp
+++ b/src/D3D9/D3D9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3D9.hpp"
 #include "Direct3D9Ex.hpp"
@@ -103,37 +106,37 @@
 {
 	RECT rect;
 
-    switch(uMsg)
-    {
-    case WM_INITDIALOG:
+	switch(uMsg)
+	{
+	case WM_INITDIALOG:
 		GetWindowRect(GetDesktopWindow(), &rect);
 		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
 		SetTimer(hwnd, 1, 100, NULL);
 		return TRUE;
-    case WM_COMMAND:
-        if(LOWORD(wParam) == IDCANCEL)
+	case WM_COMMAND:
+		if(LOWORD(wParam) == IDCANCEL)
 		{
 			EndDialog(hwnd, 0);
 		}
-        break;
-    case WM_TIMER:
+		break;
+	case WM_TIMER:
 		if(IsDebuggerPresent())
 		{
 			EndDialog(hwnd, 0);
 		}
-    }
+	}
 
-    return FALSE;
+	return FALSE;
 }
 
 static void WaitForDebugger(HINSTANCE instance)
 {
-    if(!IsDebuggerPresent())
-    {
-        HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
+	if(!IsDebuggerPresent())
+	{
+		HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
 		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
 		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
-    }
+	}
 }
 
 using namespace D3D9;
@@ -288,7 +291,7 @@
 	void __stdcall D3DPERF_SetRegion(D3DCOLOR color, const wchar_t *name)
 	{
 		GTRACE("");
-	
+
 	//	UNIMPLEMENTED();   // PIX unsupported
 	}
 
@@ -305,7 +308,7 @@
 
 	//	UNIMPLEMENTED();   // Debug output unsupported
 	}
-	
+
 	void *__stdcall Direct3DShaderValidatorCreate9()
 	{
 		GTRACE("");
diff --git a/src/D3D9/D3D9.rc b/src/D3D9/D3D9.rc
index e927519..9245d0c 100644
--- a/src/D3D9/D3D9.rc
+++ b/src/D3D9/D3D9.rc
@@ -25,18 +25,18 @@
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE 
+1 TEXTINCLUDE
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE 
+2 TEXTINCLUDE
 BEGIN
     "#include ""afxres.h""\r\n"
     "#include ""../Common/Version.h""\0"
 END
 
-3 TEXTINCLUDE 
+3 TEXTINCLUDE
 BEGIN
     "\r\n"
     "\0"
@@ -67,14 +67,14 @@
     BEGIN
         BLOCK "040904b0"
         BEGIN
-            VALUE "CompanyName", "TransGaming"
-            VALUE "FileDescription", "SwiftShader Direct3D 9 Software Renderer"
+            VALUE "CompanyName", "Google Inc."
+            VALUE "FileDescription", "SwiftShader Direct3D 9 Renderer"
             VALUE "FileVersion", VERSION_STRING
             VALUE "InternalName", "D3D9"
-            VALUE "LegalCopyright", "Copyright (C) 2011 TransGaming Inc."
+            VALUE "LegalCopyright", "Copyright (C) 2016 Google Inc."
             VALUE "OriginalFilename", "d3d9.dll"
             VALUE "PrivateBuild", REVISION_STRING
-            VALUE "ProductName", "SwiftShader Direct3D 9 Software Renderer"
+            VALUE "ProductName", "SwiftShader Direct3D 9 Renderer"
             VALUE "ProductVersion", VERSION_STRING
         END
     END
diff --git a/src/D3D9/Debug.cpp b/src/D3D9/Debug.cpp
index 0ad0731..fc9f697 100644
--- a/src/D3D9/Debug.cpp
+++ b/src/D3D9/Debug.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Debug.hpp"
 
diff --git a/src/D3D9/Debug.hpp b/src/D3D9/Debug.hpp
index eb7ed51..17c4a55 100644
--- a/src/D3D9/Debug.hpp
+++ b/src/D3D9/Debug.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef Debug_hpp
 #define Debug_hpp
diff --git a/src/D3D9/Direct3D9.cpp b/src/D3D9/Direct3D9.cpp
index 9c1a431..897973c 100644
--- a/src/D3D9/Direct3D9.cpp
+++ b/src/D3D9/Direct3D9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3D9.hpp"
 
@@ -69,7 +72,7 @@
 		else if(ps <= 21) pixelShaderVersionX = D3DPS_VERSION(2, 1);
 		else              pixelShaderVersionX = D3DPS_VERSION(3, 0);
 
-             if(vs ==  0) vertexShaderVersionX = D3DVS_VERSION(0, 0);
+		     if(vs ==  0) vertexShaderVersionX = D3DVS_VERSION(0, 0);
 		else if(vs <= 11) vertexShaderVersionX = D3DVS_VERSION(1, 1);
 		else if(vs <= 20) vertexShaderVersionX = D3DVS_VERSION(2, 0);
 		else if(vs <= 21) vertexShaderVersionX = D3DVS_VERSION(2, 1);
@@ -224,7 +227,7 @@
 				return CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, adapterFormat, usage, resourceType, checkFormat);
 			}
 		}
-		
+
 		if(usage & D3DUSAGE_QUERY_SRGBREAD)
 		{
 			if(!Capabilities::isSRGBreadable(checkFormat))
@@ -989,7 +992,7 @@
 		}
 
 		HDC deviceContext = GetDC(0);
-			
+
 		mode->Width = ::GetDeviceCaps(deviceContext, HORZRES);
 		mode->Height = ::GetDeviceCaps(deviceContext, VERTRES);
 		mode->RefreshRate = ::GetDeviceCaps(deviceContext, VREFRESH);
@@ -1108,7 +1111,7 @@
 		identifier->DriverVersion.HighPart = product << 16 | version;
 		identifier->DriverVersion.LowPart = subVersion << 16 | revision;
 		strcpy(identifier->Driver, "SwiftShader");
-		strcpy(identifier->Description, "TransGaming SwiftShader Software 3D Renderer");
+		strcpy(identifier->Description, "Google SwiftShader 3D Renderer");
 		strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
 		identifier->VendorId = 0;
 		identifier->DeviceId = 0;
@@ -1228,10 +1231,10 @@
 		// Caps from DX7
 		caps.Caps =	D3DCAPS_READ_SCANLINE;
 
-		caps.Caps2 =		D3DCAPS2_CANAUTOGENMIPMAP |		// The driver is capable of automatically generating mipmaps. For more information, see Automatic Generation of Mipmaps. 
-						//	D3DCAPS2_CANCALIBRATEGAMMA |	// The system has a calibrator installed that can automatically adjust the gamma ramp so that the result is identical on all systems that have a calibrator. To invoke the calibrator when setting new gamma levels, use the D3DSGR_CALIBRATE flag when calling IDirect3DDevice9::SetGammaRamp. Calibrating gamma ramps incurs some processing overhead and should not be used frequently.  
-						//	D3DCAPS2_CANMANAGERESOURCE |	// The driver is capable of managing resources. On such drivers, D3DPOOL_MANAGED resources will be managed by the driver. To have Microsoft® Direct3D® override the driver so that Direct3D manages resources, use the D3DCREATE_DISABLE_DRIVER_MANAGEMENT flag when calling IDirect3D9::CreateDevice. 
-							D3DCAPS2_DYNAMICTEXTURES | 		// The driver supports dynamic textures. 
+		caps.Caps2 =		D3DCAPS2_CANAUTOGENMIPMAP |		// The driver is capable of automatically generating mipmaps. For more information, see Automatic Generation of Mipmaps.
+						//	D3DCAPS2_CANCALIBRATEGAMMA |	// The system has a calibrator installed that can automatically adjust the gamma ramp so that the result is identical on all systems that have a calibrator. To invoke the calibrator when setting new gamma levels, use the D3DSGR_CALIBRATE flag when calling IDirect3DDevice9::SetGammaRamp. Calibrating gamma ramps incurs some processing overhead and should not be used frequently.
+						//	D3DCAPS2_CANMANAGERESOURCE |	// The driver is capable of managing resources. On such drivers, D3DPOOL_MANAGED resources will be managed by the driver. To have Microsoft® Direct3D® override the driver so that Direct3D manages resources, use the D3DCREATE_DISABLE_DRIVER_MANAGEMENT flag when calling IDirect3D9::CreateDevice.
+							D3DCAPS2_DYNAMICTEXTURES | 		// The driver supports dynamic textures.
 							D3DCAPS2_FULLSCREENGAMMA;		// The driver supports dynamic gamma ramp adjustment in full-screen mode.
 						//	D3DCAPS2_CANSHARERESOURCE;
 
@@ -1242,201 +1245,201 @@
 
 		caps.PresentationIntervals =		D3DPRESENT_INTERVAL_IMMEDIATE |
 											D3DPRESENT_INTERVAL_ONE;
-									 	//	D3DPRESENT_INTERVAL_TWO;
-									 	//	D3DPRESENT_INTERVAL_THREE;
-									 	//	D3DPRESENT_INTERVAL_FOUR;
+										//	D3DPRESENT_INTERVAL_TWO;
+										//	D3DPRESENT_INTERVAL_THREE;
+										//	D3DPRESENT_INTERVAL_FOUR;
 
 		// Cursor caps
-		caps.CursorCaps =	D3DCURSORCAPS_COLOR	|	// A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports at least a hardware color cursor in high-resolution modes (with scan lines greater than or equal to 400). 
-							D3DCURSORCAPS_LOWRES;	// A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports a hardware color cursor in both high-resolution and low-resolution modes (with scan lines less than 400). 
+		caps.CursorCaps =	D3DCURSORCAPS_COLOR	|	// A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports at least a hardware color cursor in high-resolution modes (with scan lines greater than or equal to 400).
+							D3DCURSORCAPS_LOWRES;	// A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports a hardware color cursor in both high-resolution and low-resolution modes (with scan lines less than 400).
 
 		// 3D Device caps
-		caps.DevCaps =		D3DDEVCAPS_CANBLTSYSTONONLOCAL |		// Device supports blits from system-memory textures to nonlocal video-memory textures. 
-							D3DDEVCAPS_CANRENDERAFTERFLIP |			// Device can queue rendering commands after a page flip. Applications do not change their behavior if this flag is set; this capability means that the device is relatively fast. 
+		caps.DevCaps =		D3DDEVCAPS_CANBLTSYSTONONLOCAL |		// Device supports blits from system-memory textures to nonlocal video-memory textures.
+							D3DDEVCAPS_CANRENDERAFTERFLIP |			// Device can queue rendering commands after a page flip. Applications do not change their behavior if this flag is set; this capability means that the device is relatively fast.
 							D3DDEVCAPS_DRAWPRIMITIVES2 |			// Device can support DrawPrimitives2.
 							D3DDEVCAPS_DRAWPRIMITIVES2EX |			// Device can support extended DrawPrimitives2; that is, this is a DirectX 7.0-compliant driver.
-							D3DDEVCAPS_DRAWPRIMTLVERTEX |			// Device exports an IDirect3DDevice9::DrawPrimitive-aware hardware abstraction layer (HAL). 
+							D3DDEVCAPS_DRAWPRIMTLVERTEX |			// Device exports an IDirect3DDevice9::DrawPrimitive-aware hardware abstraction layer (HAL).
 							D3DDEVCAPS_EXECUTESYSTEMMEMORY |		// Device can use execute buffers from system memory.
-							D3DDEVCAPS_EXECUTEVIDEOMEMORY |			// Device can use execute buffers from video memory. 
-							D3DDEVCAPS_HWRASTERIZATION |			// Device has hardware acceleration for scene rasterization. 
-							D3DDEVCAPS_HWTRANSFORMANDLIGHT |		// Device can support transformation and lighting in hardware. 
-						//	D3DDEVCAPS_NPATCHES |					// Device supports N patches. 
-							D3DDEVCAPS_PUREDEVICE |					// Device can support rasterization, transform, lighting, and shading in hardware. 
-						//	D3DDEVCAPS_QUINTICRTPATCHES |			// Device supports quintic Bézier curves and B-splines. 
-						//	D3DDEVCAPS_RTPATCHES |					// Device supports rectangular and triangular patches. 
-							D3DDEVCAPS_RTPATCHHANDLEZERO |			// When this device capability is set, the hardware architecture does not require caching of any information and uncached patches (handle zero) will be drawn as efficiently as cached ones. Note that setting D3DDEVCAPS_RTPATCHHANDLEZERO does not mean that a patch with handle zero can be drawn. A handle-zero patch can always be drawn whether this cap is set or not. 
-						//	D3DDEVCAPS_SEPARATETEXTUREMEMORIES |	// Device is texturing from separate memory pools. 
-							D3DDEVCAPS_TEXTURENONLOCALVIDMEM |		// Device can retrieve textures from non-local video memory. 
-							D3DDEVCAPS_TEXTURESYSTEMMEMORY |		// Device can retrieve textures from system memory. 
-							D3DDEVCAPS_TEXTUREVIDEOMEMORY |			// Device can retrieve textures from device memory. 
-							D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |		// Device can use buffers from system memory for transformed and lit vertices. 
+							D3DDEVCAPS_EXECUTEVIDEOMEMORY |			// Device can use execute buffers from video memory.
+							D3DDEVCAPS_HWRASTERIZATION |			// Device has hardware acceleration for scene rasterization.
+							D3DDEVCAPS_HWTRANSFORMANDLIGHT |		// Device can support transformation and lighting in hardware.
+						//	D3DDEVCAPS_NPATCHES |					// Device supports N patches.
+							D3DDEVCAPS_PUREDEVICE |					// Device can support rasterization, transform, lighting, and shading in hardware.
+						//	D3DDEVCAPS_QUINTICRTPATCHES |			// Device supports quintic Bézier curves and B-splines.
+						//	D3DDEVCAPS_RTPATCHES |					// Device supports rectangular and triangular patches.
+							D3DDEVCAPS_RTPATCHHANDLEZERO |			// When this device capability is set, the hardware architecture does not require caching of any information and uncached patches (handle zero) will be drawn as efficiently as cached ones. Note that setting D3DDEVCAPS_RTPATCHHANDLEZERO does not mean that a patch with handle zero can be drawn. A handle-zero patch can always be drawn whether this cap is set or not.
+						//	D3DDEVCAPS_SEPARATETEXTUREMEMORIES |	// Device is texturing from separate memory pools.
+							D3DDEVCAPS_TEXTURENONLOCALVIDMEM |		// Device can retrieve textures from non-local video memory.
+							D3DDEVCAPS_TEXTURESYSTEMMEMORY |		// Device can retrieve textures from system memory.
+							D3DDEVCAPS_TEXTUREVIDEOMEMORY |			// Device can retrieve textures from device memory.
+							D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |		// Device can use buffers from system memory for transformed and lit vertices.
 							D3DDEVCAPS_TLVERTEXVIDEOMEMORY;			// Device can use buffers from video memory for transformed and lit vertices.
 
-		caps.PrimitiveMiscCaps = 		D3DPMISCCAPS_MASKZ |						// Device can enable and disable modification of the depth buffer on pixel operations. 
-										D3DPMISCCAPS_CULLNONE |						// The driver does not perform triangle culling. This corresponds to the D3DCULL_NONE member of the D3DCULL enumerated type. 
-										D3DPMISCCAPS_CULLCW |						// The driver supports clockwise triangle culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CW member of the D3DCULL enumerated type. 
-										D3DPMISCCAPS_CULLCCW |						// The driver supports counterclockwise culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CCW member of the D3DCULL enumerated type. 
-										D3DPMISCCAPS_COLORWRITEENABLE |				// Device supports per-channel writes for the render-target color buffer through the D3DRS_COLORWRITEENABLE state. 
-										D3DPMISCCAPS_CLIPPLANESCALEDPOINTS |		// Device correctly clips scaled points of size greater than 1.0 to user-defined clipping planes. 
-										D3DPMISCCAPS_CLIPTLVERTS |					// Device clips post-transformed vertex primitives. Specify D3DUSAGE_DONOTCLIP when the pipeline should not do any clipping. For this case, additional software clipping may need to be performed at draw time, requiring the vertex buffer to be in system memory. 
-										D3DPMISCCAPS_TSSARGTEMP |					// Device supports D3DTA for temporary register. 
-										D3DPMISCCAPS_BLENDOP |						// Device supports alpha-blending operations other than D3DBLENDOP_ADD. 
-									//	D3DPMISCCAPS_NULLREFERENCE |				// A reference device that does not render. 
-										D3DPMISCCAPS_INDEPENDENTWRITEMASKS |		// Device supports independent write masks for multiple element textures or multiple render targets. 
-										D3DPMISCCAPS_PERSTAGECONSTANT |				// Device supports per-stage constants. See D3DTSS_CONSTANT in D3DTEXTURESTAGESTATETYPE. 
-										D3DPMISCCAPS_FOGANDSPECULARALPHA |			// Device supports separate fog and specular alpha. Many devices use the specular alpha channel to store the fog factor. 
-										D3DPMISCCAPS_SEPARATEALPHABLEND |			// Device supports separate blend settings for the alpha channel. 
-										D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS |		// Device supports different bit depths for multiple render targets. 
-										D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING |	// Device supports post-pixel shader operations for multiple render targets. 
+		caps.PrimitiveMiscCaps = 		D3DPMISCCAPS_MASKZ |						// Device can enable and disable modification of the depth buffer on pixel operations.
+										D3DPMISCCAPS_CULLNONE |						// The driver does not perform triangle culling. This corresponds to the D3DCULL_NONE member of the D3DCULL enumerated type.
+										D3DPMISCCAPS_CULLCW |						// The driver supports clockwise triangle culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CW member of the D3DCULL enumerated type.
+										D3DPMISCCAPS_CULLCCW |						// The driver supports counterclockwise culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CCW member of the D3DCULL enumerated type.
+										D3DPMISCCAPS_COLORWRITEENABLE |				// Device supports per-channel writes for the render-target color buffer through the D3DRS_COLORWRITEENABLE state.
+										D3DPMISCCAPS_CLIPPLANESCALEDPOINTS |		// Device correctly clips scaled points of size greater than 1.0 to user-defined clipping planes.
+										D3DPMISCCAPS_CLIPTLVERTS |					// Device clips post-transformed vertex primitives. Specify D3DUSAGE_DONOTCLIP when the pipeline should not do any clipping. For this case, additional software clipping may need to be performed at draw time, requiring the vertex buffer to be in system memory.
+										D3DPMISCCAPS_TSSARGTEMP |					// Device supports D3DTA for temporary register.
+										D3DPMISCCAPS_BLENDOP |						// Device supports alpha-blending operations other than D3DBLENDOP_ADD.
+									//	D3DPMISCCAPS_NULLREFERENCE |				// A reference device that does not render.
+										D3DPMISCCAPS_INDEPENDENTWRITEMASKS |		// Device supports independent write masks for multiple element textures or multiple render targets.
+										D3DPMISCCAPS_PERSTAGECONSTANT |				// Device supports per-stage constants. See D3DTSS_CONSTANT in D3DTEXTURESTAGESTATETYPE.
+										D3DPMISCCAPS_FOGANDSPECULARALPHA |			// Device supports separate fog and specular alpha. Many devices use the specular alpha channel to store the fog factor.
+										D3DPMISCCAPS_SEPARATEALPHABLEND |			// Device supports separate blend settings for the alpha channel.
+										D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS |		// Device supports different bit depths for multiple render targets.
+										D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING |	// Device supports post-pixel shader operations for multiple render targets.
 										D3DPMISCCAPS_FOGVERTEXCLAMPED;				// Device clamps fog blend factor per vertex.
 
-		caps.RasterCaps =		D3DPRASTERCAPS_ANISOTROPY |				// Device supports anisotropic filtering. 
-								D3DPRASTERCAPS_COLORPERSPECTIVE |		// Device iterates colors perspective correctly. 
-							//	D3DPRASTERCAPS_DITHER |					// Device can dither to improve color resolution. 
+		caps.RasterCaps =		D3DPRASTERCAPS_ANISOTROPY |				// Device supports anisotropic filtering.
+								D3DPRASTERCAPS_COLORPERSPECTIVE |		// Device iterates colors perspective correctly.
+							//	D3DPRASTERCAPS_DITHER |					// Device can dither to improve color resolution.
 								D3DPRASTERCAPS_DEPTHBIAS |				// Device supports legacy depth bias. For true depth bias, see D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS.
-								D3DPRASTERCAPS_FOGRANGE |				// Device supports range-based fog. In range-based fog, the distance of an object from the viewer is used to compute fog effects, not the depth of the object (that is, the z-coordinate) in the scene. 
-								D3DPRASTERCAPS_FOGTABLE |				// Device calculates the fog value by referring to a lookup table containing fog values that are indexed to the depth of a given pixel. 
-								D3DPRASTERCAPS_FOGVERTEX |				// Device calculates the fog value during the lighting operation and interpolates the fog value during rasterization. 
+								D3DPRASTERCAPS_FOGRANGE |				// Device supports range-based fog. In range-based fog, the distance of an object from the viewer is used to compute fog effects, not the depth of the object (that is, the z-coordinate) in the scene.
+								D3DPRASTERCAPS_FOGTABLE |				// Device calculates the fog value by referring to a lookup table containing fog values that are indexed to the depth of a given pixel.
+								D3DPRASTERCAPS_FOGVERTEX |				// Device calculates the fog value during the lighting operation and interpolates the fog value during rasterization.
 								D3DPRASTERCAPS_MIPMAPLODBIAS |			// Device supports level of detail (LOD) bias adjustments. These bias adjustments enable an application to make a mipmap appear crisper or less sharp than it normally would. For more information about LOD bias in mipmaps, see D3DSAMP_MIPMAPLODBIAS.
-							//	D3DPRASTERCAPS_MULTISAMPLE_TOGGLE |		// Device supports toggling multisampling on and off between IDirect3DDevice9::BeginScene and IDirect3DDevice9::EndScene (using D3DRS_MULTISAMPLEANTIALIAS). 
+							//	D3DPRASTERCAPS_MULTISAMPLE_TOGGLE |		// Device supports toggling multisampling on and off between IDirect3DDevice9::BeginScene and IDirect3DDevice9::EndScene (using D3DRS_MULTISAMPLEANTIALIAS).
 								D3DPRASTERCAPS_SCISSORTEST |			// Device supports scissor test. See Scissor Test.
 								D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |	// Device performs true slope-scale based depth bias. This is in contrast to the legacy style D3DPRASTERCAPS_DEPTHBIAS.
-							//	D3DPRASTERCAPS_WBUFFER |				// Device supports depth buffering using w. 
-								D3DPRASTERCAPS_WFOG |					// Device supports w-based fog. W-based fog is used when a perspective projection matrix is specified, but affine projections still use z-based fog. The system considers a projection matrix that contains a nonzero value in the [3][4] element to be a perspective projection matrix. 
+							//	D3DPRASTERCAPS_WBUFFER |				// Device supports depth buffering using w.
+								D3DPRASTERCAPS_WFOG |					// Device supports w-based fog. W-based fog is used when a perspective projection matrix is specified, but affine projections still use z-based fog. The system considers a projection matrix that contains a nonzero value in the [3][4] element to be a perspective projection matrix.
 							//	D3DPRASTERCAPS_ZBUFFERLESSHSR |			// Device can perform hidden-surface removal (HSR) without requiring the application to sort polygons and without requiring the allocation of a depth-buffer. This leaves more video memory for textures. The method used to perform HSR is hardware-dependent and is transparent to the application. Z-bufferless HSR is performed if no depth-buffer surface is associated with the rendering-target surface and the depth-buffer comparison test is enabled (that is, when the state value associated with the D3DRS_ZENABLE enumeration constant is set to TRUE).
-								D3DPRASTERCAPS_ZFOG |					// Device supports z-based fog. 
+								D3DPRASTERCAPS_ZFOG |					// Device supports z-based fog.
 								D3DPRASTERCAPS_ZTEST;					// Device can perform z-test operations. This effectively renders a primitive and indicates whether any z pixels have been rendered.
 
-		caps.ZCmpCaps =		D3DPCMPCAPS_ALWAYS |		// Always pass the z-test. 
-							D3DPCMPCAPS_EQUAL |			// Pass the z-test if the new z equals the current z. 
-							D3DPCMPCAPS_GREATER |		// Pass the z-test if the new z is greater than the current z. 
-							D3DPCMPCAPS_GREATEREQUAL |	// Pass the z-test if the new z is greater than or equal to the current z. 
-							D3DPCMPCAPS_LESS |			// Pass the z-test if the new z is less than the current z. 
-							D3DPCMPCAPS_LESSEQUAL |		// Pass the z-test if the new z is less than or equal to the current z. 
-							D3DPCMPCAPS_NEVER |			// Always fail the z-test. 
+		caps.ZCmpCaps =		D3DPCMPCAPS_ALWAYS |		// Always pass the z-test.
+							D3DPCMPCAPS_EQUAL |			// Pass the z-test if the new z equals the current z.
+							D3DPCMPCAPS_GREATER |		// Pass the z-test if the new z is greater than the current z.
+							D3DPCMPCAPS_GREATEREQUAL |	// Pass the z-test if the new z is greater than or equal to the current z.
+							D3DPCMPCAPS_LESS |			// Pass the z-test if the new z is less than the current z.
+							D3DPCMPCAPS_LESSEQUAL |		// Pass the z-test if the new z is less than or equal to the current z.
+							D3DPCMPCAPS_NEVER |			// Always fail the z-test.
 							D3DPCMPCAPS_NOTEQUAL;		// Pass the z-test if the new z does not equal the current z.
 
 		caps.SrcBlendCaps =		D3DPBLENDCAPS_BLENDFACTOR |		// The driver supports both D3DBLEND_BLENDFACTOR and D3DBLEND_INVBLENDFACTOR. See D3DBLEND.
-								D3DPBLENDCAPS_BOTHINVSRCALPHA |	// Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden. 
-								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.) 
-								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad). 
-								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad). 
-								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad). 
-								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad). 
-								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As). 
-								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As). 
-								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1). 
-								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As). 
-								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad). 
-								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As). 
+								D3DPBLENDCAPS_BOTHINVSRCALPHA |	// Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden.
+								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
+								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad).
+								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad).
+								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
+								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
+								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As).
+								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
+								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1).
+								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As).
+								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
+								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As).
 								D3DPBLENDCAPS_ZERO;				// Blend factor is (0, 0, 0, 0).
 
 		caps.DestBlendCaps = 	D3DPBLENDCAPS_BLENDFACTOR |		// The driver supports both D3DBLEND_BLENDFACTOR and D3DBLEND_INVBLENDFACTOR. See D3DBLEND.
-								D3DPBLENDCAPS_BOTHINVSRCALPHA |	// Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden. 
-								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.) 
-								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad). 
-								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad). 
-								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad). 
-								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad). 
-								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As). 
-								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As). 
-								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1). 
-								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As). 
-								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad). 
-								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As). 
+								D3DPBLENDCAPS_BOTHINVSRCALPHA |	// Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden.
+								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
+								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad).
+								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad).
+								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
+								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
+								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As).
+								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
+								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1).
+								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As).
+								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
+								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As).
 								D3DPBLENDCAPS_ZERO;				// Blend factor is (0, 0, 0, 0).
 
-		caps.AlphaCmpCaps = D3DPCMPCAPS_ALWAYS |		// Always pass the apha-test. 
-							D3DPCMPCAPS_EQUAL |			// Pass the apha-test if the new apha equals the current apha. 
-							D3DPCMPCAPS_GREATER |		// Pass the apha-test if the new apha is greater than the current apha. 
-							D3DPCMPCAPS_GREATEREQUAL |	// Pass the apha-test if the new apha is greater than or equal to the current apha. 
-							D3DPCMPCAPS_LESS |			// Pass the apha-test if the new apha is less than the current apha. 
-							D3DPCMPCAPS_LESSEQUAL |		// Pass the apha-test if the new apha is less than or equal to the current apha. 
-							D3DPCMPCAPS_NEVER |			// Always fail the apha-test. 
+		caps.AlphaCmpCaps = D3DPCMPCAPS_ALWAYS |		// Always pass the apha-test.
+							D3DPCMPCAPS_EQUAL |			// Pass the apha-test if the new apha equals the current apha.
+							D3DPCMPCAPS_GREATER |		// Pass the apha-test if the new apha is greater than the current apha.
+							D3DPCMPCAPS_GREATEREQUAL |	// Pass the apha-test if the new apha is greater than or equal to the current apha.
+							D3DPCMPCAPS_LESS |			// Pass the apha-test if the new apha is less than the current apha.
+							D3DPCMPCAPS_LESSEQUAL |		// Pass the apha-test if the new apha is less than or equal to the current apha.
+							D3DPCMPCAPS_NEVER |			// Always fail the apha-test.
 							D3DPCMPCAPS_NOTEQUAL;		// Pass the apha-test if the new apha does not equal the current apha.
 
-		caps.ShadeCaps =	D3DPSHADECAPS_ALPHAGOURAUDBLEND |	// Device can support an alpha component for Gouraud-blended transparency (the D3DSHADE_GOURAUD state for the D3DSHADEMODE enumerated type). In this mode, the alpha color component of a primitive is provided at vertices and interpolated across a face along with the other color components. 
-							D3DPSHADECAPS_COLORGOURAUDRGB |		// Device can support colored Gouraud shading in the RGB color model. In this mode, the color component for a primitive is provided at vertices and interpolated across a face along with the other color components. In the RGB lighting model, the red, green, and blue components are interpolated. 
-							D3DPSHADECAPS_FOGGOURAUD |			// Device can support fog in the Gouraud shading mode. 
+		caps.ShadeCaps =	D3DPSHADECAPS_ALPHAGOURAUDBLEND |	// Device can support an alpha component for Gouraud-blended transparency (the D3DSHADE_GOURAUD state for the D3DSHADEMODE enumerated type). In this mode, the alpha color component of a primitive is provided at vertices and interpolated across a face along with the other color components.
+							D3DPSHADECAPS_COLORGOURAUDRGB |		// Device can support colored Gouraud shading in the RGB color model. In this mode, the color component for a primitive is provided at vertices and interpolated across a face along with the other color components. In the RGB lighting model, the red, green, and blue components are interpolated.
+							D3DPSHADECAPS_FOGGOURAUD |			// Device can support fog in the Gouraud shading mode.
 							D3DPSHADECAPS_SPECULARGOURAUDRGB;	// Device supports Gouraud shading of specular highlights.
 
-		caps.TextureCaps =		D3DPTEXTURECAPS_ALPHA |						// Alpha in texture pixels is supported. 
-								D3DPTEXTURECAPS_ALPHAPALETTE |				// Device can draw alpha from texture palettes. 
+		caps.TextureCaps =		D3DPTEXTURECAPS_ALPHA |						// Alpha in texture pixels is supported.
+								D3DPTEXTURECAPS_ALPHAPALETTE |				// Device can draw alpha from texture palettes.
 								D3DPTEXTURECAPS_CUBEMAP |					// Supports cube textures.
-							//	D3DPTEXTURECAPS_CUBEMAP_POW2 |				// Device requires that cube texture maps have dimensions specified as powers of two. 
-								D3DPTEXTURECAPS_MIPCUBEMAP |				// Device supports mipmapped cube textures. 
-								D3DPTEXTURECAPS_MIPMAP |					// Device supports mipmapped textures. 
-								D3DPTEXTURECAPS_MIPVOLUMEMAP |				// Device supports mipmapped volume textures. 
+							//	D3DPTEXTURECAPS_CUBEMAP_POW2 |				// Device requires that cube texture maps have dimensions specified as powers of two.
+								D3DPTEXTURECAPS_MIPCUBEMAP |				// Device supports mipmapped cube textures.
+								D3DPTEXTURECAPS_MIPMAP |					// Device supports mipmapped textures.
+								D3DPTEXTURECAPS_MIPVOLUMEMAP |				// Device supports mipmapped volume textures.
 							//	D3DPTEXTURECAPS_NONPOW2CONDITIONAL |		// Conditionally supports the use of 2-D textures with dimensions that are not powers of two. A device that exposes this capability can use such a texture if all of the following requirements are met...
-							//	D3DPTEXTURECAPS_NOPROJECTEDBUMPENV |		// Device does not support a projected bump-environment loopkup operation in programmable and fixed function shaders. 
+							//	D3DPTEXTURECAPS_NOPROJECTEDBUMPENV |		// Device does not support a projected bump-environment loopkup operation in programmable and fixed function shaders.
 								D3DPTEXTURECAPS_PERSPECTIVE |				// Perspective correction texturing is supported.
 							//	D3DPTEXTURECAPS_POW2 |						// All textures must have widths and heights specified as powers of two. This requirement does not apply to either cube textures or volume textures.
-								D3DPTEXTURECAPS_PROJECTED |					// Supports the D3DTTFF_PROJECTED texture transformation flag. When applied, the device divides transformed texture coordinates by the last texture coordinate. If this capability is present, then the projective divide occurs per pixel. If this capability is not present, but the projective divide needs to occur anyway, then it is performed on a per-vertex basis by the Direct3D runtime. 
-							//	D3DPTEXTURECAPS_SQUAREONLY |				// All textures must be square. 
+								D3DPTEXTURECAPS_PROJECTED |					// Supports the D3DTTFF_PROJECTED texture transformation flag. When applied, the device divides transformed texture coordinates by the last texture coordinate. If this capability is present, then the projective divide occurs per pixel. If this capability is not present, but the projective divide needs to occur anyway, then it is performed on a per-vertex basis by the Direct3D runtime.
+							//	D3DPTEXTURECAPS_SQUAREONLY |				// All textures must be square.
 								D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE |	// Texture indices are not scaled by the texture size prior to interpolation.
 								D3DPTEXTURECAPS_VOLUMEMAP;					// Device supports volume textures.
-							//	D3DPTEXTURECAPS_VOLUMEMAP_POW2;				// Device requires that volume texture maps have dimensions specified as powers of two. 
+							//	D3DPTEXTURECAPS_VOLUMEMAP_POW2;				// Device requires that volume texture maps have dimensions specified as powers of two.
 
-		caps.TextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-									//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-									//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type. 
-									//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures. 
-										D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-									//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures. 
-									//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures. 
-										D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
+		caps.TextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+										D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+									//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+									//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+									//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
+										D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+										D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+										D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+									//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
+									//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
+										D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+										D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
 
-		caps.CubeTextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-											D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures. 
-											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-											D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures. 
-										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures. 
-											D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-											D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
+		caps.CubeTextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+											D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
+											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+											D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
+										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
+											D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+											D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
 
-		caps.VolumeTextureFilterCaps = 		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-											D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures. 
-											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-											D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures. 
-										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures. 
-											D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-											D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
+		caps.VolumeTextureFilterCaps = 		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+											D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
+											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+											D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
+										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
+											D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+											D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
 
-		caps.TextureAddressCaps =	D3DPTADDRESSCAPS_BORDER |			// Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state. 
-									D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses. 
-									D3DPTADDRESSCAPS_INDEPENDENTUV |	// Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values. 
-									D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses. 
-									D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value. 
+		caps.TextureAddressCaps =	D3DPTADDRESSCAPS_BORDER |			// Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state.
+									D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses.
+									D3DPTADDRESSCAPS_INDEPENDENTUV |	// Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values.
+									D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses.
+									D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
 									D3DPTADDRESSCAPS_WRAP;				// Device can wrap textures to addresses.
 
-		caps.VolumeTextureAddressCaps =	D3DPTADDRESSCAPS_BORDER |			// Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state. 
-										D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses. 
-										D3DPTADDRESSCAPS_INDEPENDENTUV |	// Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values. 
-										D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses. 
-										D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value. 
+		caps.VolumeTextureAddressCaps =	D3DPTADDRESSCAPS_BORDER |			// Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state.
+										D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses.
+										D3DPTADDRESSCAPS_INDEPENDENTUV |	// Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values.
+										D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses.
+										D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
 										D3DPTADDRESSCAPS_WRAP;				// Device can wrap textures to addresses.
 
-		caps.LineCaps =		D3DLINECAPS_ALPHACMP |	// Supports alpha-test comparisons. 
+		caps.LineCaps =		D3DLINECAPS_ALPHACMP |	// Supports alpha-test comparisons.
 						//	D3DLINECAPS_ANTIALIAS | // Antialiased lines are supported.
-							D3DLINECAPS_BLEND |		// Supports source-blending. 
-							D3DLINECAPS_FOG |		// Supports fog. 
-							D3DLINECAPS_TEXTURE |	// Supports texture-mapping. 
+							D3DLINECAPS_BLEND |		// Supports source-blending.
+							D3DLINECAPS_FOG |		// Supports fog.
+							D3DLINECAPS_TEXTURE |	// Supports texture-mapping.
 							D3DLINECAPS_ZTEST;		// Supports z-buffer comparisons.
-		
+
 		caps.MaxTextureWidth = 1 << (sw::MIPMAP_LEVELS - 1);
 		caps.MaxTextureHeight = 1 << (sw::MIPMAP_LEVELS - 1);
 		caps.MaxVolumeExtent = 1 << (sw::MIPMAP_LEVELS - 1);
@@ -1452,63 +1455,63 @@
 
 		caps.ExtentsAdjust = 0;
 
-		caps.StencilCaps =		D3DSTENCILCAPS_KEEP |		// Do not update the entry in the stencil buffer. This is the default value. 
-								D3DSTENCILCAPS_ZERO |		// Set the stencil-buffer entry to 0. 
-								D3DSTENCILCAPS_REPLACE |	// Replace the stencil-buffer entry with reference value. 
-								D3DSTENCILCAPS_INCRSAT |	// Increment the stencil-buffer entry, clamping to the maximum value.  
-								D3DSTENCILCAPS_DECRSAT |	// Decrement the stencil-buffer entry, clamping to zero. 
-								D3DSTENCILCAPS_INVERT |		// Invert the bits in the stencil-buffer entry. 
-								D3DSTENCILCAPS_INCR |		// Increment the stencil-buffer entry, wrapping to zero if the new value exceeds the maximum value.  
-								D3DSTENCILCAPS_DECR |		// Decrement the stencil-buffer entry, wrapping to the maximum value if the new value is less than zero. 
-								D3DSTENCILCAPS_TWOSIDED;	// The device supports two-sided stencil. 
+		caps.StencilCaps =		D3DSTENCILCAPS_KEEP |		// Do not update the entry in the stencil buffer. This is the default value.
+								D3DSTENCILCAPS_ZERO |		// Set the stencil-buffer entry to 0.
+								D3DSTENCILCAPS_REPLACE |	// Replace the stencil-buffer entry with reference value.
+								D3DSTENCILCAPS_INCRSAT |	// Increment the stencil-buffer entry, clamping to the maximum value.
+								D3DSTENCILCAPS_DECRSAT |	// Decrement the stencil-buffer entry, clamping to zero.
+								D3DSTENCILCAPS_INVERT |		// Invert the bits in the stencil-buffer entry.
+								D3DSTENCILCAPS_INCR |		// Increment the stencil-buffer entry, wrapping to zero if the new value exceeds the maximum value.
+								D3DSTENCILCAPS_DECR |		// Decrement the stencil-buffer entry, wrapping to the maximum value if the new value is less than zero.
+								D3DSTENCILCAPS_TWOSIDED;	// The device supports two-sided stencil.
 
-		caps.FVFCaps =		D3DFVFCAPS_DONOTSTRIPELEMENTS |		// It is preferable that vertex elements not be stripped. That is, if the vertex format contains elements that are not used with the current render states, there is no need to regenerate the vertices. If this capability flag is not present, stripping extraneous elements from the vertex format provides better performance. 
+		caps.FVFCaps =		D3DFVFCAPS_DONOTSTRIPELEMENTS |		// It is preferable that vertex elements not be stripped. That is, if the vertex format contains elements that are not used with the current render states, there is no need to regenerate the vertices. If this capability flag is not present, stripping extraneous elements from the vertex format provides better performance.
 							D3DFVFCAPS_PSIZE |					// Point size is determined by either the render state or the vertex data.
-						//	D3DFVFCAPS_TEXCOORDCOUNTMASK |		// Masks the low WORD of FVFCaps. These bits, cast to the WORD data type, describe the total number of texture coordinate sets that the device can simultaneously use for multiple texture blending. (You can use up to eight texture coordinate sets for any vertex, but the device can blend using only the specified number of texture coordinate sets.) 
+						//	D3DFVFCAPS_TEXCOORDCOUNTMASK |		// Masks the low WORD of FVFCaps. These bits, cast to the WORD data type, describe the total number of texture coordinate sets that the device can simultaneously use for multiple texture blending. (You can use up to eight texture coordinate sets for any vertex, but the device can blend using only the specified number of texture coordinate sets.)
 							8;
 
-		caps.TextureOpCaps =	D3DTEXOPCAPS_ADD |							// The D3DTOP_ADD texture-blending operation is supported. 
-								D3DTEXOPCAPS_ADDSIGNED |					// The D3DTOP_ADDSIGNED texture-blending operation is supported. 
-								D3DTEXOPCAPS_ADDSIGNED2X |					// The D3DTOP_ADDSIGNED2X texture-blending operation is supported. 
-								D3DTEXOPCAPS_ADDSMOOTH |					// The D3DTOP_ADDSMOOTH texture-blending operation is supported. 
-								D3DTEXOPCAPS_BLENDCURRENTALPHA |			// The D3DTOP_BLENDCURRENTALPHA texture-blending operation is supported. 
-								D3DTEXOPCAPS_BLENDDIFFUSEALPHA |			// The D3DTOP_BLENDDIFFUSEALPHA texture-blending operation is supported. 
-								D3DTEXOPCAPS_BLENDFACTORALPHA |				// The D3DTOP_BLENDFACTORALPHA texture-blending operation is supported. 
-								D3DTEXOPCAPS_BLENDTEXTUREALPHA |			// The D3DTOP_BLENDTEXTUREALPHA texture-blending operation is supported. 
-								D3DTEXOPCAPS_BLENDTEXTUREALPHAPM |			// The D3DTOP_BLENDTEXTUREALPHAPM texture-blending operation is supported. 
-								D3DTEXOPCAPS_BUMPENVMAP |					// The D3DTOP_BUMPENVMAP texture-blending operation is supported. 
-								D3DTEXOPCAPS_BUMPENVMAPLUMINANCE |			// The D3DTOP_BUMPENVMAPLUMINANCE texture-blending operation is supported. 
-								D3DTEXOPCAPS_DISABLE |						// The D3DTOP_DISABLE texture-blending operation is supported. 
-								D3DTEXOPCAPS_DOTPRODUCT3 |					// The D3DTOP_DOTPRODUCT3 texture-blending operation is supported. 
-								D3DTEXOPCAPS_LERP |							// The D3DTOP_LERP texture-blending operation is supported. 
-								D3DTEXOPCAPS_MODULATE |						// The D3DTOP_MODULATE texture-blending operation is supported. 
-								D3DTEXOPCAPS_MODULATE2X |					// The D3DTOP_MODULATE2X texture-blending operation is supported. 
-								D3DTEXOPCAPS_MODULATE4X |					// The D3DTOP_MODULATE4X texture-blending operation is supported. 
-								D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |		// The D3DTOP_MODULATEALPHA_ADDCOLOR texture-blending operation is supported. 
-								D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |		// The D3DTOP_MODULATECOLOR_ADDALPHA texture-blending operation is supported. 
-								D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |	// The D3DTOP_MODULATEINVALPHA_ADDCOLOR texture-blending operation is supported. 
-								D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |	// The D3DTOP_MODULATEINVCOLOR_ADDALPHA texture-blending operation is supported. 
-								D3DTEXOPCAPS_MULTIPLYADD |					// The D3DTOP_MULTIPLYADD texture-blending operation is supported. 
-								D3DTEXOPCAPS_PREMODULATE |					// The D3DTOP_PREMODULATE texture-blending operation is supported. 
-								D3DTEXOPCAPS_SELECTARG1 |					// The D3DTOP_SELECTARG1 texture-blending operation is supported. 
-								D3DTEXOPCAPS_SELECTARG2 |					// The D3DTOP_SELECTARG2 texture-blending operation is supported. 
-								D3DTEXOPCAPS_SUBTRACT;						// The D3DTOP_SUBTRACT texture-blending operation is supported. 
+		caps.TextureOpCaps =	D3DTEXOPCAPS_ADD |							// The D3DTOP_ADD texture-blending operation is supported.
+								D3DTEXOPCAPS_ADDSIGNED |					// The D3DTOP_ADDSIGNED texture-blending operation is supported.
+								D3DTEXOPCAPS_ADDSIGNED2X |					// The D3DTOP_ADDSIGNED2X texture-blending operation is supported.
+								D3DTEXOPCAPS_ADDSMOOTH |					// The D3DTOP_ADDSMOOTH texture-blending operation is supported.
+								D3DTEXOPCAPS_BLENDCURRENTALPHA |			// The D3DTOP_BLENDCURRENTALPHA texture-blending operation is supported.
+								D3DTEXOPCAPS_BLENDDIFFUSEALPHA |			// The D3DTOP_BLENDDIFFUSEALPHA texture-blending operation is supported.
+								D3DTEXOPCAPS_BLENDFACTORALPHA |				// The D3DTOP_BLENDFACTORALPHA texture-blending operation is supported.
+								D3DTEXOPCAPS_BLENDTEXTUREALPHA |			// The D3DTOP_BLENDTEXTUREALPHA texture-blending operation is supported.
+								D3DTEXOPCAPS_BLENDTEXTUREALPHAPM |			// The D3DTOP_BLENDTEXTUREALPHAPM texture-blending operation is supported.
+								D3DTEXOPCAPS_BUMPENVMAP |					// The D3DTOP_BUMPENVMAP texture-blending operation is supported.
+								D3DTEXOPCAPS_BUMPENVMAPLUMINANCE |			// The D3DTOP_BUMPENVMAPLUMINANCE texture-blending operation is supported.
+								D3DTEXOPCAPS_DISABLE |						// The D3DTOP_DISABLE texture-blending operation is supported.
+								D3DTEXOPCAPS_DOTPRODUCT3 |					// The D3DTOP_DOTPRODUCT3 texture-blending operation is supported.
+								D3DTEXOPCAPS_LERP |							// The D3DTOP_LERP texture-blending operation is supported.
+								D3DTEXOPCAPS_MODULATE |						// The D3DTOP_MODULATE texture-blending operation is supported.
+								D3DTEXOPCAPS_MODULATE2X |					// The D3DTOP_MODULATE2X texture-blending operation is supported.
+								D3DTEXOPCAPS_MODULATE4X |					// The D3DTOP_MODULATE4X texture-blending operation is supported.
+								D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |		// The D3DTOP_MODULATEALPHA_ADDCOLOR texture-blending operation is supported.
+								D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |		// The D3DTOP_MODULATECOLOR_ADDALPHA texture-blending operation is supported.
+								D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |	// The D3DTOP_MODULATEINVALPHA_ADDCOLOR texture-blending operation is supported.
+								D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |	// The D3DTOP_MODULATEINVCOLOR_ADDALPHA texture-blending operation is supported.
+								D3DTEXOPCAPS_MULTIPLYADD |					// The D3DTOP_MULTIPLYADD texture-blending operation is supported.
+								D3DTEXOPCAPS_PREMODULATE |					// The D3DTOP_PREMODULATE texture-blending operation is supported.
+								D3DTEXOPCAPS_SELECTARG1 |					// The D3DTOP_SELECTARG1 texture-blending operation is supported.
+								D3DTEXOPCAPS_SELECTARG2 |					// The D3DTOP_SELECTARG2 texture-blending operation is supported.
+								D3DTEXOPCAPS_SUBTRACT;						// The D3DTOP_SUBTRACT texture-blending operation is supported.
 
 		caps.MaxTextureBlendStages = 8;
 		caps.MaxSimultaneousTextures = 8;
 
-		caps.VertexProcessingCaps =		D3DVTXPCAPS_DIRECTIONALLIGHTS |			// Device can do directional lights. 
-										D3DVTXPCAPS_LOCALVIEWER |				// Device can do local viewer. 
-										D3DVTXPCAPS_MATERIALSOURCE7	|			// Device can do Microsoft® DirectX® 7.0 colormaterialsource operations. 
-									//	D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER |	// Device does not support texture generation in non-local viewer mode. 
-										D3DVTXPCAPS_POSITIONALLIGHTS |			// Device can do positional lights (includes point and spot). 
-										D3DVTXPCAPS_TEXGEN |					// Device can do texgen. 
-										D3DVTXPCAPS_TEXGEN_SPHEREMAP;			// Device supports D3DTSS_TCI_SPHEREMAP. 
-									//	D3DVTXPCAPS_TWEENING;					// Device can do vertex tweening. 
+		caps.VertexProcessingCaps =		D3DVTXPCAPS_DIRECTIONALLIGHTS |			// Device can do directional lights.
+										D3DVTXPCAPS_LOCALVIEWER |				// Device can do local viewer.
+										D3DVTXPCAPS_MATERIALSOURCE7	|			// Device can do Microsoft® DirectX® 7.0 colormaterialsource operations.
+									//	D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER |	// Device does not support texture generation in non-local viewer mode.
+										D3DVTXPCAPS_POSITIONALLIGHTS |			// Device can do positional lights (includes point and spot).
+										D3DVTXPCAPS_TEXGEN |					// Device can do texgen.
+										D3DVTXPCAPS_TEXGEN_SPHEREMAP;			// Device supports D3DTSS_TCI_SPHEREMAP.
+									//	D3DVTXPCAPS_TWEENING;					// Device can do vertex tweening.
 
 		caps.MaxActiveLights = 8;						// Maximum number of lights that can be active simultaneously. For a given physical device, this capability might vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
-		caps.MaxUserClipPlanes = 6;						// Maximum number of user-defined clipping planes supported. This member can range from 0 through D3DMAXUSERCLIPPLANES. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice. 
-		caps.MaxVertexBlendMatrices = 4;				// Maximum number of matrices that this device can apply when performing multimatrix vertex blending. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice. 
+		caps.MaxUserClipPlanes = 6;						// Maximum number of user-defined clipping planes supported. This member can range from 0 through D3DMAXUSERCLIPPLANES. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
+		caps.MaxVertexBlendMatrices = 4;				// Maximum number of matrices that this device can apply when performing multimatrix vertex blending. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
 		caps.MaxVertexBlendMatrixIndex = 11;			// DWORD value that specifies the maximum matrix index that can be indexed into using the per-vertex indices. The number of matrices is MaxVertexBlendMatrixIndex + 1, which is the size of the matrix palette. If normals are present in the vertex data that needs to be blended for lighting, then the number of matrices is half the number specified by this capability flag. If MaxVertexBlendMatrixIndex is set to zero, the driver does not support indexed vertex blending. If this value is not zero then the valid range of indices is zero through MaxVertexBlendMatrixIndex.
 		caps.MaxPointSize = 8192.0f;					// Maximum size of a point primitive. If set to 1.0f then device does not support point size control. The range is greater than or equal to 1.0f.
 		caps.MaxPrimitiveCount = 1 << 21;				// Maximum number of primitives for each IDirect3DDevice9::DrawPrimitive call. Note that when Direct3D is working with a DirectX 6.0 or DirectX 7.0 driver, this field is set to 0xFFFF. This means that not only the number of primitives but also the number of vertices is limited by this value.
@@ -1519,66 +1522,66 @@
 		caps.MaxVertexShaderConst = 256;				// The number of vertex shader Registers that are reserved for constants.
 		caps.PixelShaderVersion = pixelShaderVersion;	// Two numbers that represent the pixel shader main and sub versions. For more information about the instructions supported for each pixel shader version, see Version 1_x, Version 2_0, Version 2_0 Extended, or Version 3_0.
 		caps.PixelShader1xMaxValue = 8.0;				// Maximum value of pixel shader arithmetic component. This value indicates the internal range of values supported for pixel color blending operations. Within the range that they report to, implementations must allow data to pass through pixel processing unmodified (unclamped). Normally, the value of this member is an absolute value. For example, a 1.0 indicates that the range is -1.0 to 1, and an 8.0 indicates that the range is -8.0 to 8.0. The value must be >= 1.0 for any hardware that supports pixel shaders.
-		
-		caps.DevCaps2 = //	D3DDEVCAPS2_ADAPTIVETESSRTPATCH |				// Device supports adaptive tessellation of RT-patches 
-						//	D3DDEVCAPS2_ADAPTIVETESSNPATCH |				// Device supports adaptive tessellation of N-patches. 
-							D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES |		// Device supports IDirect3DDevice9::StretchRect using a texture as the source. 
-						//	D3DDEVCAPS2_DMAPNPATCH |						// Device supports displacement maps for N-patches. 
-						//	D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH |				// Device supports presampled displacement maps for N-patches. For more information about displacement mapping, see Displacement Mapping. 
-							D3DDEVCAPS2_STREAMOFFSET |						// Device supports stream offsets. 
-							D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;	// Multiple vertex elements can share the same offset in a stream if D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET is set by the device and the vertex declaration does not have an element with D3DDECLUSAGE_POSITIONT0. 
+
+		caps.DevCaps2 = //	D3DDEVCAPS2_ADAPTIVETESSRTPATCH |				// Device supports adaptive tessellation of RT-patches
+						//	D3DDEVCAPS2_ADAPTIVETESSNPATCH |				// Device supports adaptive tessellation of N-patches.
+							D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES |		// Device supports IDirect3DDevice9::StretchRect using a texture as the source.
+						//	D3DDEVCAPS2_DMAPNPATCH |						// Device supports displacement maps for N-patches.
+						//	D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH |				// Device supports presampled displacement maps for N-patches. For more information about displacement mapping, see Displacement Mapping.
+							D3DDEVCAPS2_STREAMOFFSET |						// Device supports stream offsets.
+							D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;	// Multiple vertex elements can share the same offset in a stream if D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET is set by the device and the vertex declaration does not have an element with D3DDECLUSAGE_POSITIONT0.
 
 		caps.MaxNpatchTessellationLevel = 0;	// Maximum number of N-patch subdivision levels. The driver will clamp applications to this value, if they are using presampled displacement mapping. See Tessellation and Displacement Mapping.
 		caps.MasterAdapterOrdinal = 0;			// This number indicates which device is the master for this subordinate. This number is taken from the same space as the adapter values passed to the IDirect3D9 methods.
 		caps.AdapterOrdinalInGroup = 0;			// This number indicates the order in which heads are referenced by the application programming interface (API). The master adapter always has AdapterOrdinalInGroup = 0. These values do not correspond to the adapter ordinals passed to the IDirect3D9 methods. They apply only to heads within a group.
 		caps.NumberOfAdaptersInGroup = 1;		// Number of adapters in this adapter group (only if master). This will be 1 for conventional adapters. The value will be greater than 1 for the master adapter of a multihead card. The value will be 0 for a subordinate adapter of a multihead card. Each card can have at most one master, but may have many subordinates.
 
-		caps.DeclTypes =	D3DDTCAPS_UBYTE4 |		// 4-D unsigned byte. 
-							D3DDTCAPS_UBYTE4N |		// Normalized, 4-D unsigned byte. Each of the four bytes is normalized by dividing to 255.0. 
-							D3DDTCAPS_SHORT2N |		// Normalized, 2-D signed short, expanded to (first byte/32767.0, second byte/32767.0, 0, 1). 
-							D3DDTCAPS_SHORT4N |		// Normalized, 4-D signed short, expanded to (first byte/32767.0, second byte/32767.0, third byte/32767.0, fourth byte/32767.0). 
-							D3DDTCAPS_USHORT2N |	// Normalized, 2-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, 0, 1).  
-							D3DDTCAPS_USHORT4N |	// Normalized 4-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, third byte/65535.0, fourth byte/65535.0).  
-							D3DDTCAPS_UDEC3 |		// 3-D unsigned 10 10 10 format expanded to (value, value, value, 1). 
-							D3DDTCAPS_DEC3N |		// 3-D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1). 
-							D3DDTCAPS_FLOAT16_2 |	// 2-D 16-bit floating point numbers. 
-							D3DDTCAPS_FLOAT16_4;	// 4-D 16-bit floating point numbers. 
+		caps.DeclTypes =	D3DDTCAPS_UBYTE4 |		// 4-D unsigned byte.
+							D3DDTCAPS_UBYTE4N |		// Normalized, 4-D unsigned byte. Each of the four bytes is normalized by dividing to 255.0.
+							D3DDTCAPS_SHORT2N |		// Normalized, 2-D signed short, expanded to (first byte/32767.0, second byte/32767.0, 0, 1).
+							D3DDTCAPS_SHORT4N |		// Normalized, 4-D signed short, expanded to (first byte/32767.0, second byte/32767.0, third byte/32767.0, fourth byte/32767.0).
+							D3DDTCAPS_USHORT2N |	// Normalized, 2-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, 0, 1).
+							D3DDTCAPS_USHORT4N |	// Normalized 4-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, third byte/65535.0, fourth byte/65535.0).
+							D3DDTCAPS_UDEC3 |		// 3-D unsigned 10 10 10 format expanded to (value, value, value, 1).
+							D3DDTCAPS_DEC3N |		// 3-D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1).
+							D3DDTCAPS_FLOAT16_2 |	// 2-D 16-bit floating point numbers.
+							D3DDTCAPS_FLOAT16_4;	// 4-D 16-bit floating point numbers.
 
 		caps.NumSimultaneousRTs = 4;	// Number of simultaneous render targets. This number must be at least one.
 
-		caps.StretchRectFilterCaps = 	D3DPTFILTERCAPS_MINFPOINT |		// Device supports point-sample filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT. 
-										D3DPTFILTERCAPS_MAGFPOINT |		// Device supports point-sample filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT. 
-										D3DPTFILTERCAPS_MINFLINEAR |	// Device supports bilinear interpolation filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR. 
-										D3DPTFILTERCAPS_MAGFLINEAR;		// Device supports bilinear interpolation filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR. 
+		caps.StretchRectFilterCaps = 	D3DPTFILTERCAPS_MINFPOINT |		// Device supports point-sample filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT.
+										D3DPTFILTERCAPS_MAGFPOINT |		// Device supports point-sample filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT.
+										D3DPTFILTERCAPS_MINFLINEAR |	// Device supports bilinear interpolation filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR.
+										D3DPTFILTERCAPS_MAGFLINEAR;		// Device supports bilinear interpolation filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR.
 
-		caps.VS20Caps.Caps = vertexShaderPredication;									// Instruction predication is supported. See setp_comp. 
+		caps.VS20Caps.Caps = vertexShaderPredication;									// Instruction predication is supported. See setp_comp.
 		caps.VS20Caps.DynamicFlowControlDepth = vertexShaderDynamicFlowControlDepth;	// The maximum level of nesting of dynamic flow control instructions (break, breakc, ifc).
 		caps.VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;									// The maximum number of temporary registers supported.
 		caps.VS20Caps.StaticFlowControlDepth = D3DVS20_MAX_STATICFLOWCONTROLDEPTH;		// The maximum depth of nesting of the loop/rep and call/callnz bool instructions.
 
-		caps.PS20Caps.Caps =	pixelShaderArbitrarySwizzle |						// Arbitrary swizzling is supported. 
-								pixelShaderGradientInstructions |					// Gradient instructions are supported. 
-								pixelShaderPredication |							// Instruction predication is supported. See setp_comp - ps. 
-								pixelShaderNoDependentReadLimit |					// There is no limit on the number of dependent reads per instruction. 
-								pixelShaderNoTexInstructionLimit;					// There is no limit on the number of tex instructions. 
+		caps.PS20Caps.Caps =	pixelShaderArbitrarySwizzle |						// Arbitrary swizzling is supported.
+								pixelShaderGradientInstructions |					// Gradient instructions are supported.
+								pixelShaderPredication |							// Instruction predication is supported. See setp_comp - ps.
+								pixelShaderNoDependentReadLimit |					// There is no limit on the number of dependent reads per instruction.
+								pixelShaderNoTexInstructionLimit;					// There is no limit on the number of tex instructions.
 
 		caps.PS20Caps.DynamicFlowControlDepth = pixelShaderDynamicFlowControlDepth;		// The maximum level of nesting of dynamic flow control instructions (break, breakc, ifc).
 		caps.PS20Caps.NumInstructionSlots = D3DPS20_MAX_NUMINSTRUCTIONSLOTS;			// The driver will support at most this many instructions.
 		caps.PS20Caps.NumTemps = D3DPS20_MAX_NUMTEMPS;									// The driver will support at most this many temporary register.
 		caps.PS20Caps.StaticFlowControlDepth = pixelShaderStaticFlowControlDepth;		// The maximum depth of nesting of the loop/rep and call/callnz bool instructions.
 
-		caps.VertexTextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures. 
-											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures. 
-										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures. 
-											D3DPTFILTERCAPS_MIPFPOINT;			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type. 
-										//	D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type. 
+		caps.VertexTextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
+											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
+										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
+											D3DPTFILTERCAPS_MIPFPOINT;			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+										//	D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
 
 		caps.MaxVShaderInstructionsExecuted = maximumVertexShaderInstructionsExecuted;	// Maximum number of vertex shader instructions that can be run.
 		caps.MaxPShaderInstructionsExecuted = maximumPixelShaderInstructionsExecuted;	// Maximum number of pixel shader instructions that can be run.
diff --git a/src/D3D9/Direct3D9.hpp b/src/D3D9/Direct3D9.hpp
index b38ed82..f1543cc 100644
--- a/src/D3D9/Direct3D9.hpp
+++ b/src/D3D9/Direct3D9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3D9_hpp
 #define D3D9_Direct3D9_hpp
diff --git a/src/D3D9/Direct3D9Ex.cpp b/src/D3D9/Direct3D9Ex.cpp
index a1fe0a2..e9c4c56 100644
--- a/src/D3D9/Direct3D9Ex.cpp
+++ b/src/D3D9/Direct3D9Ex.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3D9Ex.hpp"
 
diff --git a/src/D3D9/Direct3D9Ex.hpp b/src/D3D9/Direct3D9Ex.hpp
index 9e1e319..a6589cf 100644
--- a/src/D3D9/Direct3D9Ex.hpp
+++ b/src/D3D9/Direct3D9Ex.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3D9Ex_hpp
 #define D3D9_Direct3D9Ex_hpp
diff --git a/src/D3D9/Direct3DBaseTexture9.cpp b/src/D3D9/Direct3DBaseTexture9.cpp
index 0ab979b..d765d9d 100644
--- a/src/D3D9/Direct3DBaseTexture9.cpp
+++ b/src/D3D9/Direct3DBaseTexture9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DBaseTexture9.hpp"
 
@@ -31,7 +34,7 @@
 	{
 		resource->destruct();
 	}
-	
+
 	long Direct3DBaseTexture9::QueryInterface(const IID &iid, void **object)
 	{
 		CriticalSection cs(device);
diff --git a/src/D3D9/Direct3DBaseTexture9.hpp b/src/D3D9/Direct3DBaseTexture9.hpp
index ed785fe..52d0df7 100644
--- a/src/D3D9/Direct3DBaseTexture9.hpp
+++ b/src/D3D9/Direct3DBaseTexture9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DBaseTexture9_hpp
 #define D3D9_Direct3DBaseTexture9_hpp
diff --git a/src/D3D9/Direct3DCubeTexture9.cpp b/src/D3D9/Direct3DCubeTexture9.cpp
index 7907788..cfe1ed7 100644
--- a/src/D3D9/Direct3DCubeTexture9.cpp
+++ b/src/D3D9/Direct3DCubeTexture9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DCubeTexture9.hpp"
 
diff --git a/src/D3D9/Direct3DCubeTexture9.hpp b/src/D3D9/Direct3DCubeTexture9.hpp
index a86bb0d..b92bc74 100644
--- a/src/D3D9/Direct3DCubeTexture9.hpp
+++ b/src/D3D9/Direct3DCubeTexture9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DCubeTexture9_hpp
 #define D3D9_Direct3DCubeTexture9_hpp
diff --git a/src/D3D9/Direct3DDevice9.cpp b/src/D3D9/Direct3DDevice9.cpp
index 299ec85..60f9173 100644
--- a/src/D3D9/Direct3DDevice9.cpp
+++ b/src/D3D9/Direct3DDevice9.cpp
@@ -1,6404 +1,6407 @@
-// 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 "Direct3DDevice9.hpp"

-

-#include "Direct3D9.hpp"

-#include "Direct3DSurface9.hpp"

-#include "Direct3DIndexBuffer9.hpp"

-#include "Direct3DVertexBuffer9.hpp"

-#include "Direct3DTexture9.hpp"

-#include "Direct3DVolumeTexture9.hpp"

-#include "Direct3DCubeTexture9.hpp"

-#include "Direct3DVertexDeclaration9.hpp"

-#include "Direct3DSwapChain9.hpp"

-#include "Direct3DPixelShader9.hpp"

-#include "Direct3DVertexShader9.hpp"

-#include "Direct3DStateBlock9.hpp"

-#include "Direct3DQuery9.hpp"

-#include "Direct3DVolume9.hpp"

-

-#include "Debug.hpp"

-#include "Capabilities.hpp"

-#include "Math.hpp"

-#include "Renderer.hpp"

-#include "Config.hpp"

-#include "FrameBuffer.hpp"

-#include "Clipper.hpp"

-#include "Configurator.hpp"

-#include "Timer.hpp"

-#include "Resource.hpp"

-

-#include <assert.h>

-

-bool localShaderConstants = true;

-

-namespace D3D9

-{

-	inline unsigned long FtoDW(float f)

-	{

-		return (unsigned long&)f;

-	}

-

-	Direct3DDevice9::Direct3DDevice9(const HINSTANCE instance, Direct3D9 *d3d9, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters) : instance(instance), adapter(adapter), d3d9(d3d9), deviceType(deviceType), focusWindow(focusWindow), behaviourFlags(behaviourFlags)

-	{

-		InitializeCriticalSection(&criticalSection);

-

-		init = true;

-		stateRecorder = 0;

-

-		d3d9->AddRef();

-

-		context = new sw::Context();

-		renderer = new sw::Renderer(context, sw::Direct3D, false);

-

-		swapChain = 0;

-		depthStencil = 0;

-		autoDepthStencil = 0;

-		renderTarget[0] = 0;

-		renderTarget[1] = 0;

-		renderTarget[2] = 0;

-		renderTarget[3] = 0;

-

-		for(int i = 0; i < 16 + 4; i++)

-		{

-			texture[i] = 0;

-		}

-

-		cursor = 0;

-

-		Reset(presentParameters);

-

-		pixelShader = 0;

-		vertexShader = 0;

-

-		lightsDirty = true;

-		pixelShaderDirty = true;

-		pixelShaderConstantsBDirty = 0;

-		pixelShaderConstantsFDirty = 0;

-		pixelShaderConstantsIDirty = 0;

-		vertexShaderDirty = true;

-		vertexShaderConstantsBDirty = 0;

-		vertexShaderConstantsFDirty = 0;

-		vertexShaderConstantsIDirty = 0;

-

-		for(int i = 0; i < 16; i++)

-		{

-			dataStream[i] = 0;

-			streamStride[i] = 0;

-			streamOffset[i] = 0;

-

-			streamSourceFreq[i] = 1;

-		}

-

-		indexData = 0;

-		vertexDeclaration = 0;

-

-		D3DMATERIAL9 material;

-

-		material.Diffuse.r = 1.0f;

-		material.Diffuse.g = 1.0f;

-		material.Diffuse.b = 1.0f;

-		material.Diffuse.a = 0.0f;

-		material.Ambient.r = 0.0f;

-		material.Ambient.g = 0.0f;

-		material.Ambient.b = 0.0f;

-		material.Ambient.a = 0.0f;

-		material.Emissive.r = 0.0f;

-		material.Emissive.g = 0.0f;

-		material.Emissive.b = 0.0f;

-		material.Emissive.a = 0.0f;

-		material.Specular.r = 0.0f;

-		material.Specular.g = 0.0f;

-		material.Specular.b = 0.0f;

-		material.Specular.a = 0.0f;

-		material.Power = 0.0f;

-

-		SetMaterial(&material);

-

-		D3DMATRIX identity = {1, 0, 0, 0,

-		                      0, 1, 0, 0,

-		                      0, 0, 1, 0,

-		                      0, 0, 0, 1};

-

-		SetTransform(D3DTS_VIEW, &identity);

-		SetTransform(D3DTS_PROJECTION, &identity);

-		SetTransform(D3DTS_TEXTURE0, &identity);

-		SetTransform(D3DTS_TEXTURE1, &identity);

-		SetTransform(D3DTS_TEXTURE2, &identity);

-		SetTransform(D3DTS_TEXTURE3, &identity);

-		SetTransform(D3DTS_TEXTURE4, &identity);

-		SetTransform(D3DTS_TEXTURE5, &identity);

-		SetTransform(D3DTS_TEXTURE6, &identity);

-		SetTransform(D3DTS_TEXTURE7, &identity);

-

-		for(int i = 0; i < 12; i++)

-		{

-			SetTransform(D3DTS_WORLDMATRIX(i), &identity);

-		}

-

-		for(int i = 0; i < MAX_PIXEL_SHADER_CONST; i++)

-		{

-			float zero[4] = {0, 0, 0, 0};

-

-			SetPixelShaderConstantF(i, zero, 1);

-		}

-

-		for(int i = 0; i < MAX_VERTEX_SHADER_CONST; i++)

-		{

-			float zero[4] = {0, 0, 0, 0};

-

-			SetVertexShaderConstantF(i, zero, 1);

-		}

-

-		for(int i = 0; i < 16; i++)

-		{

-			int zero[4] = {0, 0, 0, 0};

-

-			SetPixelShaderConstantI(i, zero, 1);

-			SetVertexShaderConstantI(i, zero, 1);

-			SetPixelShaderConstantB(i, &zero[0], 1);

-			SetVertexShaderConstantB(i, &zero[0], 1);

-		}

-

-		init = false;

-

-		if(!(behaviourFlags & D3DCREATE_FPU_PRESERVE))

-		{

-			configureFPU();

-		}

-

-		instancingEnabled = pixelShaderVersionX >= D3DPS_VERSION(3, 0);

-	}

-

-	Direct3DDevice9::~Direct3DDevice9()

-	{

-		delete renderer;

-		renderer = 0;

-		delete context;

-		context = 0;

-

-		d3d9->Release();

-		d3d9 = 0;

-

-		swapChain->unbind();

-		swapChain = 0;

-

-		if(depthStencil)

-		{

-			depthStencil->unbind();

-			depthStencil = 0;

-		}

-

-		if(autoDepthStencil)

-		{

-			autoDepthStencil->unbind();

-			autoDepthStencil = 0;

-		}

-

-		for(int index = 0; index < 4; index++)

-		{

-			if(renderTarget[index])

-			{

-				renderTarget[index]->unbind();

-				renderTarget[index] = 0;

-			}

-		}

-

-		if(vertexDeclaration)

-		{

-			vertexDeclaration->unbind();

-			vertexDeclaration = 0;

-		}

-

-		for(int i = 0; i < 16 + 4; i++)

-		{

-			if(texture[i])

-			{

-				texture[i]->unbind();

-				texture[i] = 0;

-			}

-		}

-

-		for(int i = 0; i < 16; i++)

-		{

-			if(dataStream[i])

-			{

-				dataStream[i]->unbind();

-				dataStream[i] = 0;

-			}

-		}

-

-		if(indexData)

-		{

-			indexData->unbind();

-			indexData = 0;

-		}

-

-		if(pixelShader)

-		{

-			pixelShader->unbind();

-			pixelShader = 0;

-		}

-

-		if(vertexShader)

-		{

-			vertexShader->unbind();

-			vertexShader = 0;

-		}

-

-		if(stateRecorder)

-		{

-			stateRecorder->unbind();

-			stateRecorder = 0;

-		}

-

-		palette.clear();

-

-		delete cursor;

-

-		DeleteCriticalSection(&criticalSection);

-	}

-

-	long Direct3DDevice9::QueryInterface(const IID &iid, void **object)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);

-

-		if(iid == IID_IDirect3DDevice9 ||

-		   iid == IID_IUnknown)

-		{

-			AddRef();

-			*object = this;

-

-			return S_OK;

-		}

-

-		*object = 0;

-

-		return NOINTERFACE(iid);

-	}

-

-	unsigned long Direct3DDevice9::AddRef()

-	{

-		TRACE("void");

-

-		return Unknown::AddRef();

-	}

-

-	unsigned long Direct3DDevice9::Release()

-	{

-		TRACE("void");

-

-		return Unknown::Release();

-	}

-

-	long Direct3DDevice9::BeginScene()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::BeginStateBlock()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		if(stateRecorder)

-		{

-			return INVALIDCALL();

-		}

-

-		stateRecorder = new Direct3DStateBlock9(this, (D3DSTATEBLOCKTYPE)0);

-

-		if(!stateRecorder)

-		{

-			return OUTOFMEMORY();

-		}

-

-		stateRecorder->bind();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long count = %d, const D3DRECT *rects = 0x%0.8p, unsigned long flags = 0x%0.8X, unsigned long color = 0x%0.8X, float z = %f, unsigned long stencil = %d", count, rects, flags, color, z, stencil);

-

-		if(rects == 0 && count != 0)

-		{

-			return INVALIDCALL();

-		}

-

-		if(flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) && !depthStencil)

-		{

-			return INVALIDCALL();

-		}

-

-		if(flags & D3DCLEAR_STENCIL)   // Check for stencil component

-		{

-			D3DSURFACE_DESC description;

-			depthStencil->GetDesc(&description);

-

-			switch(description.Format)

-			{

-			case D3DFMT_D15S1:

-			case D3DFMT_D24S8:

-			case D3DFMT_D24X8:

-			case D3DFMT_D24X4S4:

-			case D3DFMT_D24FS8:

-			case D3DFMT_S8_LOCKABLE:   // FIXME: INVALIDCALL when trying to clear depth?

-			case D3DFMT_DF24:

-			case D3DFMT_DF16:

-			case D3DFMT_INTZ:

-				break;

-			case D3DFMT_D16_LOCKABLE:

-			case D3DFMT_D32:

-			case D3DFMT_D16:

-			case D3DFMT_D32F_LOCKABLE:

-			case D3DFMT_D32_LOCKABLE:

-				return INVALIDCALL();

-			default:

-				ASSERT(false);

-			}

-		}

-

-		if(!rects)

-		{

-			count = 1;

-

-			D3DRECT rect;

-			rect.x1 = viewport.X;

-			rect.x2 = viewport.X + viewport.Width;

-			rect.y1 = viewport.Y;

-			rect.y2 = viewport.Y + viewport.Height;

-

-			rects = &rect;

-		}

-

-		for(unsigned int i = 0; i < count; i++)

-		{

-			sw::SliceRect clearRect(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2, 0);

-

-			clearRect.clip(viewport.X, viewport.Y, viewport.X + viewport.Width, viewport.Y + viewport.Height);

-

-			if(scissorEnable)

-			{

-				clearRect.clip(scissorRect.left, scissorRect.top, scissorRect.right, scissorRect.bottom);

-			}

-

-			if(flags & D3DCLEAR_TARGET)

-			{

-				for(int index = 0; index < 4; index++)

-				{

-					if(renderTarget[index])

-					{

-						D3DSURFACE_DESC description;

-						renderTarget[index]->GetDesc(&description);

-

-						float rgba[4];

-						rgba[0] = (float)(color & 0x00FF0000) / 0x00FF0000;

-						rgba[1] = (float)(color & 0x0000FF00) / 0x0000FF00;

-						rgba[2] = (float)(color & 0x000000FF) / 0x000000FF;

-						rgba[3] = (float)(color & 0xFF000000) / 0xFF000000;

-

-						if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format))

-						{

-							rgba[0] = sw::linearToSRGB(rgba[0]);

-							rgba[1] = sw::linearToSRGB(rgba[1]);

-							rgba[2] = sw::linearToSRGB(rgba[2]);

-						}

-

-						renderer->clear(rgba, sw::FORMAT_A32B32G32R32F, renderTarget[index], clearRect, 0xF);

-					}

-				}

-			}

-

-			if(flags & D3DCLEAR_ZBUFFER)

-			{

-				z = sw::clamp01(z);

-				depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-			}

-

-			if(flags & D3DCLEAR_STENCIL)

-			{

-				depthStencil->clearStencil(stencil, 0xFF, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-			}

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DSurface9 *surface = 0x%0.8p, const RECT *rect = 0x%0.8p, D3DCOLOR color = 0x%0.8X", surface, rect, color);

-

-		if(!surface)

-		{

-			return INVALIDCALL();

-		}

-

-		D3DSURFACE_DESC description;

-

-		surface->GetDesc(&description);

-

-		if(description.Pool != D3DPOOL_DEFAULT)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!rect)

-		{

-			RECT lock;

-

-			lock.left = 0;

-			lock.top = 0;

-			lock.right = description.Width;

-			lock.bottom = description.Height;

-

-			rect = &lock;

-		}

-

-		static_cast<Direct3DSurface9*>(surface)->fill(color, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DSwapChain9 **swapChain = 0x%0.8p", presentParameters, swapChain);

-

-		if(!swapChain)

-		{

-			return INVALIDCALL();

-		}

-

-		*swapChain = 0;

-

-		if(!presentParameters)

-		{

-			return INVALIDCALL();

-		}

-

-		if(presentParameters->BackBufferCount > 3)

-		{

-			return INVALIDCALL();   // Maximum of three back buffers

-		}

-

-		*swapChain = new Direct3DSwapChain9(this, presentParameters);

-

-		if(!*swapChain)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *swapChain;

-			*swapChain = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*swapChain)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int edgeLength = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DCubeTexture9 **cubeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", edgeLength, levels, usage, format, pool, cubeTexture, sharedHandle);

-

-		*cubeTexture = 0;

-

-		if(edgeLength == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_CUBETEXTURE, format) != D3D_OK)

-		{

-			return INVALIDCALL();

-		}

-

-		*cubeTexture = new Direct3DCubeTexture9(this, edgeLength, levels, usage, format, pool);

-

-		if(!*cubeTexture)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *cubeTexture;

-			*cubeTexture = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*cubeTexture)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int discard = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, discard, surface, sharedHandle);

-

-		*surface = 0;

-

-		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)

-		{

-			return INVALIDCALL();

-		}

-

-		bool lockable = false;

-

-		switch(format)

-		{

-		case D3DFMT_D15S1:

-		case D3DFMT_D24S8:

-		case D3DFMT_D24X8:

-		case D3DFMT_D24X4S4:

-		case D3DFMT_D24FS8:

-		case D3DFMT_D32:

-		case D3DFMT_D16:

-		case D3DFMT_DF24:

-		case D3DFMT_DF16:

-		case D3DFMT_INTZ:

-			lockable = false;

-			break;

-		case D3DFMT_S8_LOCKABLE:

-		case D3DFMT_D16_LOCKABLE:

-		case D3DFMT_D32F_LOCKABLE:

-		case D3DFMT_D32_LOCKABLE:

-			lockable = true;

-			break;

-		default:

-			ASSERT(false);

-		}

-

-		*surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);

-

-		if(!*surface)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *surface;

-			*surface = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*surface)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int length = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DIndexBuffer9 **indexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, format, pool, indexBuffer, sharedHandle);

-

-		*indexBuffer = new Direct3DIndexBuffer9(this, length, usage, format, pool);

-

-		if(!*indexBuffer)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *indexBuffer;

-			*indexBuffer = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*indexBuffer)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, pool, surface, sharedHandle);

-

-		*surface = 0;

-

-		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, format) != D3D_OK)   // FIXME: Allow all formats supported by runtime/REF

-		{

-			return INVALIDCALL();

-		}

-

-		if(pool == D3DPOOL_MANAGED)

-		{

-			return INVALIDCALL();

-		}

-

-		*surface = new Direct3DSurface9(this, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, true, 0);

-

-		if(!*surface)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *surface;

-			*surface = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*surface)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const unsigned long *function = 0x%0.8p, IDirect3DPixelShader9 **shader = 0x%0.8p", function, shader);

-

-		if(!shader)

-		{

-			return INVALIDCALL();

-		}

-

-		*shader = 0;

-

-		if(!sw::PixelShader::validate(function) || function[0] > pixelShaderVersionX)

-		{

-			return INVALIDCALL();   // Shader contains unsupported operations

-		}

-

-		*shader = new Direct3DPixelShader9(this, function);

-

-		if(!*shader)

-		{

-			return OUTOFMEMORY();

-		}

-

-		(*shader)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DQUERYTYPE type = %d, IDirect3DQuery9 **query = 0x%0.8p", type, query);

-

-		if(query == 0)   // Support checked

-		{

-			switch(type)

-			{

-			case D3DQUERYTYPE_VCACHE:				return D3D_OK;

-			case D3DQUERYTYPE_RESOURCEMANAGER:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_VERTEXSTATS:			return NOTAVAILABLE();

-			case D3DQUERYTYPE_EVENT:				return D3D_OK;

-			case D3DQUERYTYPE_OCCLUSION:			return D3D_OK;

-			case D3DQUERYTYPE_TIMESTAMP:			return D3D_OK;

-			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	return D3D_OK;

-			case D3DQUERYTYPE_TIMESTAMPFREQ:		return D3D_OK;

-			case D3DQUERYTYPE_PIPELINETIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_INTERFACETIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_VERTEXTIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_PIXELTIMINGS:			return NOTAVAILABLE();

-			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_CACHEUTILIZATION:		return NOTAVAILABLE();

-			default:								ASSERT(false);   return NOTAVAILABLE();

-			}

-		}

-		else

-		{

-			switch(type)

-			{

-			case D3DQUERYTYPE_VCACHE:				break;

-			case D3DQUERYTYPE_RESOURCEMANAGER:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_VERTEXSTATS:			return NOTAVAILABLE();

-			case D3DQUERYTYPE_EVENT:				break;

-			case D3DQUERYTYPE_OCCLUSION:			break;

-			case D3DQUERYTYPE_TIMESTAMP:			break;

-			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	break;

-			case D3DQUERYTYPE_TIMESTAMPFREQ:		break;

-			case D3DQUERYTYPE_PIPELINETIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_INTERFACETIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_VERTEXTIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_PIXELTIMINGS:			return NOTAVAILABLE();

-			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return NOTAVAILABLE();

-			case D3DQUERYTYPE_CACHEUTILIZATION:		return NOTAVAILABLE();

-			default:								ASSERT(false);   return NOTAVAILABLE();

-			}

-

-			*query = new Direct3DQuery9(this, type);

-

-			if(!*query)

-			{

-				return OUTOFMEMORY();

-			}

-

-			(*query)->AddRef();

-

-			return D3D_OK;

-		}

-	}

-

-	long Direct3DDevice9::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int lockable = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, lockable, surface, sharedHandle);

-

-		*surface = 0;

-

-		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)

-		{

-			return INVALIDCALL();

-		}

-

-		*surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable != FALSE, D3DUSAGE_RENDERTARGET);

-

-		if(!*surface)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *surface;

-			*surface = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*surface)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DSTATEBLOCKTYPE type = %d, IDirect3DStateBlock9 **stateBlock = 0x%0.8p", type, stateBlock);

-

-		*stateBlock = new Direct3DStateBlock9(this, type);

-

-		if(!*stateBlock)

-		{

-			return OUTOFMEMORY();

-		}

-

-		(*stateBlock)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DTexture9 **texture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, levels, usage, format, pool, texture, sharedHandle);

-

-		*texture = 0;

-

-		if(width == 0 || height == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, format) != D3D_OK)

-		{

-			return INVALIDCALL();

-		}

-

-		*texture = new Direct3DTexture9(this, width, height, levels, usage, format, pool);

-

-		if(!*texture)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *texture;

-			*texture = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*texture)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int length = %d, unsigned long usage = %d, unsigned long FVF = 0x%0.8X, D3DPOOL pool = %d, IDirect3DVertexBuffer9 **vertexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, FVF, pool, vertexBuffer, sharedHandle);

-

-		*vertexBuffer = new Direct3DVertexBuffer9(this, length, usage, FVF, pool);

-

-		if(!*vertexBuffer)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *vertexBuffer;

-			*vertexBuffer = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*vertexBuffer)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const D3DVERTEXELEMENT9 *vertexElements = 0x%0.8p, IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", vertexElements, declaration);

-

-		if(!declaration)

-		{

-			return INVALIDCALL();

-		}

-

-		const D3DVERTEXELEMENT9 *element = vertexElements;

-

-		while(element->Stream != 0xFF)

-		{

-			if(element->Type > D3DDECLTYPE_UNUSED)   // FIXME: Check other fields too

-			{

-				return FAIL();

-			}

-

-			element++;

-		}

-

-		*declaration = new Direct3DVertexDeclaration9(this, vertexElements);

-

-		if(!*declaration)

-		{

-			return OUTOFMEMORY();

-		}

-

-		(*declaration)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const unsigned long *function = 0x%0.8p, IDirect3DVertexShader9 **shader = 0x%0.8p", function, shader);

-

-		if(!shader)

-		{

-			return INVALIDCALL();

-		}

-

-		*shader = 0;

-

-		if(!sw::VertexShader::validate(function) || function[0] > vertexShaderVersionX)

-		{

-			return INVALIDCALL();   // Shader contains unsupported operations

-		}

-

-		*shader = new Direct3DVertexShader9(this, function);

-

-		if(!*shader)

-		{

-			return OUTOFMEMORY();

-		}

-

-		(*shader)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int depth = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DVolumeTexture9 **volumeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, depth, levels, usage, format, pool, volumeTexture, sharedHandle);

-

-		*volumeTexture = 0;

-

-		if(width == 0 || height == 0 || depth == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_VOLUMETEXTURE, format) != D3D_OK)

-		{

-			return INVALIDCALL();

-		}

-

-		*volumeTexture = new Direct3DVolumeTexture9(this, width, height, depth, levels, usage, format, pool);

-

-		if(!*volumeTexture)

-		{

-			return OUTOFMEMORY();

-		}

-

-		if(GetAvailableTextureMem() == 0)

-		{

-			delete *volumeTexture;

-			*volumeTexture = 0;

-

-			return OUTOFVIDEOMEMORY();

-		}

-

-		(*volumeTexture)->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::DeletePatch(unsigned int handle)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int handle = %d", handle);

-

-		UNIMPLEMENTED();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DPRIMITIVETYPE type = %d, int baseVertexIndex = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int startIndex = %d, unsigned int primitiveCount = %d", type, baseVertexIndex, minIndex, numVertices, startIndex, primitiveCount);

-

-		if(!indexData)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!bindResources(indexData) || !primitiveCount)

-		{

-			return D3D_OK;

-		}

-

-		unsigned int indexOffset = startIndex * (indexData->is32Bit() ? 4 : 2);   // FIXME: Doesn't take stream frequencies into account

-

-		sw::DrawType drawType;

-

-		if(indexData->is32Bit())

-		{

-			switch(type)

-			{

-			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;

-			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;

-			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;

-			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;

-			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;

-			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;   break;

-			default:

-				ASSERT(false);

-			}

-		}

-		else

-		{

-			switch(type)

-			{

-			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;

-			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;

-			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;

-			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;

-			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;

-			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;

-			default:

-				ASSERT(false);

-			}

-		}

-

-		if((streamSourceFreq[0] & D3DSTREAMSOURCE_INDEXEDDATA) && instanceData())

-		{

-			int instanceCount = (streamSourceFreq[0] & ~D3DSTREAMSOURCE_INDEXEDDATA);

-

-			for(int instance = 0; instance < instanceCount; instance++)

-			{

-				bindVertexStreams(baseVertexIndex, true, instance);

-				renderer->draw(drawType, indexOffset, primitiveCount, instance == 0);

-			}

-		}

-		else

-		{

-			bindVertexStreams(baseVertexIndex, false, 0);

-			renderer->draw(drawType, indexOffset, primitiveCount);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int primitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DPRIMITIVETYPE type = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int primitiveCount = %d, const void *indexData = 0x%0.8p, D3DFORMAT indexDataFormat = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", type, minIndex, numVertices, primitiveCount, indexData, indexDataFormat, vertexStreamZeroData, vertexStreamZeroStride);

-

-		if(!vertexStreamZeroData || !indexData)

-		{

-			return INVALIDCALL();

-		}

-

-		int length = (minIndex + numVertices) * vertexStreamZeroStride;

-

-		Direct3DVertexBuffer9 *vertexBuffer = new Direct3DVertexBuffer9(this, length, 0, 0, D3DPOOL_DEFAULT);

-

-		void *data;

-		vertexBuffer->Lock(0, 0, &data, 0);

-		memcpy(data, vertexStreamZeroData, length);

-		vertexBuffer->Unlock();

-

-		SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);

-

-		switch(type)

-		{

-		case D3DPT_POINTLIST:		length = primitiveCount;		break;

-		case D3DPT_LINELIST:		length = primitiveCount * 2;	break;

-		case D3DPT_LINESTRIP:		length = primitiveCount + 1;	break;

-		case D3DPT_TRIANGLELIST:	length = primitiveCount * 3;	break;

-		case D3DPT_TRIANGLESTRIP:	length = primitiveCount + 2;	break;

-		case D3DPT_TRIANGLEFAN:		length = primitiveCount + 2;	break;

-		default:

-			ASSERT(false);

-		}

-

-		length *= indexDataFormat == D3DFMT_INDEX32 ? 4 : 2;

-

-		Direct3DIndexBuffer9 *indexBuffer = new Direct3DIndexBuffer9(this, length, 0, indexDataFormat, D3DPOOL_DEFAULT);

-

-		indexBuffer->Lock(0, 0, &data, 0);

-		memcpy(data, indexData, length);

-		indexBuffer->Unlock();

-

-		SetIndices(indexBuffer);

-

-		if(!bindResources(indexBuffer) || !primitiveCount)

-		{

-			vertexBuffer->Release();

-

-			return D3D_OK;

-		}

-

-		sw::DrawType drawType;

-

-		if(indexDataFormat == D3DFMT_INDEX32)

-		{

-			switch(type)

-			{

-			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;

-			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;

-			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;

-			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;

-			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;

-			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;   break;

-			default:

-				ASSERT(false);

-			}

-		}

-		else

-		{

-			switch(type)

-			{

-			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;

-			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;

-			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;

-			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;

-			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;

-			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;

-			default:

-				ASSERT(false);

-			}

-		}

-

-		bindVertexStreams(0, false, 0);

-		renderer->draw(drawType, 0, primitiveCount);

-

-		SetStreamSource(0, 0, 0, 0);

-		SetIndices(0);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int startVertex = %d, unsigned int primitiveCount = %d", primitiveType, startVertex, primitiveCount);

-

-		if(!bindResources(0) || !primitiveCount)

-		{

-			return D3D_OK;

-		}

-

-		sw::DrawType drawType;

-

-		switch(primitiveType)

-		{

-		case D3DPT_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;

-		case D3DPT_LINELIST:      drawType = sw::DRAW_LINELIST;      break;

-		case D3DPT_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;

-		case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;

-		case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;

-		case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;

-		default:

-			ASSERT(false);

-		}

-

-		bindVertexStreams(startVertex, false, 0);

-		renderer->draw(drawType, 0, primitiveCount);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int primitiveCount = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", primitiveType, primitiveCount, vertexStreamZeroData, vertexStreamZeroStride);

-

-		if(!vertexStreamZeroData)

-		{

-			return INVALIDCALL();

-		}

-

-		IDirect3DVertexBuffer9 *vertexBuffer = 0;

-		int length = 0;

-

-		switch(primitiveType)

-		{

-		case D3DPT_POINTLIST:		length = primitiveCount;		break;

-		case D3DPT_LINELIST:		length = primitiveCount * 2;	break;

-		case D3DPT_LINESTRIP:		length = primitiveCount + 1;	break;

-		case D3DPT_TRIANGLELIST:	length = primitiveCount * 3;	break;

-		case D3DPT_TRIANGLESTRIP:	length = primitiveCount + 2;	break;

-		case D3DPT_TRIANGLEFAN:		length = primitiveCount + 2;	break;

-		default:

-			ASSERT(false);

-		}

-

-		length *= vertexStreamZeroStride;

-

-		CreateVertexBuffer(length, 0, 0, D3DPOOL_DEFAULT, &vertexBuffer, 0);

-

-		void *data;

-		vertexBuffer->Lock(0, 0, &data, 0);

-		memcpy(data, vertexStreamZeroData, length);

-		vertexBuffer->Unlock();

-

-		SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);

-

-		if(!bindResources(0) || !primitiveCount)

-		{

-			vertexBuffer->Release();

-

-			return D3D_OK;

-		}

-

-		sw::DrawType drawType;

-

-		switch(primitiveType)

-		{

-		case D3DPT_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;

-		case D3DPT_LINELIST:      drawType = sw::DRAW_LINELIST;      break;

-		case D3DPT_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;

-		case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;

-		case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;

-		case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;

-		default:

-			ASSERT(false);

-		}

-

-		bindVertexStreams(0, false, 0);

-		renderer->draw(drawType, 0, primitiveCount);

-

-		SetStreamSource(0, 0, 0, 0);

-		vertexBuffer->Release();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DRECTPATCH_INFO *rectPatchInfo = 0x%0.8p", handle, numSegs, rectPatchInfo);

-

-		if(!numSegs || !rectPatchInfo)

-		{

-			return INVALIDCALL();

-		}

-

-		UNIMPLEMENTED();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DTRIPATCH_INFO *triPatchInfo = 0x%0.8p", handle, numSegs, triPatchInfo);

-

-		if(!numSegs || !triPatchInfo)

-		{

-			return INVALIDCALL();

-		}

-

-		UNIMPLEMENTED();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::EndScene()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::EndStateBlock(IDirect3DStateBlock9 **stateBlock)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DStateBlock9 **stateBlock = 0x%0.8p", stateBlock);

-

-		if(!stateBlock)

-		{

-			return INVALIDCALL();

-		}

-

-		*stateBlock = 0;

-

-		if(!stateRecorder)

-		{

-			return INVALIDCALL();

-		}

-

-		*stateBlock = stateRecorder;

-		stateRecorder->AddRef();

-		stateRecorder->unbind();

-		stateRecorder = 0;   // Stop recording

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::EvictManagedResources()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		//	UNIMPLEMENTED();   // FIXME

-

-		return D3D_OK;

-	}

-

-	unsigned int Direct3DDevice9::GetAvailableTextureMem()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		int availableMemory = textureMemory - Direct3DResource9::getMemoryUsage();

-		if(availableMemory < 0) availableMemory = 0;

-

-		// Round to nearest MB

-		return (availableMemory + 0x80000) & 0xFFF00000;

-	}

-

-	long Direct3DDevice9::GetBackBuffer(unsigned int swapChainIndex, unsigned int backBufferIndex, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int swapChainIndex = %d, unsigned int backBufferIndex = %d, D3DBACKBUFFER_TYPE type = %d, IDirect3DSurface9 **backBuffer = 0x%0.8p", swapChainIndex, backBufferIndex, type, backBuffer);

-

-		if(swapChainIndex >= GetNumberOfSwapChains())

-		{

-			return INVALIDCALL();

-		}

-

-		return swapChain->GetBackBuffer(backBufferIndex, type, backBuffer);

-	}

-

-	long Direct3DDevice9::GetClipPlane(unsigned long index, float *plane)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, float *plane = 0x%0.8p", index, plane);

-

-		if(!plane || index >= 6)

-		{

-			return INVALIDCALL();

-		}

-

-		plane[0] = this->plane[index][0];

-		plane[1] = this->plane[index][1];

-		plane[2] = this->plane[index][2];

-		plane[3] = this->plane[index][3];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetClipStatus(D3DCLIPSTATUS9 *clipStatus)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);

-

-		if(!clipStatus)

-		{

-			return INVALIDCALL();

-		}

-

-		*clipStatus = this->clipStatus;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DDEVICE_CREATION_PARAMETERS *parameters = 0x%0.8p", parameters);

-

-		if(!parameters)

-		{

-			return INVALIDCALL();

-		}

-

-		parameters->AdapterOrdinal = adapter;

-		parameters->BehaviorFlags = behaviourFlags;

-		parameters->DeviceType = deviceType;

-		parameters->hFocusWindow = focusWindow;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetCurrentTexturePalette(unsigned int *paletteNumber)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int *paletteNumber = 0x%0.8p", paletteNumber);

-

-		if(!paletteNumber)

-		{

-			return INVALIDCALL();

-		}

-

-		*paletteNumber = currentPalette;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DSurface9 **depthStencilSurface = 0x%0.8p", depthStencilSurface);

-

-		if(!depthStencilSurface)

-		{

-			return INVALIDCALL();

-		}

-

-		*depthStencilSurface = depthStencil;

-

-		if(depthStencil)

-		{

-			depthStencil->AddRef();

-		}

-		else

-		{

-			return NOTFOUND();

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetDeviceCaps(D3DCAPS9 *caps)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DCAPS9 *caps = 0x%0.8p", caps);

-

-		return d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps);

-	}

-

-	long Direct3DDevice9::GetDirect3D(IDirect3D9 **d3d9)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3D9 **d3d9 = 0x%0.8p", d3d9);

-

-		if(!d3d9)

-		{

-			return INVALIDCALL();

-		}

-

-		*d3d9 = this->d3d9;

-		this->d3d9->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetDisplayMode(unsigned int index, D3DDISPLAYMODE *mode)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", index, mode);

-

-		if(index >= GetNumberOfSwapChains())

-		{

-			return INVALIDCALL();

-		}

-

-		return swapChain->GetDisplayMode(mode);

-	}

-

-	long Direct3DDevice9::GetFrontBufferData(unsigned int index, IDirect3DSurface9 *destSurface)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int index = %d, IDirect3DSurface9 *destSurface = %p", index, destSurface);

-

-		if(index >= GetNumberOfSwapChains())

-		{

-			return INVALIDCALL();

-		}

-

-		return swapChain->GetFrontBufferData(destSurface);

-	}

-

-	long Direct3DDevice9::GetFVF(unsigned long *FVF)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long *FVF = 0x%0.8p", FVF);

-

-		if(!FVF)

-		{

-			return INVALIDCALL();

-		}

-

-		if(vertexDeclaration)

-		{

-			*FVF = vertexDeclaration->getFVF();

-		}

-		else

-		{

-			*FVF = 0;

-		}

-

-		return D3D_OK;

-	}

-

-	void Direct3DDevice9::GetGammaRamp(unsigned int index, D3DGAMMARAMP *ramp)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int index = %d, D3DGAMMARAMP *ramp = 0x%0.8p", index, ramp);

-

-		if(!ramp || index >= GetNumberOfSwapChains())

-		{

-			return;

-		}

-

-		swapChain->getGammaRamp((sw::GammaRamp*)ramp);

-	}

-

-	long Direct3DDevice9::GetIndices(IDirect3DIndexBuffer9 **indexData)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DIndexBuffer9 **indexData = 0x%0.8p", indexData);

-

-		if(!indexData)

-		{

-			return INVALIDCALL();

-		}

-

-		*indexData = this->indexData;

-

-		if(this->indexData)

-		{

-			this->indexData->AddRef();

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetLight(unsigned long index, D3DLIGHT9 *light)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, D3DLIGHT9 *light = 0x%0.8p", index, light);

-

-		if(!light)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!this->light.exists(index))

-		{

-			return INVALIDCALL();

-		}

-

-		*light = this->light[index];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetLightEnable(unsigned long index, int *enable)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, int *enable = 0x%0.8p", index, enable);

-

-		if(!enable)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!light.exists(index))

-		{

-			return INVALIDCALL();

-		}

-

-		*enable = light[index].enable ? 128 : 0;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetMaterial(D3DMATERIAL9 *material)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DMATERIAL9 *material = 0x%0.8p", material);

-

-		if(!material)

-		{

-			return INVALIDCALL();

-		}

-

-		*material = this->material;

-

-		return D3D_OK;

-	}

-

-	float Direct3DDevice9::GetNPatchMode()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		return 0.0f;   // FIXME: Unimplemented

-	}

-

-	unsigned int Direct3DDevice9::GetNumberOfSwapChains()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		return 1;

-	}

-

-	long Direct3DDevice9::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int paletteNumber = %d, PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);

-

-		if(paletteNumber > 0xFFFF || !entries)

-		{

-			return INVALIDCALL();

-		}

-

-		for(int i = 0; i < 256; i++)

-		{

-			entries[i] = palette[paletteNumber].entry[i];

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetPixelShader(IDirect3DPixelShader9 **shader)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DPixelShader9 **shader = 0x%0.8p", shader);

-

-		if(!shader)

-		{

-			return INVALIDCALL();

-		}

-

-		if(pixelShader)

-		{

-			pixelShader->AddRef();

-		}

-

-		*shader = pixelShader;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		for(unsigned int i = 0; i < count; i++)

-		{

-			constantData[i] = pixelShaderConstantB[startRegister + i];

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		for(unsigned int i = 0; i < count; i++)

-		{

-			constantData[i * 4 + 0] = pixelShaderConstantF[startRegister + i][0];

-			constantData[i * 4 + 1] = pixelShaderConstantF[startRegister + i][1];

-			constantData[i * 4 + 2] = pixelShaderConstantF[startRegister + i][2];

-			constantData[i * 4 + 3] = pixelShaderConstantF[startRegister + i][3];

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		for(unsigned int i = 0; i < count; i++)

-		{

-			constantData[i * 4 + 0] = pixelShaderConstantI[startRegister + i][0];

-			constantData[i * 4 + 1] = pixelShaderConstantI[startRegister + i][1];

-			constantData[i * 4 + 2] = pixelShaderConstantI[startRegister + i][2];

-			constantData[i * 4 + 3] = pixelShaderConstantI[startRegister + i][3];

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetRasterStatus(unsigned int index, D3DRASTER_STATUS *rasterStatus)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int swapChain = %d, D3DRASTER_STATUS *rasterStatus = 0x%0.8p", index, rasterStatus);

-

-		if(index >= GetNumberOfSwapChains())

-		{

-			return INVALIDCALL();

-		}

-

-		return swapChain->GetRasterStatus(rasterStatus);

-	}

-

-	long Direct3DDevice9::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DRENDERSTATETYPE state = %d, unsigned long *value = 0x%0.8p", state, value);

-

-		if(!value)

-		{

-			return INVALIDCALL();

-		}

-

-		*value = renderState[state];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, IDirect3DSurface9 **renderTarget = 0x%0.8p", index, renderTarget);

-

-		if(index >= 4 || !renderTarget)

-		{

-			return INVALIDCALL();

-		}

-

-		*renderTarget = 0;

-

-		if(!this->renderTarget[index])

-		{

-			return NOTFOUND();

-		}

-

-		*renderTarget = this->renderTarget[index];

-		this->renderTarget[index]->AddRef();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DSurface9 *renderTarget = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p", renderTarget, destSurface);

-

-		if(!renderTarget || !destSurface)

-		{

-			return INVALIDCALL();

-		}

-

-		D3DSURFACE_DESC sourceDescription;

-		D3DSURFACE_DESC destinationDescription;

-

-		renderTarget->GetDesc(&sourceDescription);

-		destSurface->GetDesc(&destinationDescription);

-

-		if(sourceDescription.Width  != destinationDescription.Width ||

-		   sourceDescription.Height != destinationDescription.Height ||

-		   sourceDescription.Format != destinationDescription.Format ||

-		   sourceDescription.MultiSampleType != D3DMULTISAMPLE_NONE)

-		{

-			return INVALIDCALL();

-		}

-

-		if(sourceDescription.Format == D3DFMT_A8R8G8B8 ||

-		   sourceDescription.Format == D3DFMT_X8R8G8B8)

-		{

-			sw::Surface *source = static_cast<Direct3DSurface9*>(renderTarget);

-			sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);

-

-			void *sourceBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-			void *destBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);

-

-			static void (__cdecl *blitFunction)(void *dst, void *src);

-			static sw::Routine *blitRoutine;

-			static sw::BlitState blitState = {0};

-

-			sw::BlitState update;

-			update.width = sourceDescription.Width;

-			update.height = sourceDescription.Height;

-			update.sourceFormat = sw::FORMAT_A8R8G8B8;

-			update.destFormat = sw::FORMAT_A8R8G8B8;

-			update.stride = dest->getExternalPitchB();

-			update.cursorHeight = 0;

-			update.cursorWidth = 0;

-

-			if(memcmp(&blitState, &update, sizeof(sw::BlitState)) != 0)

-			{

-				blitState = update;

-				delete blitRoutine;

-

-				blitRoutine = sw::FrameBuffer::copyRoutine(blitState);

-				blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();

-			}

-

-			blitFunction(destBuffer, sourceBuffer);

-

-			dest->unlockExternal();

-			source->unlockExternal();

-		}

-		else

-		{

-			return UpdateSurface(renderTarget, 0, destSurface, 0);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE type = %d, unsigned long *value = 0x%0.8p", sampler, state, value);

-

-		if(!value || state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)   // FIXME: Set *value to 0?

-		{

-			return INVALIDCALL();

-		}

-

-		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)

-		{

-			return INVALIDCALL();

-		}

-

-		if(sampler >= D3DVERTEXTEXTURESAMPLER0)

-		{

-			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);

-		}

-

-		*value = samplerState[sampler][state];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetScissorRect(RECT *rect)

-	{

-		CriticalSection cs(this);

-

-		TRACE("RECT *rect = 0x%0.8p", rect);

-

-		if(!rect)

-		{

-			return INVALIDCALL();

-		}

-

-		*rect = scissorRect;

-

-		return D3D_OK;

-	}

-

-	int Direct3DDevice9::GetSoftwareVertexProcessing()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		return softwareVertexProcessing ? TRUE : FALSE;

-	}

-

-	long Direct3DDevice9::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int streamNumber = %d, IDirect3DVertexBuffer9 **streamData = 0x%0.8p, unsigned int *offset = 0x%0.8p, unsigned int *stride = 0x%0.8p", streamNumber, streamData, offset, stride);

-

-		if(streamNumber >= 16 || !streamData || !offset || !stride)

-		{

-			return INVALIDCALL();

-		}

-

-		*streamData = dataStream[streamNumber];

-

-		if(dataStream[streamNumber])

-		{

-			dataStream[streamNumber]->AddRef();

-		}

-

-		*offset = streamOffset[streamNumber];

-		*stride = streamStride[streamNumber];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int streamNumber = %d, unsigned int *divider = 0x%0.8p", streamNumber, divider);

-

-		if(streamNumber >= 16 || !divider)

-		{

-			return INVALIDCALL();

-		}

-

-		*divider = streamSourceFreq[streamNumber];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int index = %d, IDirect3DSwapChain9 **swapChain = 0x%0.8p", index, swapChain);

-

-		if(!swapChain || index >= GetNumberOfSwapChains())

-		{

-			return INVALIDCALL();

-		}

-

-		*swapChain = this->swapChain;

-

-		if(*swapChain)

-		{

-			(*swapChain)->AddRef();

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 **texture = 0x%0.8p", sampler, texture);

-

-		if(!texture)

-		{

-			return INVALIDCALL();

-		}

-

-		*texture = 0;

-

-		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)

-		{

-			return INVALIDCALL();

-		}

-

-		*texture = this->texture[sampler];

-

-		if(this->texture[sampler])

-		{

-			this->texture[sampler]->AddRef();

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long *value = 0x%0.8p", stage, type, value);

-

-		if(!value)

-		{

-			return INVALIDCALL();

-		}

-

-		*value = textureStageState[stage][type];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DTRANSFORMSTATETYPE state = %d, D3DMATRIX *matrix = 0x%0.8p", state, matrix);

-

-		if(!matrix || state < 0 || state > 511)

-		{

-			return INVALIDCALL();

-		}

-

-		*matrix = this->matrix[state];

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", declaration);

-

-		if(!declaration)

-		{

-			return INVALIDCALL();

-		}

-

-		*declaration = vertexDeclaration;

-

-		if(vertexDeclaration)

-		{

-			vertexDeclaration->AddRef();

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetVertexShader(IDirect3DVertexShader9 **shader)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DVertexShader9 **shader = 0x%0.8p", shader);

-

-		if(!shader)

-		{

-			return INVALIDCALL();

-		}

-

-		*shader = vertexShader;

-

-		if(vertexShader)

-		{

-			vertexShader->AddRef();

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		for(unsigned int i = 0; i < count; i++)

-		{

-			constantData[i] = vertexShaderConstantB[startRegister + i];

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		for(unsigned int i = 0; i < count; i++)

-		{

-			constantData[i * 4 + 0] = vertexShaderConstantF[startRegister + i][0];

-			constantData[i * 4 + 1] = vertexShaderConstantF[startRegister + i][1];

-			constantData[i * 4 + 2] = vertexShaderConstantF[startRegister + i][2];

-			constantData[i * 4 + 3] = vertexShaderConstantF[startRegister + i][3];

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		for(unsigned int i = 0; i < count; i++)

-		{

-			constantData[i * 4 + 0] = vertexShaderConstantI[startRegister + i][0];

-			constantData[i * 4 + 1] = vertexShaderConstantI[startRegister + i][1];

-			constantData[i * 4 + 2] = vertexShaderConstantI[startRegister + i][2];

-			constantData[i * 4 + 3] = vertexShaderConstantI[startRegister + i][3];

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::GetViewport(D3DVIEWPORT9 *viewport)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);

-

-		if(!viewport)

-		{

-			return INVALIDCALL();

-		}

-

-		*viewport = this->viewport;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::LightEnable(unsigned long index, int enable)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, int enable = %d", index, enable);

-

-		if(!light.exists(index))   // Insert default light

-		{

-			D3DLIGHT9 light;

-

-			light.Type = D3DLIGHT_DIRECTIONAL;

-			light.Diffuse.r = 1;

-			light.Diffuse.g = 1;

-			light.Diffuse.b = 1;

-			light.Diffuse.a = 0;

-			light.Specular.r = 0;

-			light.Specular.g = 0;

-			light.Specular.b = 0;

-			light.Specular.a = 0;

-			light.Ambient.r = 0;

-			light.Ambient.g = 0;

-			light.Ambient.b = 0;

-			light.Ambient.a = 0;

-			light.Position.x = 0;

-			light.Position.y = 0;

-			light.Position.z = 0;

-			light.Direction.x = 0;

-			light.Direction.y = 0;

-			light.Direction.z = 1;

-			light.Range = 0;

-			light.Falloff = 0;

-			light.Attenuation0 = 0;

-			light.Attenuation1 = 0;

-			light.Attenuation2 = 0;

-			light.Theta = 0;

-			light.Phi = 0;

-

-			this->light[index] = light;

-			this->light[index].enable = false;

-		}

-

-		if(!stateRecorder)

-		{

-			light[index].enable = (enable != FALSE);

-

-			lightsDirty = true;

-		}

-		else

-		{

-			stateRecorder->lightEnable(index, enable);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);

-

-		if(!matrix)

-		{

-			return INVALIDCALL();

-		}

-

-		D3DMATRIX *current = &this->matrix[state];

-

-		sw::Matrix C(current->_11, current->_21, current->_31, current->_41,

-		             current->_12, current->_22, current->_32, current->_42,

-		             current->_13, current->_23, current->_33, current->_43,

-		             current->_14, current->_24, current->_34, current->_44);

-

-		sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,

-		             matrix->_12, matrix->_22, matrix->_32, matrix->_42,

-		             matrix->_13, matrix->_23, matrix->_33, matrix->_43,

-		             matrix->_14, matrix->_24, matrix->_34, matrix->_44);

-

-		switch(state)

-		{

-		case D3DTS_WORLD:

-			renderer->setModelMatrix(C * M);

-			break;

-		case D3DTS_VIEW:

-			renderer->setViewMatrix(C * M);

-			break;

-		case D3DTS_PROJECTION:

-			renderer->setProjectionMatrix(C * M);

-			break;

-		case D3DTS_TEXTURE0:

-			renderer->setTextureMatrix(0, C * M);

-			break;

-		case D3DTS_TEXTURE1:

-			renderer->setTextureMatrix(1, C * M);

-			break;

-		case D3DTS_TEXTURE2:

-			renderer->setTextureMatrix(2, C * M);

-			break;

-		case D3DTS_TEXTURE3:

-			renderer->setTextureMatrix(3, C * M);

-			break;

-		case D3DTS_TEXTURE4:

-			renderer->setTextureMatrix(4, C * M);

-			break;

-		case D3DTS_TEXTURE5:

-			renderer->setTextureMatrix(5, C * M);

-			break;

-		case D3DTS_TEXTURE6:

-			renderer->setTextureMatrix(6, C * M);

-			break;

-		case D3DTS_TEXTURE7:

-			renderer->setTextureMatrix(7, C * M);

-			break;

-		default:

-			if(state > 256 && state < 512)

-			{

-				renderer->setModelMatrix(C * M, state - 256);

-			}

-			else ASSERT(false);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const RECT *sourceRect = 0x%0.8p, const RECT *destRect = 0x%0.8p, HWND destWindowOverride = %d, const RGNDATA *dirtyRegion = 0x%0.8p", sourceRect, destRect, destWindowOverride, dirtyRegion);

-

-		return swapChain->Present(sourceRect, destRect, destWindowOverride, dirtyRegion, 0);

-	}

-

-	long Direct3DDevice9::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int srcStartIndex = %d, unsigned int destIndex = %d, unsigned int vertexCount = %d, IDirect3DVertexBuffer9 *destBuffer = 0x%0.8p, IDirect3DVertexDeclaration9 *vertexDeclaration = 0x%0.8p, unsigned long flags = %d", srcStartIndex, destIndex, vertexCount, destBuffer, vertexDeclaration, flags);

-

-		if(!destBuffer)

-		{

-			return INVALIDCALL();

-		}

-

-		UNIMPLEMENTED();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::Reset(D3DPRESENT_PARAMETERS *presentParameters)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p", presentParameters);

-

-		if(!presentParameters)

-		{

-			return INVALIDCALL();

-		}

-

-		deviceWindow = presentParameters->hDeviceWindow;

-

-		if(depthStencil)

-		{

-			depthStencil->unbind();

-			depthStencil = 0;

-		}

-

-		if(autoDepthStencil)

-		{

-			autoDepthStencil->unbind();

-			autoDepthStencil = 0;

-		}

-

-		for(int index = 0; index < 4; index++)

-		{

-			if(renderTarget[index])

-			{

-				renderTarget[index]->unbind();

-				renderTarget[index] = 0;

-			}

-		}

-

-		if(!swapChain)

-		{

-			swapChain = new Direct3DSwapChain9(this, presentParameters);

-			swapChain->bind();

-		}

-		else

-		{

-			swapChain->reset(presentParameters);

-		}

-

-		if(presentParameters->EnableAutoDepthStencil != FALSE)

-		{

-			bool lockable = false;

-

-			switch(presentParameters->AutoDepthStencilFormat)

-			{

-			case D3DFMT_D15S1:

-			case D3DFMT_D24S8:

-			case D3DFMT_D24X8:

-			case D3DFMT_D24X4S4:

-			case D3DFMT_D24FS8:

-			case D3DFMT_D32:

-			case D3DFMT_D16:

-			case D3DFMT_DF24:

-			case D3DFMT_DF16:

-			case D3DFMT_INTZ:

-				lockable = false;

-				break;

-			case D3DFMT_S8_LOCKABLE:

-			case D3DFMT_D16_LOCKABLE:

-			case D3DFMT_D32F_LOCKABLE:

-			case D3DFMT_D32_LOCKABLE:

-				lockable = true;

-				break;

-			default:

-				ASSERT(false);

-			}

-

-			autoDepthStencil = new Direct3DSurface9(this, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);

-			autoDepthStencil->bind();

-

-			SetDepthStencilSurface(autoDepthStencil);

-		}

-

-		IDirect3DSurface9 *renderTarget;

-		swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget);

-		SetRenderTarget(0, renderTarget);

-		renderTarget->Release();

-

-		SetRenderTarget(1, 0);

-		SetRenderTarget(2, 0);

-		SetRenderTarget(3, 0);

-

-		softwareVertexProcessing = (behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == D3DCREATE_SOFTWARE_VERTEXPROCESSING;

-

-		SetRenderState(D3DRS_ZENABLE, presentParameters->EnableAutoDepthStencil != FALSE ? D3DZB_TRUE : D3DZB_FALSE);

-		SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);

-		SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);

-		SetRenderState(D3DRS_ZWRITEENABLE, TRUE);

-		SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);

-		SetRenderState(D3DRS_LASTPIXEL, TRUE);

-		SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);

-		SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);

-		SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

-		SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);

-		SetRenderState(D3DRS_ALPHAREF, 0);

-		SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);

-		SetRenderState(D3DRS_DITHERENABLE, FALSE);

-		SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

-		SetRenderState(D3DRS_FOGENABLE, FALSE);

-		SetRenderState(D3DRS_SPECULARENABLE, FALSE);

-	//	SetRenderState(D3DRS_ZVISIBLE, 0);

-		SetRenderState(D3DRS_FOGCOLOR, 0);

-		SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);

-		SetRenderState(D3DRS_FOGSTART, FtoDW(0.0f));

-		SetRenderState(D3DRS_FOGEND, FtoDW(1.0f));

-		SetRenderState(D3DRS_FOGDENSITY, FtoDW(1.0f));

-		SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);

-		SetRenderState(D3DRS_STENCILENABLE, FALSE);

-		SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);

-		SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);

-		SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);

-		SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);

-		SetRenderState(D3DRS_STENCILREF, 0);

-		SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);

-		SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);

-		SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);

-		SetRenderState(D3DRS_WRAP0, 0);

-		SetRenderState(D3DRS_WRAP1, 0);

-		SetRenderState(D3DRS_WRAP2, 0);

-		SetRenderState(D3DRS_WRAP3, 0);

-		SetRenderState(D3DRS_WRAP4, 0);

-		SetRenderState(D3DRS_WRAP5, 0);

-		SetRenderState(D3DRS_WRAP6, 0);

-		SetRenderState(D3DRS_WRAP7, 0);

-		SetRenderState(D3DRS_CLIPPING, TRUE);

-		SetRenderState(D3DRS_LIGHTING, TRUE);

-		SetRenderState(D3DRS_AMBIENT, 0);

-		SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);

-		SetRenderState(D3DRS_COLORVERTEX, TRUE);

-		SetRenderState(D3DRS_LOCALVIEWER, TRUE);

-		SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);

-		SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);

-		SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);

-		SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

-		SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);

-		SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);

-		SetRenderState(D3DRS_CLIPPLANEENABLE, 0);

-		SetRenderState(D3DRS_POINTSIZE, FtoDW(1.0f));

-		SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(1.0f));

-		SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);

-		SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);

-		SetRenderState(D3DRS_POINTSCALE_A, FtoDW(1.0f));

-		SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));

-		SetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.0f));

-		SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);

-		SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);

-		SetRenderState(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);

-		SetRenderState(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE);

-		SetRenderState(D3DRS_POINTSIZE_MAX, FtoDW(64.0f));

-		SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);

-		SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F);

-		SetRenderState(D3DRS_TWEENFACTOR, FtoDW(0.0f));

-		SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);

-		SetRenderState(D3DRS_POSITIONDEGREE, D3DDEGREE_CUBIC);

-		SetRenderState(D3DRS_NORMALDEGREE, D3DDEGREE_LINEAR);

-		SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);

-		SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FtoDW(0.0f));

-		SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE);

-		SetRenderState(D3DRS_MINTESSELLATIONLEVEL, FtoDW(1.0f));

-		SetRenderState(D3DRS_MAXTESSELLATIONLEVEL, FtoDW(1.0f));

-		SetRenderState(D3DRS_ADAPTIVETESS_X, FtoDW(0.0f));

-		SetRenderState(D3DRS_ADAPTIVETESS_Y, FtoDW(0.0f));

-		SetRenderState(D3DRS_ADAPTIVETESS_Z, FtoDW(1.0f));

-		SetRenderState(D3DRS_ADAPTIVETESS_W, FtoDW(0.0f));

-		SetRenderState(D3DRS_ENABLEADAPTIVETESSELLATION, FALSE);

-		SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);

-		SetRenderState(D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP);

-		SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP);

-		SetRenderState(D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP);

-		SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS);

-		SetRenderState(D3DRS_COLORWRITEENABLE1, 0x0000000F);

-		SetRenderState(D3DRS_COLORWRITEENABLE2, 0x0000000F);

-		SetRenderState(D3DRS_COLORWRITEENABLE3, 0x0000000F);

-		SetRenderState(D3DRS_BLENDFACTOR, 0xFFFFFFFF);

-		SetRenderState(D3DRS_SRGBWRITEENABLE, 0);

-		SetRenderState(D3DRS_DEPTHBIAS, FtoDW(0.0f));

-		SetRenderState(D3DRS_WRAP8, 0);

-		SetRenderState(D3DRS_WRAP9, 0);

-		SetRenderState(D3DRS_WRAP10, 0);

-		SetRenderState(D3DRS_WRAP11, 0);

-		SetRenderState(D3DRS_WRAP12, 0);

-		SetRenderState(D3DRS_WRAP13, 0);

-		SetRenderState(D3DRS_WRAP14, 0);

-		SetRenderState(D3DRS_WRAP15, 0);

-		SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);

-		SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);

-		SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);

-		SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);

-

-		for(int i = 0; i < 8; i++)

-		{

-			SetTextureStageState(i, D3DTSS_COLOROP, i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE);

-			SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);

-			SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);

-			SetTextureStageState(i, D3DTSS_ALPHAOP, i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE);

-			SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);

-			SetTextureStageState(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);

-			SetTextureStageState(i, D3DTSS_BUMPENVMAT00, FtoDW(0.0f));

-			SetTextureStageState(i, D3DTSS_BUMPENVMAT01, FtoDW(0.0f));

-			SetTextureStageState(i, D3DTSS_BUMPENVMAT10, FtoDW(0.0f));

-			SetTextureStageState(i, D3DTSS_BUMPENVMAT11, FtoDW(0.0f));

-			SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i);

-			SetTextureStageState(i, D3DTSS_BUMPENVLSCALE, FtoDW(0.0f));

-			SetTextureStageState(i, D3DTSS_BUMPENVLOFFSET, FtoDW(0.0f));

-			SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);

-			SetTextureStageState(i, D3DTSS_COLORARG0, D3DTA_CURRENT);

-			SetTextureStageState(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT);

-			SetTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT);

-			SetTextureStageState(i, D3DTSS_CONSTANT, 0x00000000);

-		}

-

-		for(int i = 0; i <= D3DVERTEXTEXTURESAMPLER3; i = (i != 15) ? (i + 1) : D3DVERTEXTEXTURESAMPLER0)

-		{

-			SetTexture(i, 0);

-

-			SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);

-			SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

-			SetSamplerState(i, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);

-			SetSamplerState(i, D3DSAMP_BORDERCOLOR, 0x00000000);

-			SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);

-			SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_POINT);

-			SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

-			SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, 0);

-			SetSamplerState(i, D3DSAMP_MAXMIPLEVEL, 0);

-			SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 1);

-			SetSamplerState(i, D3DSAMP_SRGBTEXTURE, 0);

-			SetSamplerState(i, D3DSAMP_ELEMENTINDEX, 0);

-			SetSamplerState(i, D3DSAMP_DMAPOFFSET, 0);

-		}

-

-		for(int i = 0; i < 6; i++)

-		{

-			float plane[4] = {0, 0, 0, 0};

-

-			SetClipPlane(i, plane);

-		}

-

-		currentPalette = 0xFFFF;

-

-		ShowCursor(FALSE);

-		delete cursor;

-		cursor = 0;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetClipPlane(unsigned long index, const float *plane)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, const float *plane = 0x%0.8p", index, plane);

-

-		if(!plane || index >= 6)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			this->plane[index][0] = plane[0];

-			this->plane[index][1] = plane[1];

-			this->plane[index][2] = plane[2];

-			this->plane[index][3] = plane[3];

-

-			renderer->setClipPlane(index, plane);

-		}

-		else

-		{

-			stateRecorder->setClipPlane(index, plane);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetClipStatus(const D3DCLIPSTATUS9 *clipStatus)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);

-

-		if(!clipStatus)

-		{

-			return INVALIDCALL();

-		}

-

-		this->clipStatus = *clipStatus;

-

-		UNIMPLEMENTED();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetCurrentTexturePalette(unsigned int paletteNumber)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int paletteNumber = %d", paletteNumber);

-

-		if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end())

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			currentPalette = paletteNumber;

-

-			sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);

-		}

-		else

-		{

-			stateRecorder->setCurrentTexturePalette(paletteNumber);

-		}

-

-		return D3D_OK;

-	}

-

-	void Direct3DDevice9::SetCursorPosition(int x, int y, unsigned long flags)

-	{

-		CriticalSection cs(this);

-

-		TRACE("int x = %d, int y = %d, unsigned long flags = 0x%0.8X", x, y, flags);

-

-		POINT point = {x, y};

-		HWND window = deviceWindow ? deviceWindow : focusWindow;

-		ScreenToClient(window, &point);

-

-		sw::FrameBuffer::setCursorPosition(point.x, point.y);

-	}

-

-	long Direct3DDevice9::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface9 *cursorBitmap)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int x0 = %d, unsigned int y0 = %d, IDirect3DSurface9 *cursorBitmap = 0x%0.8p", x0, y0, cursorBitmap);

-

-		if(!cursorBitmap)

-		{

-			return INVALIDCALL();

-		}

-

-		sw::Surface *cursorSurface = static_cast<Direct3DSurface9*>(cursorBitmap);

-

-		int width = cursorSurface->getWidth();

-		int height = cursorSurface->getHeight();

-		void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-

-		delete cursor;

-		cursor = new sw::Surface(0, width, height, 1, sw::FORMAT_A8R8G8B8, false, false);

-

-		void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);

-		memcpy(buffer, bitmap, width * height * sizeof(unsigned int));

-		cursor->unlockExternal();

-

-		cursorSurface->unlockExternal();

-

-		if(showCursor)

-		{

-			sw::FrameBuffer::setCursorImage(cursor);

-		}

-		else

-		{

-			sw::FrameBuffer::setCursorImage(0);

-		}

-

-		sw::FrameBuffer::setCursorOrigin(x0, y0);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *iDepthStencil)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DSurface9 *newDepthStencil = 0x%0.8p", iDepthStencil);

-

-		Direct3DSurface9 *depthStencil = static_cast<Direct3DSurface9*>(iDepthStencil);

-

-		if(this->depthStencil == depthStencil)

-		{

-			return D3D_OK;

-		}

-

-		if(depthStencil)

-		{

-			depthStencil->bind();

-		}

-

-		if(this->depthStencil)

-		{

-			this->depthStencil->unbind();

-		}

-

-		this->depthStencil = depthStencil;

-

-		renderer->setDepthBuffer(depthStencil);

-		renderer->setStencilBuffer(depthStencil);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetDialogBoxMode(int enableDialogs)

-	{

-		CriticalSection cs(this);

-

-		TRACE("int enableDialogs = %d", enableDialogs);

-

-		UNIMPLEMENTED();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetFVF(unsigned long FVF)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long FVF = 0x%0.8X", FVF);

-

-		if(!stateRecorder)

-		{

-			if(FVF != 0 || !this->vertexDeclaration)

-			{

-				Direct3DVertexDeclaration9 *vertexDeclaration = new Direct3DVertexDeclaration9(this, FVF);

-				vertexDeclaration->bind();

-

-				if(this->vertexDeclaration)

-				{

-					this->vertexDeclaration->unbind();

-				}

-

-				this->vertexDeclaration = vertexDeclaration;

-			}

-		}

-		else

-		{

-			stateRecorder->setFVF(FVF);

-		}

-

-		return D3D_OK;

-	}

-

-	void Direct3DDevice9::SetGammaRamp(unsigned int index, unsigned long flags, const D3DGAMMARAMP *ramp)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int index = %d, unsigned long flags = 0x%0.8X, const D3DGAMMARAMP *ramp = 0x%0.8p", index, flags, ramp);

-

-		if(!ramp || index >= GetNumberOfSwapChains())

-		{

-			return;

-		}

-

-		swapChain->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE);

-	}

-

-	long Direct3DDevice9::SetIndices(IDirect3DIndexBuffer9* iIndexBuffer)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DIndexBuffer9* indexData = 0x%0.8p", iIndexBuffer);

-

-		Direct3DIndexBuffer9 *indexBuffer = static_cast<Direct3DIndexBuffer9*>(iIndexBuffer);

-

-		if(!stateRecorder)

-		{

-			if(this->indexData == indexBuffer)

-			{

-				return D3D_OK;

-			}

-

-			if(indexBuffer)

-			{

-				indexBuffer->bind();

-			}

-

-			if(this->indexData)

-			{

-				this->indexData->unbind();

-			}

-

-			this->indexData = indexBuffer;

-		}

-		else

-		{

-			stateRecorder->setIndices(indexBuffer);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetLight(unsigned long index, const D3DLIGHT9 *light)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, const D3DLIGHT9 *light = 0x%0.8p", index, light);

-

-		if(!light)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			this->light[index] = *light;

-

-			lightsDirty = true;

-		}

-		else

-		{

-			stateRecorder->setLight(index, light);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetMaterial(const D3DMATERIAL9 *material)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const D3DMATERIAL9 *material = 0x%0.8p", material);

-

-		if(!material)

-		{

-			return INVALIDCALL();   // FIXME: Correct behaviour?

-		}

-

-		if(!stateRecorder)

-		{

-			this->material = *material;

-

-			renderer->setMaterialAmbient(sw::Color<float>(material->Ambient.r, material->Ambient.g, material->Ambient.b, material->Ambient.a));

-			renderer->setMaterialDiffuse(sw::Color<float>(material->Diffuse.r, material->Diffuse.g, material->Diffuse.b, material->Diffuse.a));

-			renderer->setMaterialEmission(sw::Color<float>(material->Emissive.r, material->Emissive.g, material->Emissive.b, material->Emissive.a));

-			renderer->setMaterialShininess(material->Power);

-			renderer->setMaterialSpecular(sw::Color<float>(material->Specular.r, material->Specular.g, material->Specular.b, material->Specular.a));

-		}

-		else

-		{

-			stateRecorder->setMaterial(material);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetNPatchMode(float segments)

-	{

-		CriticalSection cs(this);

-

-		TRACE("float segments = %f", segments);

-

-		if(!stateRecorder)

-		{

-			if(segments < 1)

-			{

-				// NOTE: Disable

-			}

-			else

-			{

-				UNIMPLEMENTED();

-			}

-		}

-		else

-		{

-			stateRecorder->setNPatchMode(segments);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int paletteNumber = %d, const PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);

-

-		if(paletteNumber > 0xFFFF || !entries)

-		{

-			return INVALIDCALL();

-		}

-

-		for(int i = 0; i < 256; i++)

-		{

-			palette[paletteNumber].entry[i] = entries[i];

-		}

-

-		if(paletteNumber == currentPalette)

-		{

-			sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetPixelShader(IDirect3DPixelShader9 *iPixelShader)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DPixelShader9 *shader = 0x%0.8p", iPixelShader);

-

-		Direct3DPixelShader9 *pixelShader = static_cast<Direct3DPixelShader9*>(iPixelShader);

-

-		if(!stateRecorder)

-		{

-			if(this->pixelShader == pixelShader)

-			{

-				return D3D_OK;

-			}

-

-			if(pixelShader)

-			{

-				pixelShader->bind();

-			}

-

-			if(this->pixelShader)

-			{

-				this->pixelShader->unbind();

-			}

-

-			this->pixelShader = pixelShader;

-			pixelShaderDirty = true;

-		}

-		else

-		{

-			stateRecorder->setPixelShader(pixelShader);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!stateRecorder)

-		{

-			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)

-			{

-				pixelShaderConstantB[startRegister + i] = constantData[i];

-			}

-

-			pixelShaderConstantsBDirty = sw::max(startRegister + count, pixelShaderConstantsBDirty);

-			pixelShaderDirty = true;   // Reload DEF constants

-		}

-		else

-		{

-			stateRecorder->setPixelShaderConstantB(startRegister, constantData, count);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!stateRecorder)

-		{

-			for(unsigned int i = 0; i < count && startRegister + i < MAX_PIXEL_SHADER_CONST; 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 = sw::max(startRegister + count, pixelShaderConstantsFDirty);

-			pixelShaderDirty = true;   // Reload DEF constants

-		}

-		else

-		{

-			stateRecorder->setPixelShaderConstantF(startRegister, constantData, count);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!stateRecorder)

-		{

-			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)

-			{

-				pixelShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];

-				pixelShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];

-				pixelShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];

-				pixelShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];

-			}

-

-			pixelShaderConstantsIDirty = sw::max(startRegister + count, pixelShaderConstantsIDirty);

-			pixelShaderDirty = true;   // Reload DEF constants

-		}

-		else

-		{

-			stateRecorder->setPixelShaderConstantI(startRegister, constantData, count);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);

-

-		if(state < D3DRS_ZENABLE || state > D3DRS_BLENDOPALPHA)

-		{

-			return D3D_OK;   // FIXME: Warning

-		}

-

-		if(!stateRecorder)

-		{

-			if(!init && renderState[state] == value)

-			{

-				return D3D_OK;

-			}

-

-			renderState[state] = value;

-

-			switch(state)

-			{

-			case D3DRS_ZENABLE:

-				switch(value)

-				{

-				case D3DZB_TRUE:

-				case D3DZB_USEW:

-					renderer->setDepthBufferEnable(true);

-					break;

-				case D3DZB_FALSE:

-					renderer->setDepthBufferEnable(false);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_FILLMODE:

-				switch(value)

-				{

-				case D3DFILL_POINT:

-					renderer->setFillMode(sw::FILL_VERTEX);

-					break;

-				case D3DFILL_WIREFRAME:

-					renderer->setFillMode(sw::FILL_WIREFRAME);

-					break;

-				case D3DFILL_SOLID:

-					renderer->setFillMode(sw::FILL_SOLID);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_SHADEMODE:

-				switch(value)

-				{

-				case D3DSHADE_FLAT:

-					renderer->setShadingMode(sw::SHADING_FLAT);

-					break;

-				case D3DSHADE_GOURAUD:

-					renderer->setShadingMode(sw::SHADING_GOURAUD);

-					break;

-				case D3DSHADE_PHONG:

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_ZWRITEENABLE:

-				renderer->setDepthWriteEnable(value != FALSE);

-				break;

-			case D3DRS_ALPHATESTENABLE:

-				renderer->setAlphaTestEnable(value != FALSE);

-				break;

-			case D3DRS_LASTPIXEL:

-			//	if(!init) UNIMPLEMENTED();   // FIXME

-				break;

-			case D3DRS_SRCBLEND:

-				switch(value)

-				{

-				case D3DBLEND_ZERO:

-					renderer->setSourceBlendFactor(sw::BLEND_ZERO);

-					break;

-				case D3DBLEND_ONE:

-					renderer->setSourceBlendFactor(sw::BLEND_ONE);

-					break;

-				case D3DBLEND_SRCCOLOR:

-					renderer->setSourceBlendFactor(sw::BLEND_SOURCE);

-					break;

-				case D3DBLEND_INVSRCCOLOR:

-					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCE);

-					break;

-				case D3DBLEND_SRCALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_INVSRCALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_DESTALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_DESTALPHA);

-					break;

-				case D3DBLEND_INVDESTALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_INVDESTALPHA);

-					break;

-				case D3DBLEND_DESTCOLOR:

-					renderer->setSourceBlendFactor(sw::BLEND_DEST);

-					break;

-				case D3DBLEND_INVDESTCOLOR:

-					renderer->setSourceBlendFactor(sw::BLEND_INVDEST);

-					break;

-				case D3DBLEND_SRCALPHASAT:

-					renderer->setSourceBlendFactor(sw::BLEND_SRCALPHASAT);

-					break;

-				case D3DBLEND_BOTHSRCALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);

-					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_BOTHINVSRCALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);

-					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_BLENDFACTOR:

-					renderer->setSourceBlendFactor(sw::BLEND_CONSTANT);

-					break;

-				case D3DBLEND_INVBLENDFACTOR:

-					renderer->setSourceBlendFactor(sw::BLEND_INVCONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_DESTBLEND:

-				switch(value)

-				{

-				case D3DBLEND_ZERO:

-					renderer->setDestBlendFactor(sw::BLEND_ZERO);

-					break;

-				case D3DBLEND_ONE:

-					renderer->setDestBlendFactor(sw::BLEND_ONE);

-					break;

-				case D3DBLEND_SRCCOLOR:

-					renderer->setDestBlendFactor(sw::BLEND_SOURCE);

-					break;

-				case D3DBLEND_INVSRCCOLOR:

-					renderer->setDestBlendFactor(sw::BLEND_INVSOURCE);

-					break;

-				case D3DBLEND_SRCALPHA:

-					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_INVSRCALPHA:

-					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_DESTALPHA:

-					renderer->setDestBlendFactor(sw::BLEND_DESTALPHA);

-					break;

-				case D3DBLEND_INVDESTALPHA:

-					renderer->setDestBlendFactor(sw::BLEND_INVDESTALPHA);

-					break;

-				case D3DBLEND_DESTCOLOR:

-					renderer->setDestBlendFactor(sw::BLEND_DEST);

-					break;

-				case D3DBLEND_INVDESTCOLOR:

-					renderer->setDestBlendFactor(sw::BLEND_INVDEST);

-					break;

-				case D3DBLEND_SRCALPHASAT:

-					renderer->setDestBlendFactor(sw::BLEND_SRCALPHASAT);

-					break;

-				case D3DBLEND_BOTHSRCALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);

-					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_BOTHINVSRCALPHA:

-					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);

-					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_BLENDFACTOR:

-					renderer->setDestBlendFactor(sw::BLEND_CONSTANT);

-					break;

-				case D3DBLEND_INVBLENDFACTOR:

-					renderer->setDestBlendFactor(sw::BLEND_INVCONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_CULLMODE:

-				switch(value)

-				{

-				case D3DCULL_NONE:

-					renderer->setCullMode(sw::CULL_NONE);

-					break;

-				case D3DCULL_CCW:

-					renderer->setCullMode(sw::CULL_COUNTERCLOCKWISE);

-					break;

-				case D3DCULL_CW:

-					renderer->setCullMode(sw::CULL_CLOCKWISE);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_ZFUNC:

-				switch(value)

-				{

-				case D3DCMP_NEVER:

-					renderer->setDepthCompare(sw::DEPTH_NEVER);

-					break;

-				case D3DCMP_LESS:

-					renderer->setDepthCompare(sw::DEPTH_LESS);

-					break;

-				case D3DCMP_EQUAL:

-					renderer->setDepthCompare(sw::DEPTH_EQUAL);

-					break;

-				case D3DCMP_LESSEQUAL:

-					renderer->setDepthCompare(sw::DEPTH_LESSEQUAL);

-					break;

-				case D3DCMP_GREATER:

-					renderer->setDepthCompare(sw::DEPTH_GREATER);

-					break;

-				case D3DCMP_NOTEQUAL:

-					renderer->setDepthCompare(sw::DEPTH_NOTEQUAL);

-					break;

-				case D3DCMP_GREATEREQUAL:

-					renderer->setDepthCompare(sw::DEPTH_GREATEREQUAL);

-					break;

-				case D3DCMP_ALWAYS:

-					renderer->setDepthCompare(sw::DEPTH_ALWAYS);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_ALPHAREF:

-				renderer->setAlphaReference(value & 0x000000FF);

-				break;

-			case D3DRS_ALPHAFUNC:

-				switch(value)

-				{

-				case D3DCMP_NEVER:

-					renderer->setAlphaCompare(sw::ALPHA_NEVER);

-					break;

-				case D3DCMP_LESS:

-					renderer->setAlphaCompare(sw::ALPHA_LESS);

-					break;

-				case D3DCMP_EQUAL:

-					renderer->setAlphaCompare(sw::ALPHA_EQUAL);

-					break;

-				case D3DCMP_LESSEQUAL:

-					renderer->setAlphaCompare(sw::ALPHA_LESSEQUAL);

-					break;

-				case D3DCMP_GREATER:

-					renderer->setAlphaCompare(sw::ALPHA_GREATER);

-					break;

-				case D3DCMP_NOTEQUAL:

-					renderer->setAlphaCompare(sw::ALPHA_NOTEQUAL);

-					break;

-				case D3DCMP_GREATEREQUAL:

-					renderer->setAlphaCompare(sw::ALPHA_GREATEREQUAL);

-					break;

-				case D3DCMP_ALWAYS:

-					renderer->setAlphaCompare(sw::ALPHA_ALWAYS);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_DITHERENABLE:

-			//	if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_ALPHABLENDENABLE:

-				renderer->setAlphaBlendEnable(value != FALSE);

-				break;

-			case D3DRS_FOGENABLE:

-				renderer->setFogEnable(value != FALSE);

-				break;

-			case D3DRS_FOGCOLOR:

-				renderer->setFogColor(value);

-				break;

-			case D3DRS_FOGTABLEMODE:

-				switch(value)

-				{

-				case D3DFOG_NONE:

-					renderer->setPixelFogMode(sw::FOG_NONE);

-					break;

-				case D3DFOG_LINEAR:

-					renderer->setPixelFogMode(sw::FOG_LINEAR);

-					break;

-				case D3DFOG_EXP:

-					renderer->setPixelFogMode(sw::FOG_EXP);

-					break;

-				case D3DFOG_EXP2:

-					renderer->setPixelFogMode(sw::FOG_EXP2);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_FOGSTART:

-				renderer->setFogStart((float&)value);

-				break;

-			case D3DRS_FOGEND:

-				renderer->setFogEnd((float&)value);

-				break;

-			case D3DRS_FOGDENSITY:

-				renderer->setFogDensity((float&)value);

-				break;

-			case D3DRS_RANGEFOGENABLE:

-				renderer->setRangeFogEnable(value != FALSE);

-				break;

-			case D3DRS_SPECULARENABLE:

-				renderer->setSpecularEnable(value != FALSE);

-				break;

-			case D3DRS_STENCILENABLE:

-				renderer->setStencilEnable(value != FALSE);

-				break;

-			case D3DRS_STENCILFAIL:

-				switch(value)

-				{

-				case D3DSTENCILOP_KEEP:

-					renderer->setStencilFailOperation(sw::OPERATION_KEEP);

-					break;

-				case D3DSTENCILOP_ZERO:

-					renderer->setStencilFailOperation(sw::OPERATION_ZERO);

-					break;

-				case D3DSTENCILOP_REPLACE:

-					renderer->setStencilFailOperation(sw::OPERATION_REPLACE);

-					break;

-				case D3DSTENCILOP_INCRSAT:

-					renderer->setStencilFailOperation(sw::OPERATION_INCRSAT);

-					break;

-				case D3DSTENCILOP_DECRSAT:

-					renderer->setStencilFailOperation(sw::OPERATION_DECRSAT);

-					break;

-				case D3DSTENCILOP_INVERT:

-					renderer->setStencilFailOperation(sw::OPERATION_INVERT);

-					break;

-				case D3DSTENCILOP_INCR:

-					renderer->setStencilFailOperation(sw::OPERATION_INCR);

-					break;

-				case D3DSTENCILOP_DECR:

-					renderer->setStencilFailOperation(sw::OPERATION_DECR);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_STENCILZFAIL:

-				switch(value)

-				{

-				case D3DSTENCILOP_KEEP:

-					renderer->setStencilZFailOperation(sw::OPERATION_KEEP);

-					break;

-				case D3DSTENCILOP_ZERO:

-					renderer->setStencilZFailOperation(sw::OPERATION_ZERO);

-					break;

-				case D3DSTENCILOP_REPLACE:

-					renderer->setStencilZFailOperation(sw::OPERATION_REPLACE);

-					break;

-				case D3DSTENCILOP_INCRSAT:

-					renderer->setStencilZFailOperation(sw::OPERATION_INCRSAT);

-					break;

-				case D3DSTENCILOP_DECRSAT:

-					renderer->setStencilZFailOperation(sw::OPERATION_DECRSAT);

-					break;

-				case D3DSTENCILOP_INVERT:

-					renderer->setStencilZFailOperation(sw::OPERATION_INVERT);

-					break;

-				case D3DSTENCILOP_INCR:

-					renderer->setStencilZFailOperation(sw::OPERATION_INCR);

-					break;

-				case D3DSTENCILOP_DECR:

-					renderer->setStencilZFailOperation(sw::OPERATION_DECR);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_STENCILPASS:

-				switch(value)

-				{

-				case D3DSTENCILOP_KEEP:

-					renderer->setStencilPassOperation(sw::OPERATION_KEEP);

-					break;

-				case D3DSTENCILOP_ZERO:

-					renderer->setStencilPassOperation(sw::OPERATION_ZERO);

-					break;

-				case D3DSTENCILOP_REPLACE:

-					renderer->setStencilPassOperation(sw::OPERATION_REPLACE);

-					break;

-				case D3DSTENCILOP_INCRSAT:

-					renderer->setStencilPassOperation(sw::OPERATION_INCRSAT);

-					break;

-				case D3DSTENCILOP_DECRSAT:

-					renderer->setStencilPassOperation(sw::OPERATION_DECRSAT);

-					break;

-				case D3DSTENCILOP_INVERT:

-					renderer->setStencilPassOperation(sw::OPERATION_INVERT);

-					break;

-				case D3DSTENCILOP_INCR:

-					renderer->setStencilPassOperation(sw::OPERATION_INCR);

-					break;

-				case D3DSTENCILOP_DECR:

-					renderer->setStencilPassOperation(sw::OPERATION_DECR);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_STENCILFUNC:

-				switch(value)

-				{

-				case D3DCMP_NEVER:

-					renderer->setStencilCompare(sw::STENCIL_NEVER);

-					break;

-				case D3DCMP_LESS:

-					renderer->setStencilCompare(sw::STENCIL_LESS);

-					break;

-				case D3DCMP_EQUAL:

-					renderer->setStencilCompare(sw::STENCIL_EQUAL);

-					break;

-				case D3DCMP_LESSEQUAL:

-					renderer->setStencilCompare(sw::STENCIL_LESSEQUAL);

-					break;

-				case D3DCMP_GREATER:

-					renderer->setStencilCompare(sw::STENCIL_GREATER);

-					break;

-				case D3DCMP_NOTEQUAL:

-					renderer->setStencilCompare(sw::STENCIL_NOTEQUAL);

-					break;

-				case D3DCMP_GREATEREQUAL:

-					renderer->setStencilCompare(sw::STENCIL_GREATEREQUAL);

-					break;

-				case D3DCMP_ALWAYS:

-					renderer->setStencilCompare(sw::STENCIL_ALWAYS);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_STENCILREF:

-				renderer->setStencilReference(value);

-				renderer->setStencilReferenceCCW(value);

-				break;

-			case D3DRS_STENCILMASK:

-				renderer->setStencilMask(value);

-				renderer->setStencilMaskCCW(value);

-				break;

-			case D3DRS_STENCILWRITEMASK:

-				renderer->setStencilWriteMask(value);

-				renderer->setStencilWriteMaskCCW(value);

-				break;

-			case D3DRS_TEXTUREFACTOR:

-				renderer->setTextureFactor(value);

-				break;

-			case D3DRS_WRAP0:

-				renderer->setTextureWrap(0, value);

-				break;

-			case D3DRS_WRAP1:

-				renderer->setTextureWrap(1, value);

-				break;

-			case D3DRS_WRAP2:

-				renderer->setTextureWrap(2, value);

-				break;

-			case D3DRS_WRAP3:

-				renderer->setTextureWrap(3, value);

-				break;

-			case D3DRS_WRAP4:

-				renderer->setTextureWrap(4, value);

-				break;

-			case D3DRS_WRAP5:

-				renderer->setTextureWrap(5, value);

-				break;

-			case D3DRS_WRAP6:

-				renderer->setTextureWrap(6, value);

-				break;

-			case D3DRS_WRAP7:

-				renderer->setTextureWrap(7, value);

-				break;

-			case D3DRS_CLIPPING:

-				// Ignored, clipping is always performed

-				break;

-			case D3DRS_LIGHTING:

-				renderer->setLightingEnable(value != FALSE);

-				break;

-			case D3DRS_AMBIENT:

-				renderer->setGlobalAmbient(value);

-				break;

-			case D3DRS_FOGVERTEXMODE:

-				switch(value)

-				{

-				case D3DFOG_NONE:

-					renderer->setVertexFogMode(sw::FOG_NONE);

-					break;

-				case D3DFOG_LINEAR:

-					renderer->setVertexFogMode(sw::FOG_LINEAR);

-					break;

-				case D3DFOG_EXP:

-					renderer->setVertexFogMode(sw::FOG_EXP);

-					break;

-				case D3DFOG_EXP2:

-					renderer->setVertexFogMode(sw::FOG_EXP2);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_COLORVERTEX:

-				renderer->setColorVertexEnable(value != FALSE);

-				break;

-			case D3DRS_LOCALVIEWER:

-				renderer->setLocalViewer(value != FALSE);

-				break;

-			case D3DRS_NORMALIZENORMALS:

-				renderer->setNormalizeNormals(value != FALSE);

-				break;

-			case D3DRS_DIFFUSEMATERIALSOURCE:

-				switch(value)

-				{

-				case D3DMCS_MATERIAL:

-					renderer->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);

-					break;

-				case D3DMCS_COLOR1:

-					renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);

-					break;

-				case D3DMCS_COLOR2:

-					renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR2);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_SPECULARMATERIALSOURCE:

-				switch(value)

-				{

-				case D3DMCS_MATERIAL:

-					renderer->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-					break;

-				case D3DMCS_COLOR1:

-					renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR1);

-					break;

-				case D3DMCS_COLOR2:

-					renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR2);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_AMBIENTMATERIALSOURCE:

-				switch(value)

-				{

-				case D3DMCS_MATERIAL:

-					renderer->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);

-					break;

-				case D3DMCS_COLOR1:

-					renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR1);

-					break;

-				case D3DMCS_COLOR2:

-					renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR2);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_EMISSIVEMATERIALSOURCE:

-				switch(value)

-				{

-				case D3DMCS_MATERIAL:

-					renderer->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-					break;

-				case D3DMCS_COLOR1:

-					renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);

-					break;

-				case D3DMCS_COLOR2:

-					renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR2);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_VERTEXBLEND:

-				switch(value)

-				{

-				case D3DVBF_DISABLE:

-					renderer->setVertexBlendMatrixCount(0);

-					break;

-				case D3DVBF_1WEIGHTS:

-					renderer->setVertexBlendMatrixCount(2);

-					break;

-				case D3DVBF_2WEIGHTS:

-					renderer->setVertexBlendMatrixCount(3);

-					break;

-				case D3DVBF_3WEIGHTS:

-					renderer->setVertexBlendMatrixCount(4);

-					break;

-				case D3DVBF_TWEENING:

-					UNIMPLEMENTED();

-					break;

-				case D3DVBF_0WEIGHTS:

-					renderer->setVertexBlendMatrixCount(1);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_CLIPPLANEENABLE:

-				renderer->setClipFlags(value);

-				break;

-			case D3DRS_POINTSIZE:

-				if(value == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0))   // ATI hack to enable instancing on SM 2.0 hardware

-				{

-					instancingEnabled = true;

-				}

-				else if(value == D3DFMT_A2M1)   // ATI hack to enable transparency anti-aliasing

-				{

-					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);

-					renderer->setAlphaTestEnable(true);

-				}

-				else if(value == D3DFMT_A2M0)   // ATI hack to disable transparency anti-aliasing

-				{

-					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);

-					renderer->setAlphaTestEnable(false);

-				}

-				else

-				{

-					renderer->setPointSize((float&)value);

-				}

-				break;

-			case D3DRS_POINTSIZE_MIN:

-				renderer->setPointSizeMin((float&)value);

-				break;

-			case D3DRS_POINTSPRITEENABLE:

-				renderer->setPointSpriteEnable(value != FALSE);

-				break;

-			case D3DRS_POINTSCALEENABLE:

-				renderer->setPointScaleEnable(value != FALSE);

-				break;

-			case D3DRS_POINTSCALE_A:

-				renderer->setPointScaleA((float&)value);

-				break;

-			case D3DRS_POINTSCALE_B:

-				renderer->setPointScaleB((float&)value);

-				break;

-			case D3DRS_POINTSCALE_C:

-				renderer->setPointScaleC((float&)value);

-				break;

-			case D3DRS_MULTISAMPLEANTIALIAS:

-			//	if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_MULTISAMPLEMASK:

-				SetRenderTarget(0, renderTarget[0]);   // Sets the multi-sample mask, if maskable

-				break;

-			case D3DRS_PATCHEDGESTYLE:

-				if(!init) if(value != D3DPATCHEDGE_DISCRETE) UNIMPLEMENTED();

-				break;

-			case D3DRS_DEBUGMONITORTOKEN:

-				if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_POINTSIZE_MAX:

-				renderer->setPointSizeMax((float&)value);

-				break;

-			case D3DRS_INDEXEDVERTEXBLENDENABLE:

-				renderer->setIndexedVertexBlendEnable(value != FALSE);

-				break;

-			case D3DRS_COLORWRITEENABLE:

-				renderer->setColorWriteMask(0, value & 0x0000000F);

-				break;

-			case D3DRS_TWEENFACTOR:

-				if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_BLENDOP:

-				switch(value)

-				{

-				case D3DBLENDOP_ADD:

-					renderer->setBlendOperation(sw::BLENDOP_ADD);

-					break;

-				case D3DBLENDOP_SUBTRACT:

-					renderer->setBlendOperation(sw::BLENDOP_SUB);

-					break;

-				case D3DBLENDOP_REVSUBTRACT:

-					renderer->setBlendOperation(sw::BLENDOP_INVSUB);

-					break;

-				case D3DBLENDOP_MIN:

-					renderer->setBlendOperation(sw::BLENDOP_MIN);

-					break;

-				case D3DBLENDOP_MAX:

-					renderer->setBlendOperation(sw::BLENDOP_MAX);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_POSITIONDEGREE:

-				if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_NORMALDEGREE:

-				if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_SCISSORTESTENABLE:

-				scissorEnable = (value != FALSE);

-				break;

-			case D3DRS_SLOPESCALEDEPTHBIAS:

-				renderer->setSlopeDepthBias((float&)value);

-				break;

-			case D3DRS_ANTIALIASEDLINEENABLE:

-				if(!init) if(value != FALSE) UNIMPLEMENTED();

-				break;

-			case D3DRS_MINTESSELLATIONLEVEL:

-				if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_MAXTESSELLATIONLEVEL:

-				if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_ADAPTIVETESS_X:

-				if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();

-				break;

-			case D3DRS_ADAPTIVETESS_Y:

-				if(value == D3DFMT_ATOC)   // NVIDIA hack to enable transparency anti-aliasing

-				{

-					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);

-				}

-				else if(value == D3DFMT_UNKNOWN)   // NVIDIA hack to disable transparency anti-aliasing

-				{

-					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);

-				}

-				else

-				{

-					if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();

-				}

-				break;

-			case D3DRS_ADAPTIVETESS_Z:

-				if(!init) if((float&)value != 1.0f) UNIMPLEMENTED();

-				break;

-			case D3DRS_ADAPTIVETESS_W:

-				if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();

-				break;

-			case D3DRS_ENABLEADAPTIVETESSELLATION:

-				if(!init) UNIMPLEMENTED();

-				break;

-			case D3DRS_TWOSIDEDSTENCILMODE:

-				renderer->setTwoSidedStencil(value != FALSE);

-				break;

-			case D3DRS_CCW_STENCILFAIL:

-				switch(value)

-				{

-				case D3DSTENCILOP_KEEP:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_KEEP);

-					break;

-				case D3DSTENCILOP_ZERO:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_ZERO);

-					break;

-				case D3DSTENCILOP_REPLACE:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_REPLACE);

-					break;

-				case D3DSTENCILOP_INCRSAT:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_INCRSAT);

-					break;

-				case D3DSTENCILOP_DECRSAT:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_DECRSAT);

-					break;

-				case D3DSTENCILOP_INVERT:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_INVERT);

-					break;

-				case D3DSTENCILOP_INCR:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_INCR);

-					break;

-				case D3DSTENCILOP_DECR:

-					renderer->setStencilFailOperationCCW(sw::OPERATION_DECR);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_CCW_STENCILZFAIL:

-				switch(value)

-				{

-				case D3DSTENCILOP_KEEP:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_KEEP);

-					break;

-				case D3DSTENCILOP_ZERO:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_ZERO);

-					break;

-				case D3DSTENCILOP_REPLACE:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_REPLACE);

-					break;

-				case D3DSTENCILOP_INCRSAT:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_INCRSAT);

-					break;

-				case D3DSTENCILOP_DECRSAT:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_DECRSAT);

-					break;

-				case D3DSTENCILOP_INVERT:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_INVERT);

-					break;

-				case D3DSTENCILOP_INCR:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_INCR);

-					break;

-				case D3DSTENCILOP_DECR:

-					renderer->setStencilZFailOperationCCW(sw::OPERATION_DECR);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_CCW_STENCILPASS:

-				switch(value)

-				{

-				case D3DSTENCILOP_KEEP:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_KEEP);

-					break;

-				case D3DSTENCILOP_ZERO:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_ZERO);

-					break;

-				case D3DSTENCILOP_REPLACE:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_REPLACE);

-					break;

-				case D3DSTENCILOP_INCRSAT:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_INCRSAT);

-					break;

-				case D3DSTENCILOP_DECRSAT:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_DECRSAT);

-					break;

-				case D3DSTENCILOP_INVERT:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_INVERT);

-					break;

-				case D3DSTENCILOP_INCR:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_INCR);

-					break;

-				case D3DSTENCILOP_DECR:

-					renderer->setStencilPassOperationCCW(sw::OPERATION_DECR);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_CCW_STENCILFUNC:

-				switch(value)

-				{

-				case D3DCMP_NEVER:

-					renderer->setStencilCompareCCW(sw::STENCIL_NEVER);

-					break;

-				case D3DCMP_LESS:

-					renderer->setStencilCompareCCW(sw::STENCIL_LESS);

-					break;

-				case D3DCMP_EQUAL:

-					renderer->setStencilCompareCCW(sw::STENCIL_EQUAL);

-					break;

-				case D3DCMP_LESSEQUAL:

-					renderer->setStencilCompareCCW(sw::STENCIL_LESSEQUAL);

-					break;

-				case D3DCMP_GREATER:

-					renderer->setStencilCompareCCW(sw::STENCIL_GREATER);

-					break;

-				case D3DCMP_NOTEQUAL:

-					renderer->setStencilCompareCCW(sw::STENCIL_NOTEQUAL);

-					break;

-				case D3DCMP_GREATEREQUAL:

-					renderer->setStencilCompareCCW(sw::STENCIL_GREATEREQUAL);

-					break;

-				case D3DCMP_ALWAYS:

-					renderer->setStencilCompareCCW(sw::STENCIL_ALWAYS);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_COLORWRITEENABLE1:

-				renderer->setColorWriteMask(1, value);

-				break;

-			case D3DRS_COLORWRITEENABLE2:

-				renderer->setColorWriteMask(2, value);

-				break;

-			case D3DRS_COLORWRITEENABLE3:

-				renderer->setColorWriteMask(3, value);

-				break;

-			case D3DRS_BLENDFACTOR:

-				renderer->setBlendConstant(sw::Color<float>(value));

-				break;

-			case D3DRS_SRGBWRITEENABLE:

-				renderer->setWriteSRGB(value != FALSE);

-				break;

-			case D3DRS_DEPTHBIAS:

-				renderer->setDepthBias((float&)value);

-				break;

-			case D3DRS_WRAP8:

-				renderer->setTextureWrap(8, value);

-				break;

-			case D3DRS_WRAP9:

-				renderer->setTextureWrap(9, value);

-				break;

-			case D3DRS_WRAP10:

-				renderer->setTextureWrap(10, value);

-				break;

-			case D3DRS_WRAP11:

-				renderer->setTextureWrap(11, value);

-				break;

-			case D3DRS_WRAP12:

-				renderer->setTextureWrap(12, value);

-				break;

-			case D3DRS_WRAP13:

-				renderer->setTextureWrap(13, value);

-				break;

-			case D3DRS_WRAP14:

-				renderer->setTextureWrap(14, value);

-				break;

-			case D3DRS_WRAP15:

-				renderer->setTextureWrap(15, value);

-				break;

-			case D3DRS_SEPARATEALPHABLENDENABLE:

-				renderer->setSeparateAlphaBlendEnable(value != FALSE);

-				break;

-			case D3DRS_SRCBLENDALPHA:

-				switch(value)

-				{

-				case D3DBLEND_ZERO:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_ZERO);

-					break;

-				case D3DBLEND_ONE:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_ONE);

-					break;

-				case D3DBLEND_SRCCOLOR:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCE);

-					break;

-				case D3DBLEND_INVSRCCOLOR:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCE);

-					break;

-				case D3DBLEND_SRCALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_INVSRCALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_DESTALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_DESTALPHA);

-					break;

-				case D3DBLEND_INVDESTALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDESTALPHA);

-					break;

-				case D3DBLEND_DESTCOLOR:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_DEST);

-					break;

-				case D3DBLEND_INVDESTCOLOR:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDEST);

-					break;

-				case D3DBLEND_SRCALPHASAT:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_SRCALPHASAT);

-					break;

-				case D3DBLEND_BOTHSRCALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);

-					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_BOTHINVSRCALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);

-					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_BLENDFACTOR:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_CONSTANT);

-					break;

-				case D3DBLEND_INVBLENDFACTOR:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVCONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_DESTBLENDALPHA:

-				switch(value)

-				{

-				case D3DBLEND_ZERO:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_ZERO);

-					break;

-				case D3DBLEND_ONE:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_ONE);

-					break;

-				case D3DBLEND_SRCCOLOR:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCE);

-					break;

-				case D3DBLEND_INVSRCCOLOR:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCE);

-					break;

-				case D3DBLEND_SRCALPHA:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_INVSRCALPHA:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_DESTALPHA:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_DESTALPHA);

-					break;

-				case D3DBLEND_INVDESTALPHA:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_INVDESTALPHA);

-					break;

-				case D3DBLEND_DESTCOLOR:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_DEST);

-					break;

-				case D3DBLEND_INVDESTCOLOR:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_INVDEST);

-					break;

-				case D3DBLEND_SRCALPHASAT:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_SRCALPHASAT);

-					break;

-				case D3DBLEND_BOTHSRCALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);

-					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);

-					break;

-				case D3DBLEND_BOTHINVSRCALPHA:

-					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);

-					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);

-					break;

-				case D3DBLEND_BLENDFACTOR:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_CONSTANT);

-					break;

-				case D3DBLEND_INVBLENDFACTOR:

-					renderer->setDestBlendFactorAlpha(sw::BLEND_INVCONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DRS_BLENDOPALPHA:

-				switch(value)

-				{

-				case D3DBLENDOP_ADD:

-					renderer->setBlendOperationAlpha(sw::BLENDOP_ADD);

-					break;

-				case D3DBLENDOP_SUBTRACT:

-					renderer->setBlendOperationAlpha(sw::BLENDOP_SUB);

-					break;

-				case D3DBLENDOP_REVSUBTRACT:

-					renderer->setBlendOperationAlpha(sw::BLENDOP_INVSUB);

-					break;

-				case D3DBLENDOP_MIN:

-					renderer->setBlendOperationAlpha(sw::BLENDOP_MIN);

-					break;

-				case D3DBLENDOP_MAX:

-					renderer->setBlendOperationAlpha(sw::BLENDOP_MAX);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			default:

-				ASSERT(false);

-			}

-		}

-		else   // stateRecorder

-		{

-			stateRecorder->setRenderState(state, value);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetRenderTarget(unsigned long index, IDirect3DSurface9 *iRenderTarget)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long index = %d, IDirect3DSurface9 *newRenderTarget = 0x%0.8p", index, iRenderTarget);

-

-		// FIXME: Check for D3DUSAGE_RENDERTARGET

-

-		if(index >= 4 || (index == 0 && !iRenderTarget))

-		{

-			return INVALIDCALL();

-		}

-

-		Direct3DSurface9 *renderTarget = static_cast<Direct3DSurface9*>(iRenderTarget);

-

-		if(renderTarget)

-		{

-			renderTarget->bind();

-		}

-

-		if(this->renderTarget[index])

-		{

-			this->renderTarget[index]->unbind();

-		}

-

-		this->renderTarget[index] = renderTarget;

-

-		if(renderTarget && index == 0)

-		{

-			D3DSURFACE_DESC renderTargetDesc;

-			renderTarget->GetDesc(&renderTargetDesc);

-

-			// Reset viewport to size of current render target

-			viewport.X = 0;

-			viewport.Y = 0;

-			viewport.Width = renderTargetDesc.Width;

-			viewport.Height = renderTargetDesc.Height;

-			viewport.MinZ = 0;

-			viewport.MaxZ = 1;

-

-			// Reset scissor rectangle to size of current render target

-			scissorRect.left = 0;

-			scissorRect.top = 0;

-			scissorRect.right = renderTargetDesc.Width;

-			scissorRect.bottom = renderTargetDesc.Height;

-

-			// Set the multi-sample mask, if maskable

-			if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE &&

-			   renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONMASKABLE)

-			{

-				renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]);

-			}

-			else

-			{

-				renderer->setMultiSampleMask(0xFFFFFFFF);

-			}

-		}

-

-		renderer->setRenderTarget(index, renderTarget);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE state = %d, unsigned long value = %d", sampler, state, value);

-

-		if(state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)

-		{

-			return INVALIDCALL();

-		}

-

-		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)

-		{

-			return INVALIDCALL();

-		}

-

-		if(sampler >= D3DVERTEXTEXTURESAMPLER0)

-		{

-			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);

-		}

-

-		if(!stateRecorder)

-		{

-			if(!init && samplerState[sampler][state] == value)

-			{

-				return D3D_OK;

-			}

-

-			samplerState[sampler][state] = value;

-

-			sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;

-			int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group

-

-			switch(state)

-			{

-			case D3DSAMP_ADDRESSU:

-				switch(value)

-				{

-				case D3DTADDRESS_WRAP:

-					renderer->setAddressingModeU(type, index, sw::ADDRESSING_WRAP);

-					break;

-				case D3DTADDRESS_MIRROR:

-					renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRROR);

-					break;

-				case D3DTADDRESS_CLAMP:

-					renderer->setAddressingModeU(type, index, sw::ADDRESSING_CLAMP);

-					break;

-				case D3DTADDRESS_BORDER:

-					renderer->setAddressingModeU(type, index, sw::ADDRESSING_BORDER);

-					break;

-				case D3DTADDRESS_MIRRORONCE:

-					renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRRORONCE);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DSAMP_ADDRESSV:

-				switch(value)

-				{

-				case D3DTADDRESS_WRAP:

-					renderer->setAddressingModeV(type, index, sw::ADDRESSING_WRAP);

-					break;

-				case D3DTADDRESS_MIRROR:

-					renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRROR);

-					break;

-				case D3DTADDRESS_CLAMP:

-					renderer->setAddressingModeV(type, index, sw::ADDRESSING_CLAMP);

-					break;

-				case D3DTADDRESS_BORDER:

-					renderer->setAddressingModeV(type, index, sw::ADDRESSING_BORDER);

-					break;

-				case D3DTADDRESS_MIRRORONCE:

-					renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRRORONCE);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DSAMP_ADDRESSW:

-				switch(value)

-				{

-				case D3DTADDRESS_WRAP:

-					renderer->setAddressingModeW(type, index, sw::ADDRESSING_WRAP);

-					break;

-				case D3DTADDRESS_MIRROR:

-					renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRROR);

-					break;

-				case D3DTADDRESS_CLAMP:

-					renderer->setAddressingModeW(type, index, sw::ADDRESSING_CLAMP);

-					break;

-				case D3DTADDRESS_BORDER:

-					renderer->setAddressingModeW(type, index, sw::ADDRESSING_BORDER);

-					break;

-				case D3DTADDRESS_MIRRORONCE:

-					renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRRORONCE);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DSAMP_BORDERCOLOR:

-				renderer->setBorderColor(type, index, value);

-				break;

-			case D3DSAMP_MAGFILTER:

-				// NOTE: SwiftShader does not differentiate between minification and magnification filter

-				switch(value)

-				{

-				case D3DTEXF_NONE:

-					renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter

-					break;

-				case D3DTEXF_POINT:

-					renderer->setTextureFilter(type, index, sw::FILTER_POINT);

-					break;

-				case D3DTEXF_LINEAR:

-					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);

-					break;

-				case D3DTEXF_ANISOTROPIC:

-					renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);

-					break;

-				case D3DTEXF_PYRAMIDALQUAD:

-					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently

-					break;

-				case D3DTEXF_GAUSSIANQUAD:

-					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently

-					break;

-				default:

-					return INVALIDCALL();

-				};

-				break;

-			case D3DSAMP_MINFILTER:

-				// NOTE: SwiftShader does not differentiate between minification and magnification filter

-				switch(value)

-				{

-				case D3DTEXF_NONE:

-					renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter

-					break;

-				case D3DTEXF_POINT:

-					renderer->setTextureFilter(type, index, sw::FILTER_POINT);

-					break;

-				case D3DTEXF_LINEAR:

-					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);

-					break;

-				case D3DTEXF_ANISOTROPIC:

-					renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);

-					break;

-				case D3DTEXF_PYRAMIDALQUAD:

-					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently

-					break;

-				case D3DTEXF_GAUSSIANQUAD:

-					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently

-					break;

-				default:

-					return INVALIDCALL();

-				};

-				break;

-			case D3DSAMP_MIPFILTER:

-				switch(value)

-				{

-				case D3DTEXF_NONE:

-					renderer->setMipmapFilter(type, index, sw::MIPMAP_NONE);

-					break;

-				case D3DTEXF_POINT:

-					renderer->setMipmapFilter(type, index, sw::MIPMAP_POINT);

-					break;

-				case D3DTEXF_LINEAR:

-					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);

-					break;

-				case D3DTEXF_ANISOTROPIC:

-					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter

-					break;

-				case D3DTEXF_PYRAMIDALQUAD:

-					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter

-					break;

-				case D3DTEXF_GAUSSIANQUAD:

-					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter

-					break;

-				default:

-					return INVALIDCALL();

-				};

-				break;

-			case D3DSAMP_MIPMAPLODBIAS:

-				if(value == D3DFMT_GET4)   // ATI hack to enable Fetch4

-				{

-					renderer->setGatherEnable(type, index, true);

-				}

-				else if(value == D3DFMT_GET1)   // ATI hack to disable Fetch4

-				{

-					renderer->setGatherEnable(type, index, false);

-				}

-				else

-				{

-					float LOD = (float&)value - sw::log2((float)context->renderTarget[0]->getSuperSampleCount());   // FIXME: Update when render target changes

-					renderer->setMipmapLOD(type, index, LOD);

-				}

-				break;

-			case D3DSAMP_MAXMIPLEVEL:

-				break;

-			case D3DSAMP_MAXANISOTROPY:

-				renderer->setMaxAnisotropy(type, index, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy));

-				break;

-			case D3DSAMP_SRGBTEXTURE:

-				renderer->setReadSRGB(type, index, value != FALSE);

-				break;

-			case D3DSAMP_ELEMENTINDEX:

-				if(!init) UNIMPLEMENTED();   // Multi-element textures deprecated in favor of multiple render targets

-				break;

-			case D3DSAMP_DMAPOFFSET:

-			//	if(!init) UNIMPLEMENTED();

-				break;

-			default:

-				ASSERT(false);

-			}

-		}

-		else   // stateRecorder

-		{

-			stateRecorder->setSamplerState(sampler, state, value);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetScissorRect(const RECT *rect)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const RECT *rect = 0x%0.8p", rect);

-

-		if(!rect)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			scissorRect = *rect;

-		}

-		else

-		{

-			stateRecorder->setScissorRect(rect);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetSoftwareVertexProcessing(int software)

-	{

-		CriticalSection cs(this);

-

-		TRACE("int software = %d", software);

-

-		if(behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING && software == FALSE)

-		{

-			return INVALIDCALL();

-		}

-

-		if(behaviourFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && software == TRUE)

-		{

-			return INVALIDCALL();

-		}

-

-		softwareVertexProcessing = (software != FALSE);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *iVertexBuffer, unsigned int offset, unsigned int stride)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int stream = %d, IDirect3DVertexBuffer9 *data = 0x%0.8p, unsigned int offset = %d, unsigned int stride = %d", stream, iVertexBuffer, offset, stride);

-

-		Direct3DVertexBuffer9 *vertexBuffer = static_cast<Direct3DVertexBuffer9*>(iVertexBuffer);

-

-		if(!stateRecorder)

-		{

-			if(dataStream[stream] == vertexBuffer && streamOffset[stream] == offset && streamStride[stream] == stride)

-			{

-				return D3D_OK;

-			}

-

-			if(vertexBuffer)

-			{

-				vertexBuffer->bind();

-			}

-

-			if(dataStream[stream])

-			{

-				dataStream[stream]->unbind();

-			}

-

-			dataStream[stream] = vertexBuffer;

-			streamOffset[stream] = offset;

-			streamStride[stream] = stride;

-		}

-		else

-		{

-			stateRecorder->setStreamSource(stream, vertexBuffer, offset, stride);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int streamNumber = %d, unsigned int divider = %d", streamNumber, divider);

-

-		if(!instancingEnabled)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			streamSourceFreq[streamNumber] = divider;

-		}

-		else

-		{

-			stateRecorder->setStreamSourceFreq(streamNumber, divider);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);

-

-		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)

-		{

-			return INVALIDCALL();

-		}

-

-		if(sampler >= D3DVERTEXTEXTURESAMPLER0)

-		{

-			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);

-		}

-

-		Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(iBaseTexture);

-

-		if(!stateRecorder)

-		{

-			if(texture[sampler] == baseTexture)

-			{

-				return D3D_OK;

-			}

-

-			if(baseTexture)

-			{

-				baseTexture->bind();   // FIXME: Bind individual sub-surfaces?

-			}

-

-			if(texture[sampler])

-			{

-				texture[sampler]->unbind();

-			}

-

-			texture[sampler] = baseTexture;

-		}

-		else

-		{

-			stateRecorder->setTexture(sampler, baseTexture);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);

-

-		if(stage < 0 || stage >= 8 || type < D3DTSS_COLOROP || type > D3DTSS_CONSTANT)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			if(!init && textureStageState[stage][type] == value)

-			{

-				return D3D_OK;

-			}

-

-			textureStageState[stage][type] = value;

-

-			switch(type)

-			{

-			case D3DTSS_COLOROP:

-				switch(value)

-				{

-				case D3DTOP_DISABLE:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE);

-					break;

-				case D3DTOP_SELECTARG1:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1);

-					break;

-				case D3DTOP_SELECTARG2:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2);

-					break;

-				case D3DTOP_MODULATE:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE);

-					break;

-				case D3DTOP_MODULATE2X:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X);

-					break;

-				case D3DTOP_MODULATE4X:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X);

-					break;

-				case D3DTOP_ADD:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD);

-					break;

-				case D3DTOP_ADDSIGNED:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED);

-					break;

-				case D3DTOP_ADDSIGNED2X:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X);

-					break;

-				case D3DTOP_SUBTRACT:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT);

-					break;

-				case D3DTOP_ADDSMOOTH:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH);

-					break;

-				case D3DTOP_BLENDDIFFUSEALPHA:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);

-					break;

-				case D3DTOP_BLENDTEXTUREALPHA:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);

-					break;

-				case D3DTOP_BLENDFACTORALPHA:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);

-					break;

-				case D3DTOP_BLENDTEXTUREALPHAPM:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);

-					break;

-				case D3DTOP_BLENDCURRENTALPHA:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);

-					break;

-				case D3DTOP_PREMODULATE:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE);

-					break;

-				case D3DTOP_MODULATEALPHA_ADDCOLOR:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);

-					break;

-				case D3DTOP_MODULATECOLOR_ADDALPHA:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);

-					break;

-				case D3DTOP_MODULATEINVALPHA_ADDCOLOR:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);

-					break;

-				case D3DTOP_MODULATEINVCOLOR_ADDALPHA:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);

-					break;

-				case D3DTOP_BUMPENVMAP:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP);

-					break;

-				case D3DTOP_BUMPENVMAPLUMINANCE:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);

-					break;

-				case D3DTOP_DOTPRODUCT3:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3);

-					break;

-				case D3DTOP_MULTIPLYADD:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD);

-					break;

-				case D3DTOP_LERP:

-					renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_COLORARG1:

-				switch(value & D3DTA_SELECTMASK)

-				{

-				case D3DTA_DIFFUSE:

-					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);

-					break;

-				case D3DTA_CURRENT:

-					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT);

-					break;

-				case D3DTA_TEXTURE:

-					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE);

-					break;

-				case D3DTA_TFACTOR:

-					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR);

-					break;

-				case D3DTA_SPECULAR:

-					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR);

-					break;

-				case D3DTA_TEMP:

-					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP);

-					break;

-				case D3DTA_CONSTANT:

-					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-

-				switch(value & ~D3DTA_SELECTMASK)

-				{

-				case 0:

-					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR);

-					break;

-				case D3DTA_COMPLEMENT:

-					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);

-					break;

-				case D3DTA_ALPHAREPLICATE:

-					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA);

-					break;

-				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:

-					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_COLORARG2:

-				switch(value & D3DTA_SELECTMASK)

-				{

-				case D3DTA_DIFFUSE:

-					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);

-					break;

-				case D3DTA_CURRENT:

-					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT);

-					break;

-				case D3DTA_TEXTURE:

-					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE);

-					break;

-				case D3DTA_TFACTOR:

-					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR);

-					break;

-				case D3DTA_SPECULAR:

-					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR);

-					break;

-				case D3DTA_TEMP:

-					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP);

-					break;

-				case D3DTA_CONSTANT:

-					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-

-				switch(value & ~D3DTA_SELECTMASK)

-				{

-				case 0:

-					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR);

-					break;

-				case D3DTA_COMPLEMENT:

-					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);

-					break;

-				case D3DTA_ALPHAREPLICATE:

-					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA);

-					break;

-				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:

-					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_ALPHAOP:

-				switch(value)

-				{

-				case D3DTOP_DISABLE:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE);

-					break;

-				case D3DTOP_SELECTARG1:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1);

-					break;

-				case D3DTOP_SELECTARG2:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2);

-					break;

-				case D3DTOP_MODULATE:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE);

-					break;

-				case D3DTOP_MODULATE2X:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X);

-					break;

-				case D3DTOP_MODULATE4X:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X);

-					break;

-				case D3DTOP_ADD:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD);

-					break;

-				case D3DTOP_ADDSIGNED:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED);

-					break;

-				case D3DTOP_ADDSIGNED2X:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X);

-					break;

-				case D3DTOP_SUBTRACT:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT);

-					break;

-				case D3DTOP_ADDSMOOTH:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH);

-					break;

-				case D3DTOP_BLENDDIFFUSEALPHA:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);

-					break;

-				case D3DTOP_BLENDTEXTUREALPHA:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);

-					break;

-				case D3DTOP_BLENDFACTORALPHA:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);

-					break;

-				case D3DTOP_BLENDTEXTUREALPHAPM:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);

-					break;

-				case D3DTOP_BLENDCURRENTALPHA:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);

-					break;

-				case D3DTOP_PREMODULATE:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE);

-					break;

-				case D3DTOP_MODULATEALPHA_ADDCOLOR:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);

-					break;

-				case D3DTOP_MODULATECOLOR_ADDALPHA:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);

-					break;

-				case D3DTOP_MODULATEINVALPHA_ADDCOLOR:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);

-					break;

-				case D3DTOP_MODULATEINVCOLOR_ADDALPHA:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);

-					break;

-				case D3DTOP_BUMPENVMAP:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP);

-					break;

-				case D3DTOP_BUMPENVMAPLUMINANCE:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);

-					break;

-				case D3DTOP_DOTPRODUCT3:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3);

-					break;

-				case D3DTOP_MULTIPLYADD:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD);

-					break;

-				case D3DTOP_LERP:

-					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_ALPHAARG1:

-				switch(value & D3DTA_SELECTMASK)

-				{

-				case D3DTA_DIFFUSE:

-					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);

-					break;

-				case D3DTA_CURRENT:

-					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);

-					break;

-				case D3DTA_TEXTURE:

-					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);

-					break;

-				case D3DTA_TFACTOR:

-					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);

-					break;

-				case D3DTA_SPECULAR:

-					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);

-					break;

-				case D3DTA_TEMP:

-					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);

-					break;

-				case D3DTA_CONSTANT:

-					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-

-				switch(value & ~D3DTA_SELECTMASK)

-				{

-				case 0:

-					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);

-					break;

-				case D3DTA_COMPLEMENT:

-					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);

-					break;

-				case D3DTA_ALPHAREPLICATE:

-					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);

-					break;

-				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:

-					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_ALPHAARG2:

-				switch(value & D3DTA_SELECTMASK)

-				{

-				case D3DTA_DIFFUSE:

-					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);

-					break;

-				case D3DTA_CURRENT:

-					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);

-					break;

-				case D3DTA_TEXTURE:

-					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);

-					break;

-				case D3DTA_TFACTOR:

-					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);

-					break;

-				case D3DTA_SPECULAR:

-					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);

-					break;

-				case D3DTA_TEMP:

-					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);

-					break;

-				case D3DTA_CONSTANT:

-					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-

-				switch(value & ~D3DTA_SELECTMASK)

-				{

-				case 0:

-					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);

-					break;

-				case D3DTA_COMPLEMENT:

-					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);

-					break;

-				case D3DTA_ALPHAREPLICATE:

-					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);

-					break;

-				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:

-					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_BUMPENVMAT00:

-				renderer->setBumpmapMatrix(stage, 0, (float&)value);

-				break;

-			case D3DTSS_BUMPENVMAT01:

-				renderer->setBumpmapMatrix(stage, 1, (float&)value);

-				break;

-			case D3DTSS_BUMPENVMAT10:

-				renderer->setBumpmapMatrix(stage, 2, (float&)value);

-				break;

-			case D3DTSS_BUMPENVMAT11:

-				renderer->setBumpmapMatrix(stage, 3, (float&)value);

-				break;

-			case D3DTSS_TEXCOORDINDEX:

-				renderer->setTexCoordIndex(stage, value & 0x0000FFFF);

-

-				switch(value & 0xFFFF0000)

-				{

-				case D3DTSS_TCI_PASSTHRU:

-					renderer->setTexGen(stage, sw::TEXGEN_PASSTHRU);

-					break;

-				case D3DTSS_TCI_CAMERASPACENORMAL:

-					renderer->setTexCoordIndex(stage, stage);

-					renderer->setTexGen(stage, sw::TEXGEN_NORMAL);

-					break;

-				case D3DTSS_TCI_CAMERASPACEPOSITION:

-					renderer->setTexCoordIndex(stage, stage);

-					renderer->setTexGen(stage, sw::TEXGEN_POSITION);

-					break;

-				case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:

-					renderer->setTexCoordIndex(stage, stage);

-					renderer->setTexGen(stage, sw::TEXGEN_REFLECTION);

-					break;

-				case D3DTSS_TCI_SPHEREMAP:

-					renderer->setTexCoordIndex(stage, stage);

-					renderer->setTexGen(stage, sw::TEXGEN_SPHEREMAP);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_BUMPENVLSCALE:

-				renderer->setLuminanceScale(stage, (float&)value);

-				break;

-			case D3DTSS_BUMPENVLOFFSET:

-				renderer->setLuminanceOffset(stage, (float&)value);

-				break;

-			case D3DTSS_TEXTURETRANSFORMFLAGS:

-				switch(value & ~D3DTTFF_PROJECTED)

-				{

-				case D3DTTFF_DISABLE:

-					renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);

-					break;

-				case D3DTTFF_COUNT1:

-					renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);

-					break;

-				case D3DTTFF_COUNT2:

-					renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);

-					break;

-				case D3DTTFF_COUNT3:

-					renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);

-					break;

-				case D3DTTFF_COUNT4:

-					renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_COLORARG0:

-				switch(value & D3DTA_SELECTMASK)

-				{

-				case D3DTA_CURRENT:

-					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT);

-					break;

-				case D3DTA_DIFFUSE:

-					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);

-					break;

-				case D3DTA_SPECULAR:

-					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR);

-					break;

-				case D3DTA_TEMP:

-					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP);

-					break;

-				case D3DTA_TEXTURE:

-					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE);

-					break;

-				case D3DTA_TFACTOR:

-					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR);

-					break;

-				default:

-					ASSERT(false);

-				}

-

-				switch(value & ~D3DTA_SELECTMASK)

-				{

-				case 0:

-					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR);

-					break;

-				case D3DTA_COMPLEMENT:

-					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);

-					break;

-				case D3DTA_ALPHAREPLICATE:

-					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA);

-					break;

-				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:

-					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_ALPHAARG0:

-				switch(value & D3DTA_SELECTMASK)

-				{

-				case D3DTA_DIFFUSE:

-					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);

-					break;

-				case D3DTA_CURRENT:

-					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);

-					break;

-				case D3DTA_TEXTURE:

-					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);

-					break;

-				case D3DTA_TFACTOR:

-					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);

-					break;

-				case D3DTA_SPECULAR:

-					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);

-					break;

-				case D3DTA_TEMP:

-					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);

-					break;

-				case D3DTA_CONSTANT:

-					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);

-					break;

-				default:

-					ASSERT(false);

-				}

-

-				switch(value & ~D3DTA_SELECTMASK)

-				{

-				case 0:

-					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);

-					break;

-				case D3DTA_COMPLEMENT:

-					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);

-					break;

-				case D3DTA_ALPHAREPLICATE:

-					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);

-					break;

-				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:

-					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_RESULTARG:

-				switch(value & D3DTA_SELECTMASK)

-				{

-				case D3DTA_CURRENT:

-					renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT);

-					break;

-				case D3DTA_TEMP:

-					renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP);

-					break;

-				default:

-					ASSERT(false);

-				}

-				break;

-			case D3DTSS_CONSTANT:

-				renderer->setConstantColor(stage, value);

-				break;

-			default:

-				ASSERT(false);

-			}

-		}

-		else   // stateRecorder

-		{

-			stateRecorder->setTextureStageState(stage, type, value);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)

-	{

-		CriticalSection cs(this);

-

-		TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);

-

-		if(!matrix)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			this->matrix[state] = *matrix;

-

-			sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,

-			             matrix->_12, matrix->_22, matrix->_32, matrix->_42,

-			             matrix->_13, matrix->_23, matrix->_33, matrix->_43,

-			             matrix->_14, matrix->_24, matrix->_34, matrix->_44);

-

-			switch(state)

-			{

-			case D3DTS_WORLD:

-				renderer->setModelMatrix(M);

-				break;

-			case D3DTS_VIEW:

-				renderer->setViewMatrix(M);

-				break;

-			case D3DTS_PROJECTION:

-				renderer->setProjectionMatrix(M);

-				break;

-			case D3DTS_TEXTURE0:

-				renderer->setTextureMatrix(0, M);

-				break;

-			case D3DTS_TEXTURE1:

-				renderer->setTextureMatrix(1, M);

-				break;

-			case D3DTS_TEXTURE2:

-				renderer->setTextureMatrix(2, M);

-				break;

-			case D3DTS_TEXTURE3:

-				renderer->setTextureMatrix(3, M);

-				break;

-			case D3DTS_TEXTURE4:

-				renderer->setTextureMatrix(4, M);

-				break;

-			case D3DTS_TEXTURE5:

-				renderer->setTextureMatrix(5, M);

-				break;

-			case D3DTS_TEXTURE6:

-				renderer->setTextureMatrix(6, M);

-				break;

-			case D3DTS_TEXTURE7:

-				renderer->setTextureMatrix(7, M);

-				break;

-			default:

-				if(state > 256 && state < 512)

-				{

-					renderer->setModelMatrix(M, state - 256);

-				}

-				else ASSERT(false);

-			}

-		}

-		else   // stateRecorder

-		{

-			stateRecorder->setTransform(state, matrix);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *iVertexDeclaration)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DVertexDeclaration9 *declaration = 0x%0.8p", iVertexDeclaration);

-

-		Direct3DVertexDeclaration9 *vertexDeclaration = static_cast<Direct3DVertexDeclaration9*>(iVertexDeclaration);

-

-		if(!stateRecorder)

-		{

-			if(this->vertexDeclaration == vertexDeclaration)

-			{

-				return D3D_OK;

-			}

-

-			if(vertexDeclaration)

-			{

-				vertexDeclaration->bind();

-			}

-

-			if(this->vertexDeclaration)

-			{

-				this->vertexDeclaration->unbind();

-			}

-

-			this->vertexDeclaration = vertexDeclaration;

-		}

-		else

-		{

-			stateRecorder->setVertexDeclaration(vertexDeclaration);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetVertexShader(IDirect3DVertexShader9 *iVertexShader)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DVertexShader9 *shader = 0x%0.8p", iVertexShader);

-

-		Direct3DVertexShader9 *vertexShader = static_cast<Direct3DVertexShader9*>(iVertexShader);

-

-		if(!stateRecorder)

-		{

-			if(this->vertexShader == vertexShader)

-			{

-				return D3D_OK;

-			}

-

-			if(vertexShader)

-			{

-				vertexShader->bind();

-			}

-

-			if(this->vertexShader)

-			{

-				this->vertexShader->unbind();

-			}

-

-			this->vertexShader = vertexShader;

-			vertexShaderDirty = true;

-		}

-		else

-		{

-			stateRecorder->setVertexShader(vertexShader);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)

-			{

-				vertexShaderConstantB[startRegister + i] = constantData[i];

-			}

-

-			vertexShaderConstantsBDirty = sw::max(startRegister + count, vertexShaderConstantsBDirty);

-			vertexShaderDirty = true;   // Reload DEF constants

-		}

-		else

-		{

-			stateRecorder->setVertexShaderConstantB(startRegister, constantData, count);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			for(unsigned int i = 0; i < count && startRegister + i < MAX_VERTEX_SHADER_CONST; 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 = sw::max(startRegister + count, vertexShaderConstantsFDirty);

-			vertexShaderDirty = true;   // Reload DEF constants

-		}

-		else

-		{

-			stateRecorder->setVertexShaderConstantF(startRegister, constantData, count);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);

-

-		if(!constantData)

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)

-			{

-				vertexShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];

-				vertexShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];

-				vertexShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];

-				vertexShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];

-			}

-

-			vertexShaderConstantsIDirty = sw::max(startRegister + count, vertexShaderConstantsIDirty);

-			vertexShaderDirty = true;   // Reload DEF constants

-		}

-		else

-		{

-			stateRecorder->setVertexShaderConstantI(startRegister, constantData, count);

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::SetViewport(const D3DVIEWPORT9 *viewport)

-	{

-		CriticalSection cs(this);

-

-		TRACE("const D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);

-

-		if(!viewport)   // FIXME: Check if valid

-		{

-			return INVALIDCALL();

-		}

-

-		if(!stateRecorder)

-		{

-			this->viewport = *viewport;

-		}

-		else

-		{

-			stateRecorder->setViewport(viewport);

-		}

-

-		return D3D_OK;

-	}

-

-	int Direct3DDevice9::ShowCursor(int show)

-	{

-		CriticalSection cs(this);

-

-		TRACE("int show = %d", show);

-

-		int oldValue = showCursor ? TRUE : FALSE;

-		showCursor = show != FALSE;

-

-		if(showCursor)

-		{

-			sw::FrameBuffer::setCursorImage(cursor);

-		}

-		else

-		{

-			sw::FrameBuffer::setCursorImage(0);

-		}

-

-		return oldValue;

-	}

-

-	long Direct3DDevice9::StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p, const RECT *destRect = 0x%0.8p, D3DTEXTUREFILTERTYPE filter = %d", sourceSurface, sourceRect, destSurface, destRect, filter);

-

-		if(!sourceSurface || !destSurface || !validRectangle(sourceRect, sourceSurface) || !validRectangle(destRect, destSurface))

-		{

-			return INVALIDCALL();

-		}

-

-		D3DSURFACE_DESC sourceDescription;

-		D3DSURFACE_DESC destDescription;

-

-		sourceSurface->GetDesc(&sourceDescription);

-		destSurface->GetDesc(&destDescription);

-

-		if(sourceDescription.Pool != D3DPOOL_DEFAULT || destDescription.Pool != D3DPOOL_DEFAULT)

-		{

-			return INVALIDCALL();

-		}

-

-		Direct3DSurface9 *source = static_cast<Direct3DSurface9*>(sourceSurface);

-		Direct3DSurface9 *dest = static_cast<Direct3DSurface9*>(destSurface);

-

-		stretchRect(source, sourceRect, dest, destRect, filter);

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::TestCooperativeLevel()

-	{

-		CriticalSection cs(this);

-

-		TRACE("void");

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destinationSurface = 0x%0.8p, const POINT *destPoint = 0x%0.8p", sourceSurface, sourceRect, destinationSurface, destPoint);

-

-		if(!sourceSurface || !destinationSurface)

-		{

-			return INVALIDCALL();

-		}

-

-		D3DSURFACE_DESC sourceDescription;

-		D3DSURFACE_DESC destinationDescription;

-

-		sourceSurface->GetDesc(&sourceDescription);

-		destinationSurface->GetDesc(&destinationDescription);

-

-		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 = sourceDescription.Width;

-			sRect.bottom = sourceDescription.Height;

-		}

-

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

-		{

-			return INVALIDCALL();

-		}

-

-		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(sourceDescription.MultiSampleType      != D3DMULTISAMPLE_NONE ||

-		   destinationDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||

-		// sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||   // FIXME: Check back buffer and depth buffer memory pool flags

-		// destinationDescription.Pool != D3DPOOL_DEFAULT ||

-		   sourceDescription.Format != destinationDescription.Format)

-		{

-			return INVALIDCALL();

-		}

-

-		sw::Surface *source = static_cast<Direct3DSurface9*>(sourceSurface);

-		sw::Surface *dest = static_cast<Direct3DSurface9*>(destinationSurface);

-

-		unsigned char *sBuffer = (unsigned char*)source->lockExternal(sRect.left, sRect.top, 0, sw::LOCK_READONLY, sw::PUBLIC);

-		unsigned char *dBuffer = (unsigned char*)dest->lockExternal(dRect.left, dRect.top, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);

-		int sPitch = source->getExternalPitchB();

-		int dPitch = dest->getExternalPitchB();

-

-		unsigned int width;

-		unsigned int height;

-		unsigned int bytes;

-

-		switch(sourceDescription.Format)

-		{

-		case D3DFMT_DXT1:

-		case D3DFMT_ATI1:

-			width = (dWidth + 3) / 4;

-			height = (dHeight + 3) / 4;

-			bytes = width * 8;   // 64 bit per 4x4 block

-			break;

-		case D3DFMT_DXT2:

-		case D3DFMT_DXT3:

-		case D3DFMT_DXT4:

-		case D3DFMT_DXT5:

-		case D3DFMT_ATI2:

-			width = (dWidth + 3) / 4;

-			height = (dHeight + 3) / 4;

-			bytes = width * 16;   // 128 bit per 4x4 block

-			break;

-		default:

-			width = dWidth;

-			height = dHeight;

-			bytes = width * Direct3DSurface9::bytes(sourceDescription.Format);

-		}

-

-		if(sourceDescription.Format == D3DFMT_ATI1 || sourceDescription.Format == D3DFMT_ATI2)

-		{

-			// Make the pitch correspond to 4 rows

-			sPitch *= 4;

-			dPitch *= 4;

-		}

-

-		for(unsigned int y = 0; y < height; y++)

-		{

-			memcpy(dBuffer, sBuffer, bytes);

-

-			sBuffer += sPitch;

-			dBuffer += dPitch;

-		}

-

-		source->unlockExternal();

-		dest->unlockExternal();

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture)

-	{

-		CriticalSection cs(this);

-

-		TRACE("IDirect3DBaseTexture9 *sourceTexture = 0x%0.8p, IDirect3DBaseTexture9 *destinationTexture = 0x%0.8p", sourceTexture, destinationTexture);

-

-		if(!sourceTexture || !destinationTexture)

-		{

-			return INVALIDCALL();

-		}

-

-		// FIXME: Check memory pools

-

-		D3DRESOURCETYPE type = sourceTexture->GetType();

-

-		if(type != destinationTexture->GetType())

-		{

-			return INVALIDCALL();

-		}

-

-		switch(type)

-		{

-		case D3DRTYPE_TEXTURE:

-			{

-				IDirect3DTexture9 *source;

-				IDirect3DTexture9 *dest;

-

-				sourceTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&source);

-				destinationTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&dest);

-

-				ASSERT(source && dest);

-

-				for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination

-				{

-					IDirect3DSurface9 *sourceSurface;

-					IDirect3DSurface9 *destinationSurface;

-

-					source->GetSurfaceLevel(level, &sourceSurface);

-					dest->GetSurfaceLevel(level, &destinationSurface);

-

-					UpdateSurface(sourceSurface, 0, destinationSurface, 0);

-

-					sourceSurface->Release();

-					destinationSurface->Release();

-				}

-

-				source->Release();

-				dest->Release();

-			}

-			break;

-		case D3DRTYPE_VOLUMETEXTURE:

-			{

-				IDirect3DVolumeTexture9 *source;

-				IDirect3DVolumeTexture9 *dest;

-

-				sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&source);

-				destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&dest);

-

-				ASSERT(source && dest);

-

-				for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination

-				{

-					IDirect3DVolume9 *sourceVolume;

-					IDirect3DVolume9 *destinationVolume;

-

-					source->GetVolumeLevel(level, &sourceVolume);

-					dest->GetVolumeLevel(level, &destinationVolume);

-

-					updateVolume(sourceVolume, destinationVolume);

-

-					sourceVolume->Release();

-					destinationVolume->Release();

-				}

-

-				source->Release();

-				dest->Release();

-			}

-			break;

-		case D3DRTYPE_CUBETEXTURE:

-			{

-				IDirect3DCubeTexture9 *source;

-				IDirect3DCubeTexture9 *dest;

-

-				sourceTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&source);

-				destinationTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&dest);

-

-				ASSERT(source && dest);

-

-				for(int face = 0; face < 6; face++)

-				{

-					for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination

-					{

-						IDirect3DSurface9 *sourceSurface;

-						IDirect3DSurface9 *destinationSurface;

-

-						source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface);

-						dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface);

-

-						UpdateSurface(sourceSurface, 0, destinationSurface, 0);

-

-						sourceSurface->Release();

-						destinationSurface->Release();

-					}

-				}

-

-				source->Release();

-				dest->Release();

-			}

-			break;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::ValidateDevice(unsigned long *numPasses)

-	{

-		CriticalSection cs(this);

-

-		TRACE("unsigned long *numPasses = 0x%0.8p", numPasses);

-

-		if(!numPasses)

-		{

-			return INVALIDCALL();

-		}

-

-		*numPasses = 1;

-

-		return D3D_OK;

-	}

-

-	long Direct3DDevice9::getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)

-	{

-		return d3d9->GetAdapterDisplayMode(adapter, mode);

-	}

-

-	int Direct3DDevice9::typeStride(unsigned char streamType)

-	{

-		static int LUT[] =

-		{

-			4,	// D3DDECLTYPE_FLOAT1    =  0,  // 1D float expanded to (value, 0., 0., 1.)

-			8,	// D3DDECLTYPE_FLOAT2    =  1,  // 2D float expanded to (value, value, 0., 1.)

-			12,	// D3DDECLTYPE_FLOAT3    =  2,  // 3D float expanded to (value, value, value, 1.)

-			16,	// D3DDECLTYPE_FLOAT4    =  3,  // 4D float

-			4,	// D3DDECLTYPE_D3DCOLOR  =  4,  // 4D packed unsigned bytes mapped to 0. to 1. range. Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)

-			4,	// D3DDECLTYPE_UBYTE4    =  5,  // 4D unsigned byte

-			4,	// D3DDECLTYPE_SHORT2    =  6,  // 2D signed short expanded to (value, value, 0., 1.)

-			8,	// D3DDECLTYPE_SHORT4    =  7,  // 4D signed short

-			4,	// D3DDECLTYPE_UBYTE4N   =  8,  // Each of 4 bytes is normalized by dividing to 255.0

-			4,	// D3DDECLTYPE_SHORT2N   =  9,  // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)

-			8,	// D3DDECLTYPE_SHORT4N   = 10,  // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)

-			4,	// D3DDECLTYPE_USHORT2N  = 11,  // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)

-			8,	// D3DDECLTYPE_USHORT4N  = 12,  // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)

-			4,	// D3DDECLTYPE_UDEC3     = 13,  // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)

-			4,	// D3DDECLTYPE_DEC3N     = 14,  // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)

-			4,	// D3DDECLTYPE_FLOAT16_2 = 15,  // Two 16-bit floating point values, expanded to (value, value, 0, 1)

-			8,	// D3DDECLTYPE_FLOAT16_4 = 16,  // Four 16-bit floating point values

-			0,	// D3DDECLTYPE_UNUSED    = 17,  // When the type field in a decl is unused.

-		};

-

-		return LUT[streamType];

-	}

-

-	bool Direct3DDevice9::instanceData()

-	{

-		ASSERT(vertexDeclaration);

-

-		D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];

-		unsigned int numElements;

-		vertexDeclaration->GetDeclaration(vertexElement, &numElements);

-

-		bool instanceData = false;

-

-		for(unsigned int i = 0; i < numElements - 1; i++)

-		{

-			unsigned short stream = vertexElement[i].Stream;

-

-			if(stream != 0)

-			{

-				instanceData = instanceData || (streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA) != 0;

-			}

-		}

-

-		return instanceData;

-	}

-

-	bool Direct3DDevice9::bindResources(Direct3DIndexBuffer9 *indexBuffer)

-	{

-		if(!bindViewport())

-		{

-			return false;   // Zero-area target region

-		}

-

-		bindTextures();

-		bindIndexBuffer(indexBuffer);

-		bindShaderConstants();

-		bindLights();

-

-		return true;

-	}

-

-	void Direct3DDevice9::bindVertexStreams(int base, bool instancing, int instance)

-	{

-		ASSERT(vertexDeclaration);

-

-		renderer->resetInputStreams(vertexDeclaration->isPreTransformed());

-

-		D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];

-		unsigned int numElements;

-		vertexDeclaration->GetDeclaration(vertexElement, &numElements);

-

-		// Bind vertex data streams

-		for(unsigned int i = 0; i < numElements - 1; i++)

-		{

-			unsigned short stream = vertexElement[i].Stream;

-			unsigned short offset = vertexElement[i].Offset;

-			unsigned char type = vertexElement[i].Type;

-			unsigned char method = vertexElement[i].Method;

-			unsigned char usage = vertexElement[i].Usage;

-			unsigned char index = vertexElement[i].UsageIndex;

-

-			ASSERT(method == D3DDECLMETHOD_DEFAULT);	// FIXME: Unimplemented

-

-			if(!dataStream[stream])

-			{

-				continue;

-			}

-

-			Direct3DVertexBuffer9 *streamBuffer = dataStream[stream];

-			sw::Resource *resource = streamBuffer->getResource();

-			const void *buffer = ((char*)resource->data() + streamOffset[stream]) + offset;

-

-			int stride = streamStride[stream];

-

-			if(instancing && streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA)

-			{

-				int instanceFrequency = streamSourceFreq[stream] & ~D3DSTREAMSOURCE_INSTANCEDATA;

-				buffer = (char*)buffer + stride * (instance / instanceFrequency);

-

-				stride = 0;

-			}

-			else

-			{

-				buffer = (char*)buffer + stride * base;

-			}

-

-			sw::Stream attribute(resource, buffer, stride);

-

-			switch(type)

-			{

-			case D3DDECLTYPE_FLOAT1:    attribute.define(sw::STREAMTYPE_FLOAT, 1, false);  break;

-			case D3DDECLTYPE_FLOAT2:    attribute.define(sw::STREAMTYPE_FLOAT, 2, false);  break;

-			case D3DDECLTYPE_FLOAT3:    attribute.define(sw::STREAMTYPE_FLOAT, 3, false);  break;

-			case D3DDECLTYPE_FLOAT4:    attribute.define(sw::STREAMTYPE_FLOAT, 4, false);  break;

-			case D3DDECLTYPE_D3DCOLOR:  attribute.define(sw::STREAMTYPE_COLOR, 4, false);  break;

-			case D3DDECLTYPE_UBYTE4:    attribute.define(sw::STREAMTYPE_BYTE, 4, false);   break;

-			case D3DDECLTYPE_SHORT2:    attribute.define(sw::STREAMTYPE_SHORT, 2, false);  break;

-			case D3DDECLTYPE_SHORT4:    attribute.define(sw::STREAMTYPE_SHORT, 4, false);  break;

-			case D3DDECLTYPE_UBYTE4N:   attribute.define(sw::STREAMTYPE_BYTE, 4, true);    break;

-			case D3DDECLTYPE_SHORT2N:   attribute.define(sw::STREAMTYPE_SHORT, 2, true);   break;

-			case D3DDECLTYPE_SHORT4N:   attribute.define(sw::STREAMTYPE_SHORT, 4, true);   break;

-			case D3DDECLTYPE_USHORT2N:  attribute.define(sw::STREAMTYPE_USHORT, 2, true);  break;

-			case D3DDECLTYPE_USHORT4N:  attribute.define(sw::STREAMTYPE_USHORT, 4, true);  break;

-			case D3DDECLTYPE_UDEC3:     attribute.define(sw::STREAMTYPE_UDEC3, 3, false);  break;

-			case D3DDECLTYPE_DEC3N:     attribute.define(sw::STREAMTYPE_DEC3N, 3, true);   break;

-			case D3DDECLTYPE_FLOAT16_2: attribute.define(sw::STREAMTYPE_HALF, 2, false);   break;

-			case D3DDECLTYPE_FLOAT16_4: attribute.define(sw::STREAMTYPE_HALF, 4, false);   break;

-			case D3DDECLTYPE_UNUSED:    attribute.defaults();                              break;

-			default:

-				ASSERT(false);

-			}

-

-			if(vertexShader)

-			{

-				const sw::VertexShader *shader = vertexShader->getVertexShader();

-

-				if(!vertexDeclaration->isPreTransformed())

-				{

-					for(int i = 0; i < 16; i++)

-					{

-						if(usage == shader->input[i].usage &&

-						   index == shader->input[i].index)

-						{

-							renderer->setInputStream(i, attribute);

-

-							break;

-						}

-					}

-				}

-				else   // Bind directly to the output

-				{

-					for(int i = 0; i < 12; i++)

-					{

-						if((usage == shader->output[i][0].usage || (usage == D3DDECLUSAGE_POSITIONT && shader->output[i][0].usage == D3DDECLUSAGE_POSITION)) &&

-						    index == shader->output[i][0].index)

-						{

-							renderer->setInputStream(i, attribute);

-

-							break;

-						}

-					}

-				}

-			}

-			else

-			{

-				switch(usage)

-				{

-				case D3DDECLUSAGE_POSITION:     renderer->setInputStream(sw::Position, attribute);                                       break;

-				case D3DDECLUSAGE_BLENDWEIGHT:  renderer->setInputStream(sw::BlendWeight, attribute);                                    break;

-				case D3DDECLUSAGE_BLENDINDICES: renderer->setInputStream(sw::BlendIndices, attribute.define(sw::STREAMTYPE_INDICES, 1)); break;

-				case D3DDECLUSAGE_NORMAL:       renderer->setInputStream(sw::Normal, attribute.define(sw::STREAMTYPE_FLOAT, 3));         break;

-				case D3DDECLUSAGE_PSIZE:        renderer->setInputStream(sw::PointSize, attribute.define(sw::STREAMTYPE_FLOAT, 1));      break;

-				case D3DDECLUSAGE_TEXCOORD:     renderer->setInputStream(sw::TexCoord0 + index, attribute);                              break;

-				case D3DDECLUSAGE_TANGENT:      /* Ignored */                                                                            break;

-				case D3DDECLUSAGE_BINORMAL:     /* Ignored */                                                                            break;

-				case D3DDECLUSAGE_TESSFACTOR:   UNIMPLEMENTED();                                                                         break;

-				case D3DDECLUSAGE_POSITIONT:    renderer->setInputStream(sw::PositionT, attribute.define(sw::STREAMTYPE_FLOAT, 4));      break;

-				case D3DDECLUSAGE_COLOR:        renderer->setInputStream(sw::Color0 + index, attribute.define(sw::STREAMTYPE_COLOR, 4)); break;

-				case D3DDECLUSAGE_FOG:          /* Ignored */                                                                            break;

-				case D3DDECLUSAGE_DEPTH:        /* Ignored */                                                                            break;

-				case D3DDECLUSAGE_SAMPLE:       UNIMPLEMENTED();                                                                         break;

-				default:

-					ASSERT(false);

-				}

-			}

-		}

-	}

-

-	void Direct3DDevice9::bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer)

-	{

-		sw::Resource *resource = 0;

-

-		if(indexBuffer)

-		{

-			resource = indexBuffer->getResource();

-		}

-

-		renderer->setIndexBuffer(resource);

-	}

-

-	void Direct3DDevice9::bindShaderConstants()

-	{

-		if(pixelShaderDirty)

-		{

-			if(pixelShader)

-			{

-				if(pixelShaderConstantsBDirty)

-				{

-					renderer->setPixelShaderConstantB(0, pixelShaderConstantB, pixelShaderConstantsBDirty);

-				}

-

-				if(pixelShaderConstantsFDirty)

-				{

-					renderer->setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);

-				}

-

-				if(pixelShaderConstantsIDirty)

-				{

-					renderer->setPixelShaderConstantI(0, pixelShaderConstantI[0], pixelShaderConstantsIDirty);

-				}

-

-				renderer->setPixelShader(pixelShader->getPixelShader());   // Loads shader constants set with DEF

-				pixelShaderConstantsBDirty = pixelShader->getPixelShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty

-				pixelShaderConstantsFDirty = pixelShader->getPixelShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty

-				pixelShaderConstantsIDirty = pixelShader->getPixelShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty

-			}

-			else

-			{

-				renderer->setPixelShader(0);

-			}

-

-			pixelShaderDirty = false;

-		}

-

-		if(vertexShaderDirty)

-		{

-			if(vertexShader)

-			{

-				if(vertexShaderConstantsBDirty)

-				{

-					renderer->setVertexShaderConstantB(0, vertexShaderConstantB, vertexShaderConstantsBDirty);

-				}

-

-				if(vertexShaderConstantsFDirty)

-				{

-					renderer->setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);

-				}

-

-				if(vertexShaderConstantsIDirty)

-				{

-					renderer->setVertexShaderConstantI(0, vertexShaderConstantI[0], vertexShaderConstantsIDirty);

-				}

-

-				renderer->setVertexShader(vertexShader->getVertexShader());   // Loads shader constants set with DEF

-				vertexShaderConstantsBDirty = vertexShader->getVertexShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty

-				vertexShaderConstantsFDirty = vertexShader->getVertexShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty

-				vertexShaderConstantsIDirty = vertexShader->getVertexShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty

-			}

-			else

-			{

-				renderer->setVertexShader(0);

-			}

-

-			vertexShaderDirty = false;

-		}

-	}

-

-	void Direct3DDevice9::bindLights()

-	{

-		if(!lightsDirty) return;

-

-		Lights::iterator i = light.begin();

-		int active = 0;

-

-		// Set and enable renderer lights

-		while(active < 8)

-		{

-			while(i != light.end() && !i->second.enable)

-			{

-				i++;

-			}

-

-			if(i == light.end())

-			{

-				break;

-			}

-

-			const Light &l = i->second;

-

-			sw::Point position(l.Position.x, l.Position.y, l.Position.z);

-			sw::Color<float> diffuse(l.Diffuse.r, l.Diffuse.g, l.Diffuse.b, l.Diffuse.a);

-			sw::Color<float> specular(l.Specular.r, l.Specular.g, l.Specular.b, l.Specular.a);

-			sw::Color<float> ambient(l.Ambient.r, l.Ambient.g, l.Ambient.b, l.Ambient.a);

-			sw::Vector direction(l.Direction.x, l.Direction.y, l.Direction.z);

-

-			renderer->setLightDiffuse(active, diffuse);

-			renderer->setLightSpecular(active, specular);

-			renderer->setLightAmbient(active, ambient);

-

-			if(l.Type == D3DLIGHT_DIRECTIONAL)

-			{

-				// FIXME: Unsupported, make it a positional light far away without falloff

-				renderer->setLightPosition(active, -1e10f * direction);

-				renderer->setLightRange(active, l.Range);

-				renderer->setLightAttenuation(active, 1, 0, 0);

-			}

-			else if(l.Type == D3DLIGHT_SPOT)

-			{

-				// FIXME: Unsupported, make it a positional light

-				renderer->setLightPosition(active, position);

-				renderer->setLightRange(active, l.Range);

-				renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);

-			}

-			else

-			{

-				renderer->setLightPosition(active, position);

-				renderer->setLightRange(active, l.Range);

-				renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);

-			}

-

-			renderer->setLightEnable(active, true);

-

-			active++;

-			i++;

-		}

-

-		// Remaining lights are disabled

-		while(active < 8)

-		{

-			renderer->setLightEnable(active, false);

-

-			active++;

-		}

-

-		lightsDirty = false;

-	}

-

-	bool Direct3DDevice9::bindViewport()

-	{

-		if(viewport.Width <= 0 || viewport.Height <= 0)

-		{

-			return false;

-		}

-

-		if(scissorEnable)

-		{

-			if(scissorRect.left >= scissorRect.right || scissorRect.top >= scissorRect.bottom)

-			{

-				return false;

-			}

-

-			sw::Rect scissor;

-			scissor.x0 = scissorRect.left;

-			scissor.x1 = scissorRect.right;

-			scissor.y0 = scissorRect.top;

-			scissor.y1 = scissorRect.bottom;

-

-			renderer->setScissor(scissor);

-		}

-		else

-		{

-			sw::Rect scissor;

-			scissor.x0 = viewport.X;

-			scissor.x1 = viewport.X + viewport.Width;

-			scissor.y0 = viewport.Y;

-			scissor.y1 = viewport.Y + viewport.Height;

-

-			renderer->setScissor(scissor);

-		}

-

-		sw::Viewport view;

-		view.x0 = (float)viewport.X;

-		view.y0 = (float)viewport.Y + viewport.Height;

-		view.width = (float)viewport.Width;

-		view.height = -(float)viewport.Height;

-		view.minZ = viewport.MinZ;

-		view.maxZ = viewport.MaxZ;

-

-		renderer->setViewport(view);

-

-		return true;

-	}

-

-	void Direct3DDevice9::bindTextures()

-	{

-		for(int sampler = 0; sampler < 16 + 4; sampler++)

-		{

-			Direct3DBaseTexture9 *baseTexture = texture[sampler];

-

-			sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;

-			int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group

-

-			bool textureUsed = false;

-

-			if(type == sw::SAMPLER_PIXEL && pixelShader)

-			{

-				textureUsed = pixelShader->getPixelShader()->usesSampler(index);

-			}

-			else if(type == sw::SAMPLER_VERTEX && vertexShader)

-			{

-				textureUsed = vertexShader->getVertexShader()->usesSampler(index);

-			}

-			else

-			{

-				textureUsed = true;   // FIXME: Check fixed-function use?

-			}

-

-			sw::Resource *resource = 0;

-

-			if(baseTexture && textureUsed)

-			{

-				resource = baseTexture->getResource();

-			}

-

-			renderer->setTextureResource(sampler, resource);

-

-			if(baseTexture && textureUsed)

-			{

-				baseTexture->GenerateMipSubLevels();

-			}

-

-			if(baseTexture && textureUsed)

-			{

-				int levelCount = baseTexture->getInternalLevelCount();

-

-				int textureLOD = baseTexture->GetLOD();

-				int samplerLOD = samplerState[sampler][D3DSAMP_MAXMIPLEVEL];

-				int LOD = textureLOD > samplerLOD ? textureLOD : samplerLOD;

-

-				if(samplerState[sampler][D3DSAMP_MIPFILTER] == D3DTEXF_NONE)

-				{

-					LOD = 0;

-				}

-

-				switch(baseTexture->GetType())

-				{

-				case D3DRTYPE_TEXTURE:

-					{

-						Direct3DTexture9 *texture = dynamic_cast<Direct3DTexture9*>(baseTexture);

-						Direct3DSurface9 *surface;

-

-						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-						{

-							int surfaceLevel = mipmapLevel;

-

-							if(surfaceLevel < LOD)

-							{

-								surfaceLevel = LOD;

-							}

-

-							if(surfaceLevel < 0)

-							{

-								surfaceLevel = 0;

-							}

-							else if(surfaceLevel >= levelCount)

-							{

-								surfaceLevel = levelCount - 1;

-							}

-

-							surface = texture->getInternalSurfaceLevel(surfaceLevel);

-							renderer->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);

-						}

-					}

-					break;

-				case D3DRTYPE_CUBETEXTURE:

-					for(int face = 0; face < 6; face++)

-					{

-						Direct3DCubeTexture9 *cubeTexture = dynamic_cast<Direct3DCubeTexture9*>(baseTexture);

-						Direct3DSurface9 *surface;

-

-						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-						{

-							int surfaceLevel = mipmapLevel;

-

-							if(surfaceLevel < LOD)

-							{

-								surfaceLevel = LOD;

-							}

-

-							if(surfaceLevel < 0)

-							{

-								surfaceLevel = 0;

-							}

-							else if(surfaceLevel >= levelCount)

-							{

-								surfaceLevel = levelCount - 1;

-							}

-

-							surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel);

-							renderer->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);

-						}

-					}

-					break;

-				case D3DRTYPE_VOLUMETEXTURE:

-					{

-						Direct3DVolumeTexture9 *volumeTexture = dynamic_cast<Direct3DVolumeTexture9*>(baseTexture);

-						Direct3DVolume9 *volume;

-

-						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-						{

-							int surfaceLevel = mipmapLevel;

-

-							if(surfaceLevel < LOD)

-							{

-								surfaceLevel = LOD;

-							}

-

-							if(surfaceLevel < 0)

-							{

-								surfaceLevel = 0;

-							}

-							else if(surfaceLevel >= levelCount)

-							{

-								surfaceLevel = levelCount - 1;

-							}

-

-							volume = volumeTexture->getInternalVolumeLevel(surfaceLevel);

-							renderer->setTextureLevel(sampler, 0, mipmapLevel, volume, sw::TEXTURE_3D);

-						}

-					}

-					break;

-				default:

-					UNIMPLEMENTED();

-				}

-			}

-			else

-			{

-				renderer->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);

-			}

-		}

-	}

-

-	bool Direct3DDevice9::isRecording() const

-	{

-		return stateRecorder != 0;

-	}

-

-	void Direct3DDevice9::setOcclusionEnabled(bool enable)

-	{

-		renderer->setOcclusionEnabled(enable);

-	}

-

-	void Direct3DDevice9::removeQuery(sw::Query *query)

-	{

-		renderer->removeQuery(query);

-	}

-

-	void Direct3DDevice9::addQuery(sw::Query *query)

-	{

-		renderer->addQuery(query);

-	}

-

-	void Direct3DDevice9::stretchRect(Direct3DSurface9 *source, const RECT *sourceRect, Direct3DSurface9 *dest, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)

-	{

-		D3DSURFACE_DESC sourceDescription;

-		D3DSURFACE_DESC destDescription;

-

-		source->GetDesc(&sourceDescription);

-		dest->GetDesc(&destDescription);

-

-		int sWidth = source->getWidth();

-		int sHeight = source->getHeight();

-		int dWidth = dest->getWidth();

-		int dHeight = dest->getHeight();

-

-		sw::Rect sRect(0, 0, sWidth, sHeight);

-		sw::Rect dRect(0, 0, dWidth, dHeight);

-

-		if(sourceRect)

-		{

-			sRect.x0 = sourceRect->left;

-			sRect.y0 = sourceRect->top;

-			sRect.x1 = sourceRect->right;

-			sRect.y1 = sourceRect->bottom;

-		}

-

-		if(destRect)

-		{

-			dRect.x0 = destRect->left;

-			dRect.y0 = destRect->top;

-			dRect.x1 = destRect->right;

-			dRect.y1 = destRect->bottom;

-		}

-

-		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);

-		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();

-		bool depthStencil = (sourceDescription.Usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL;

-		bool alpha0xFF = false;

-

-		if((sourceDescription.Format == D3DFMT_A8R8G8B8 && destDescription.Format == D3DFMT_X8R8G8B8) ||

-		   (sourceDescription.Format == D3DFMT_X8R8G8B8 && destDescription.Format == D3DFMT_A8R8G8B8))

-		{

-			equalFormats = true;

-			alpha0xFF = true;

-		}

-

-		if(depthStencil)   // Copy entirely, internally   // FIXME: Check

-		{

-			if(source->hasDepth())

-			{

-				byte *sourceBuffer = (byte*)source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-				byte *destBuffer = (byte*)dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getInternalPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockInternal();

-				dest->unlockInternal();

-			}

-

-			if(source->hasStencil())

-			{

-				byte *sourceBuffer = (byte*)source->lockStencil(0, sw::PUBLIC);

-				byte *destBuffer = (byte*)dest->lockStencil(0, sw::PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getStencilPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockStencil();

-				dest->unlockStencil();

-			}

-		}

-		else if(!scaling && equalFormats)

-		{

-			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, 0, sw::LOCK_READWRITE, sw::PUBLIC);

-			unsigned int sourcePitch = source->getInternalPitchB();

-			unsigned int destPitch = dest->getInternalPitchB();

-

-			unsigned int width = dRect.x1 - dRect.x0;

-			unsigned int height = dRect.y1 - dRect.y0;

-			unsigned int bytes = width * sw::Surface::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

-		{

-			renderer->blit(source, sRect, dest, dRect, filter >= D3DTEXF_LINEAR);

-		}

-	}

-

-	long Direct3DDevice9::updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume)

-	{

-		TRACE("IDirect3DVolume9 *sourceVolume = 0x%0.8p, IDirect3DVolume9 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume);

-

-		if(!sourceVolume || !destinationVolume)

-		{

-			return INVALIDCALL();

-		}

-

-		D3DVOLUME_DESC sourceDescription;

-		D3DVOLUME_DESC destinationDescription;

-

-		sourceVolume->GetDesc(&sourceDescription);

-		destinationVolume->GetDesc(&destinationDescription);

-

-		if(sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||

-		   destinationDescription.Pool != D3DPOOL_DEFAULT ||

-		   sourceDescription.Format != destinationDescription.Format ||

-		   sourceDescription.Width  != destinationDescription.Width ||

-		   sourceDescription.Height != destinationDescription.Height ||

-		   sourceDescription.Depth  != destinationDescription.Depth)

-		{

-			return INVALIDCALL();

-		}

-

-		sw::Surface *source = static_cast<Direct3DVolume9*>(sourceVolume);

-		sw::Surface *dest = static_cast<Direct3DVolume9*>(destinationVolume);

-

-		if(source->getExternalPitchB() != dest->getExternalPitchB() ||

-		   source->getExternalSliceB() != dest->getExternalSliceB())

-		{

-			UNIMPLEMENTED();

-		}

-

-		void *sBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-		void *dBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);

-

-		memcpy(dBuffer, sBuffer, source->getExternalSliceB() * sourceDescription.Depth);

-

-		source->unlockExternal();

-		dest->unlockExternal();

-

-		return D3D_OK;

-	}

-

-	bool Direct3DDevice9::validRectangle(const RECT *rect, IDirect3DSurface9 *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;

-		}

-

-		D3DSURFACE_DESC description;

-		surface->GetDesc(&description);

-

-		if(rect->right > (int)description.Width || rect->bottom > (int)description.Height)

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	void Direct3DDevice9::configureFPU()

-	{

-	//	_controlfp(_PC_24, _MCW_PC);     // Single-precision

-		_controlfp(_MCW_EM, _MCW_EM);    // Mask all exceptions

-		_controlfp(_RC_NEAR, _MCW_RC);   // Round to nearest

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Direct3DDevice9.hpp"
+
+#include "Direct3D9.hpp"
+#include "Direct3DSurface9.hpp"
+#include "Direct3DIndexBuffer9.hpp"
+#include "Direct3DVertexBuffer9.hpp"
+#include "Direct3DTexture9.hpp"
+#include "Direct3DVolumeTexture9.hpp"
+#include "Direct3DCubeTexture9.hpp"
+#include "Direct3DVertexDeclaration9.hpp"
+#include "Direct3DSwapChain9.hpp"
+#include "Direct3DPixelShader9.hpp"
+#include "Direct3DVertexShader9.hpp"
+#include "Direct3DStateBlock9.hpp"
+#include "Direct3DQuery9.hpp"
+#include "Direct3DVolume9.hpp"
+
+#include "Debug.hpp"
+#include "Capabilities.hpp"
+#include "Math.hpp"
+#include "Renderer.hpp"
+#include "Config.hpp"
+#include "FrameBuffer.hpp"
+#include "Clipper.hpp"
+#include "Configurator.hpp"
+#include "Timer.hpp"
+#include "Resource.hpp"
+
+#include <assert.h>
+
+bool localShaderConstants = true;
+
+namespace D3D9
+{
+	inline unsigned long FtoDW(float f)
+	{
+		return (unsigned long&)f;
+	}
+
+	Direct3DDevice9::Direct3DDevice9(const HINSTANCE instance, Direct3D9 *d3d9, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters) : instance(instance), adapter(adapter), d3d9(d3d9), deviceType(deviceType), focusWindow(focusWindow), behaviourFlags(behaviourFlags)
+	{
+		InitializeCriticalSection(&criticalSection);
+
+		init = true;
+		stateRecorder = 0;
+
+		d3d9->AddRef();
+
+		context = new sw::Context();
+		renderer = new sw::Renderer(context, sw::Direct3D, false);
+
+		swapChain = 0;
+		depthStencil = 0;
+		autoDepthStencil = 0;
+		renderTarget[0] = 0;
+		renderTarget[1] = 0;
+		renderTarget[2] = 0;
+		renderTarget[3] = 0;
+
+		for(int i = 0; i < 16 + 4; i++)
+		{
+			texture[i] = 0;
+		}
+
+		cursor = 0;
+
+		Reset(presentParameters);
+
+		pixelShader = 0;
+		vertexShader = 0;
+
+		lightsDirty = true;
+		pixelShaderDirty = true;
+		pixelShaderConstantsBDirty = 0;
+		pixelShaderConstantsFDirty = 0;
+		pixelShaderConstantsIDirty = 0;
+		vertexShaderDirty = true;
+		vertexShaderConstantsBDirty = 0;
+		vertexShaderConstantsFDirty = 0;
+		vertexShaderConstantsIDirty = 0;
+
+		for(int i = 0; i < 16; i++)
+		{
+			dataStream[i] = 0;
+			streamStride[i] = 0;
+			streamOffset[i] = 0;
+
+			streamSourceFreq[i] = 1;
+		}
+
+		indexData = 0;
+		vertexDeclaration = 0;
+
+		D3DMATERIAL9 material;
+
+		material.Diffuse.r = 1.0f;
+		material.Diffuse.g = 1.0f;
+		material.Diffuse.b = 1.0f;
+		material.Diffuse.a = 0.0f;
+		material.Ambient.r = 0.0f;
+		material.Ambient.g = 0.0f;
+		material.Ambient.b = 0.0f;
+		material.Ambient.a = 0.0f;
+		material.Emissive.r = 0.0f;
+		material.Emissive.g = 0.0f;
+		material.Emissive.b = 0.0f;
+		material.Emissive.a = 0.0f;
+		material.Specular.r = 0.0f;
+		material.Specular.g = 0.0f;
+		material.Specular.b = 0.0f;
+		material.Specular.a = 0.0f;
+		material.Power = 0.0f;
+
+		SetMaterial(&material);
+
+		D3DMATRIX identity = {1, 0, 0, 0,
+		                      0, 1, 0, 0,
+		                      0, 0, 1, 0,
+		                      0, 0, 0, 1};
+
+		SetTransform(D3DTS_VIEW, &identity);
+		SetTransform(D3DTS_PROJECTION, &identity);
+		SetTransform(D3DTS_TEXTURE0, &identity);
+		SetTransform(D3DTS_TEXTURE1, &identity);
+		SetTransform(D3DTS_TEXTURE2, &identity);
+		SetTransform(D3DTS_TEXTURE3, &identity);
+		SetTransform(D3DTS_TEXTURE4, &identity);
+		SetTransform(D3DTS_TEXTURE5, &identity);
+		SetTransform(D3DTS_TEXTURE6, &identity);
+		SetTransform(D3DTS_TEXTURE7, &identity);
+
+		for(int i = 0; i < 12; i++)
+		{
+			SetTransform(D3DTS_WORLDMATRIX(i), &identity);
+		}
+
+		for(int i = 0; i < MAX_PIXEL_SHADER_CONST; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			SetPixelShaderConstantF(i, zero, 1);
+		}
+
+		for(int i = 0; i < MAX_VERTEX_SHADER_CONST; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			SetVertexShaderConstantF(i, zero, 1);
+		}
+
+		for(int i = 0; i < 16; i++)
+		{
+			int zero[4] = {0, 0, 0, 0};
+
+			SetPixelShaderConstantI(i, zero, 1);
+			SetVertexShaderConstantI(i, zero, 1);
+			SetPixelShaderConstantB(i, &zero[0], 1);
+			SetVertexShaderConstantB(i, &zero[0], 1);
+		}
+
+		init = false;
+
+		if(!(behaviourFlags & D3DCREATE_FPU_PRESERVE))
+		{
+			configureFPU();
+		}
+
+		instancingEnabled = pixelShaderVersionX >= D3DPS_VERSION(3, 0);
+	}
+
+	Direct3DDevice9::~Direct3DDevice9()
+	{
+		delete renderer;
+		renderer = 0;
+		delete context;
+		context = 0;
+
+		d3d9->Release();
+		d3d9 = 0;
+
+		swapChain->unbind();
+		swapChain = 0;
+
+		if(depthStencil)
+		{
+			depthStencil->unbind();
+			depthStencil = 0;
+		}
+
+		if(autoDepthStencil)
+		{
+			autoDepthStencil->unbind();
+			autoDepthStencil = 0;
+		}
+
+		for(int index = 0; index < 4; index++)
+		{
+			if(renderTarget[index])
+			{
+				renderTarget[index]->unbind();
+				renderTarget[index] = 0;
+			}
+		}
+
+		if(vertexDeclaration)
+		{
+			vertexDeclaration->unbind();
+			vertexDeclaration = 0;
+		}
+
+		for(int i = 0; i < 16 + 4; i++)
+		{
+			if(texture[i])
+			{
+				texture[i]->unbind();
+				texture[i] = 0;
+			}
+		}
+
+		for(int i = 0; i < 16; i++)
+		{
+			if(dataStream[i])
+			{
+				dataStream[i]->unbind();
+				dataStream[i] = 0;
+			}
+		}
+
+		if(indexData)
+		{
+			indexData->unbind();
+			indexData = 0;
+		}
+
+		if(pixelShader)
+		{
+			pixelShader->unbind();
+			pixelShader = 0;
+		}
+
+		if(vertexShader)
+		{
+			vertexShader->unbind();
+			vertexShader = 0;
+		}
+
+		if(stateRecorder)
+		{
+			stateRecorder->unbind();
+			stateRecorder = 0;
+		}
+
+		palette.clear();
+
+		delete cursor;
+
+		DeleteCriticalSection(&criticalSection);
+	}
+
+	long Direct3DDevice9::QueryInterface(const IID &iid, void **object)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
+
+		if(iid == IID_IDirect3DDevice9 ||
+		   iid == IID_IUnknown)
+		{
+			AddRef();
+			*object = this;
+
+			return S_OK;
+		}
+
+		*object = 0;
+
+		return NOINTERFACE(iid);
+	}
+
+	unsigned long Direct3DDevice9::AddRef()
+	{
+		TRACE("void");
+
+		return Unknown::AddRef();
+	}
+
+	unsigned long Direct3DDevice9::Release()
+	{
+		TRACE("void");
+
+		return Unknown::Release();
+	}
+
+	long Direct3DDevice9::BeginScene()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::BeginStateBlock()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		if(stateRecorder)
+		{
+			return INVALIDCALL();
+		}
+
+		stateRecorder = new Direct3DStateBlock9(this, (D3DSTATEBLOCKTYPE)0);
+
+		if(!stateRecorder)
+		{
+			return OUTOFMEMORY();
+		}
+
+		stateRecorder->bind();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long count = %d, const D3DRECT *rects = 0x%0.8p, unsigned long flags = 0x%0.8X, unsigned long color = 0x%0.8X, float z = %f, unsigned long stencil = %d", count, rects, flags, color, z, stencil);
+
+		if(rects == 0 && count != 0)
+		{
+			return INVALIDCALL();
+		}
+
+		if(flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) && !depthStencil)
+		{
+			return INVALIDCALL();
+		}
+
+		if(flags & D3DCLEAR_STENCIL)   // Check for stencil component
+		{
+			D3DSURFACE_DESC description;
+			depthStencil->GetDesc(&description);
+
+			switch(description.Format)
+			{
+			case D3DFMT_D15S1:
+			case D3DFMT_D24S8:
+			case D3DFMT_D24X8:
+			case D3DFMT_D24X4S4:
+			case D3DFMT_D24FS8:
+			case D3DFMT_S8_LOCKABLE:   // FIXME: INVALIDCALL when trying to clear depth?
+			case D3DFMT_DF24:
+			case D3DFMT_DF16:
+			case D3DFMT_INTZ:
+				break;
+			case D3DFMT_D16_LOCKABLE:
+			case D3DFMT_D32:
+			case D3DFMT_D16:
+			case D3DFMT_D32F_LOCKABLE:
+			case D3DFMT_D32_LOCKABLE:
+				return INVALIDCALL();
+			default:
+				ASSERT(false);
+			}
+		}
+
+		if(!rects)
+		{
+			count = 1;
+
+			D3DRECT rect;
+			rect.x1 = viewport.X;
+			rect.x2 = viewport.X + viewport.Width;
+			rect.y1 = viewport.Y;
+			rect.y2 = viewport.Y + viewport.Height;
+
+			rects = &rect;
+		}
+
+		for(unsigned int i = 0; i < count; i++)
+		{
+			sw::SliceRect clearRect(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2, 0);
+
+			clearRect.clip(viewport.X, viewport.Y, viewport.X + viewport.Width, viewport.Y + viewport.Height);
+
+			if(scissorEnable)
+			{
+				clearRect.clip(scissorRect.left, scissorRect.top, scissorRect.right, scissorRect.bottom);
+			}
+
+			if(flags & D3DCLEAR_TARGET)
+			{
+				for(int index = 0; index < 4; index++)
+				{
+					if(renderTarget[index])
+					{
+						D3DSURFACE_DESC description;
+						renderTarget[index]->GetDesc(&description);
+
+						float rgba[4];
+						rgba[0] = (float)(color & 0x00FF0000) / 0x00FF0000;
+						rgba[1] = (float)(color & 0x0000FF00) / 0x0000FF00;
+						rgba[2] = (float)(color & 0x000000FF) / 0x000000FF;
+						rgba[3] = (float)(color & 0xFF000000) / 0xFF000000;
+
+						if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format))
+						{
+							rgba[0] = sw::linearToSRGB(rgba[0]);
+							rgba[1] = sw::linearToSRGB(rgba[1]);
+							rgba[2] = sw::linearToSRGB(rgba[2]);
+						}
+
+						renderer->clear(rgba, sw::FORMAT_A32B32G32R32F, renderTarget[index], clearRect, 0xF);
+					}
+				}
+			}
+
+			if(flags & D3DCLEAR_ZBUFFER)
+			{
+				z = sw::clamp01(z);
+				depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+			}
+
+			if(flags & D3DCLEAR_STENCIL)
+			{
+				depthStencil->clearStencil(stencil, 0xFF, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+			}
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DSurface9 *surface = 0x%0.8p, const RECT *rect = 0x%0.8p, D3DCOLOR color = 0x%0.8X", surface, rect, color);
+
+		if(!surface)
+		{
+			return INVALIDCALL();
+		}
+
+		D3DSURFACE_DESC description;
+
+		surface->GetDesc(&description);
+
+		if(description.Pool != D3DPOOL_DEFAULT)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!rect)
+		{
+			RECT lock;
+
+			lock.left = 0;
+			lock.top = 0;
+			lock.right = description.Width;
+			lock.bottom = description.Height;
+
+			rect = &lock;
+		}
+
+		static_cast<Direct3DSurface9*>(surface)->fill(color, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DSwapChain9 **swapChain = 0x%0.8p", presentParameters, swapChain);
+
+		if(!swapChain)
+		{
+			return INVALIDCALL();
+		}
+
+		*swapChain = 0;
+
+		if(!presentParameters)
+		{
+			return INVALIDCALL();
+		}
+
+		if(presentParameters->BackBufferCount > 3)
+		{
+			return INVALIDCALL();   // Maximum of three back buffers
+		}
+
+		*swapChain = new Direct3DSwapChain9(this, presentParameters);
+
+		if(!*swapChain)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *swapChain;
+			*swapChain = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*swapChain)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int edgeLength = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DCubeTexture9 **cubeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", edgeLength, levels, usage, format, pool, cubeTexture, sharedHandle);
+
+		*cubeTexture = 0;
+
+		if(edgeLength == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_CUBETEXTURE, format) != D3D_OK)
+		{
+			return INVALIDCALL();
+		}
+
+		*cubeTexture = new Direct3DCubeTexture9(this, edgeLength, levels, usage, format, pool);
+
+		if(!*cubeTexture)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *cubeTexture;
+			*cubeTexture = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*cubeTexture)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int discard = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, discard, surface, sharedHandle);
+
+		*surface = 0;
+
+		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
+		{
+			return INVALIDCALL();
+		}
+
+		bool lockable = false;
+
+		switch(format)
+		{
+		case D3DFMT_D15S1:
+		case D3DFMT_D24S8:
+		case D3DFMT_D24X8:
+		case D3DFMT_D24X4S4:
+		case D3DFMT_D24FS8:
+		case D3DFMT_D32:
+		case D3DFMT_D16:
+		case D3DFMT_DF24:
+		case D3DFMT_DF16:
+		case D3DFMT_INTZ:
+			lockable = false;
+			break;
+		case D3DFMT_S8_LOCKABLE:
+		case D3DFMT_D16_LOCKABLE:
+		case D3DFMT_D32F_LOCKABLE:
+		case D3DFMT_D32_LOCKABLE:
+			lockable = true;
+			break;
+		default:
+			ASSERT(false);
+		}
+
+		*surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
+
+		if(!*surface)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *surface;
+			*surface = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*surface)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int length = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DIndexBuffer9 **indexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, format, pool, indexBuffer, sharedHandle);
+
+		*indexBuffer = new Direct3DIndexBuffer9(this, length, usage, format, pool);
+
+		if(!*indexBuffer)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *indexBuffer;
+			*indexBuffer = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*indexBuffer)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, pool, surface, sharedHandle);
+
+		*surface = 0;
+
+		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, format) != D3D_OK)   // FIXME: Allow all formats supported by runtime/REF
+		{
+			return INVALIDCALL();
+		}
+
+		if(pool == D3DPOOL_MANAGED)
+		{
+			return INVALIDCALL();
+		}
+
+		*surface = new Direct3DSurface9(this, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, true, 0);
+
+		if(!*surface)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *surface;
+			*surface = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*surface)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const unsigned long *function = 0x%0.8p, IDirect3DPixelShader9 **shader = 0x%0.8p", function, shader);
+
+		if(!shader)
+		{
+			return INVALIDCALL();
+		}
+
+		*shader = 0;
+
+		if(!sw::PixelShader::validate(function) || function[0] > pixelShaderVersionX)
+		{
+			return INVALIDCALL();   // Shader contains unsupported operations
+		}
+
+		*shader = new Direct3DPixelShader9(this, function);
+
+		if(!*shader)
+		{
+			return OUTOFMEMORY();
+		}
+
+		(*shader)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DQUERYTYPE type = %d, IDirect3DQuery9 **query = 0x%0.8p", type, query);
+
+		if(query == 0)   // Support checked
+		{
+			switch(type)
+			{
+			case D3DQUERYTYPE_VCACHE:				return D3D_OK;
+			case D3DQUERYTYPE_RESOURCEMANAGER:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_VERTEXSTATS:			return NOTAVAILABLE();
+			case D3DQUERYTYPE_EVENT:				return D3D_OK;
+			case D3DQUERYTYPE_OCCLUSION:			return D3D_OK;
+			case D3DQUERYTYPE_TIMESTAMP:			return D3D_OK;
+			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	return D3D_OK;
+			case D3DQUERYTYPE_TIMESTAMPFREQ:		return D3D_OK;
+			case D3DQUERYTYPE_PIPELINETIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_INTERFACETIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_VERTEXTIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_PIXELTIMINGS:			return NOTAVAILABLE();
+			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_CACHEUTILIZATION:		return NOTAVAILABLE();
+			default:								ASSERT(false);   return NOTAVAILABLE();
+			}
+		}
+		else
+		{
+			switch(type)
+			{
+			case D3DQUERYTYPE_VCACHE:				break;
+			case D3DQUERYTYPE_RESOURCEMANAGER:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_VERTEXSTATS:			return NOTAVAILABLE();
+			case D3DQUERYTYPE_EVENT:				break;
+			case D3DQUERYTYPE_OCCLUSION:			break;
+			case D3DQUERYTYPE_TIMESTAMP:			break;
+			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	break;
+			case D3DQUERYTYPE_TIMESTAMPFREQ:		break;
+			case D3DQUERYTYPE_PIPELINETIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_INTERFACETIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_VERTEXTIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_PIXELTIMINGS:			return NOTAVAILABLE();
+			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return NOTAVAILABLE();
+			case D3DQUERYTYPE_CACHEUTILIZATION:		return NOTAVAILABLE();
+			default:								ASSERT(false);   return NOTAVAILABLE();
+			}
+
+			*query = new Direct3DQuery9(this, type);
+
+			if(!*query)
+			{
+				return OUTOFMEMORY();
+			}
+
+			(*query)->AddRef();
+
+			return D3D_OK;
+		}
+	}
+
+	long Direct3DDevice9::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int lockable = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, lockable, surface, sharedHandle);
+
+		*surface = 0;
+
+		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
+		{
+			return INVALIDCALL();
+		}
+
+		*surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable != FALSE, D3DUSAGE_RENDERTARGET);
+
+		if(!*surface)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *surface;
+			*surface = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*surface)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DSTATEBLOCKTYPE type = %d, IDirect3DStateBlock9 **stateBlock = 0x%0.8p", type, stateBlock);
+
+		*stateBlock = new Direct3DStateBlock9(this, type);
+
+		if(!*stateBlock)
+		{
+			return OUTOFMEMORY();
+		}
+
+		(*stateBlock)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DTexture9 **texture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, levels, usage, format, pool, texture, sharedHandle);
+
+		*texture = 0;
+
+		if(width == 0 || height == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, format) != D3D_OK)
+		{
+			return INVALIDCALL();
+		}
+
+		*texture = new Direct3DTexture9(this, width, height, levels, usage, format, pool);
+
+		if(!*texture)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *texture;
+			*texture = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*texture)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int length = %d, unsigned long usage = %d, unsigned long FVF = 0x%0.8X, D3DPOOL pool = %d, IDirect3DVertexBuffer9 **vertexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, FVF, pool, vertexBuffer, sharedHandle);
+
+		*vertexBuffer = new Direct3DVertexBuffer9(this, length, usage, FVF, pool);
+
+		if(!*vertexBuffer)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *vertexBuffer;
+			*vertexBuffer = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*vertexBuffer)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const D3DVERTEXELEMENT9 *vertexElements = 0x%0.8p, IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", vertexElements, declaration);
+
+		if(!declaration)
+		{
+			return INVALIDCALL();
+		}
+
+		const D3DVERTEXELEMENT9 *element = vertexElements;
+
+		while(element->Stream != 0xFF)
+		{
+			if(element->Type > D3DDECLTYPE_UNUSED)   // FIXME: Check other fields too
+			{
+				return FAIL();
+			}
+
+			element++;
+		}
+
+		*declaration = new Direct3DVertexDeclaration9(this, vertexElements);
+
+		if(!*declaration)
+		{
+			return OUTOFMEMORY();
+		}
+
+		(*declaration)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const unsigned long *function = 0x%0.8p, IDirect3DVertexShader9 **shader = 0x%0.8p", function, shader);
+
+		if(!shader)
+		{
+			return INVALIDCALL();
+		}
+
+		*shader = 0;
+
+		if(!sw::VertexShader::validate(function) || function[0] > vertexShaderVersionX)
+		{
+			return INVALIDCALL();   // Shader contains unsupported operations
+		}
+
+		*shader = new Direct3DVertexShader9(this, function);
+
+		if(!*shader)
+		{
+			return OUTOFMEMORY();
+		}
+
+		(*shader)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int depth = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DVolumeTexture9 **volumeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, depth, levels, usage, format, pool, volumeTexture, sharedHandle);
+
+		*volumeTexture = 0;
+
+		if(width == 0 || height == 0 || depth == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_VOLUMETEXTURE, format) != D3D_OK)
+		{
+			return INVALIDCALL();
+		}
+
+		*volumeTexture = new Direct3DVolumeTexture9(this, width, height, depth, levels, usage, format, pool);
+
+		if(!*volumeTexture)
+		{
+			return OUTOFMEMORY();
+		}
+
+		if(GetAvailableTextureMem() == 0)
+		{
+			delete *volumeTexture;
+			*volumeTexture = 0;
+
+			return OUTOFVIDEOMEMORY();
+		}
+
+		(*volumeTexture)->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::DeletePatch(unsigned int handle)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int handle = %d", handle);
+
+		UNIMPLEMENTED();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DPRIMITIVETYPE type = %d, int baseVertexIndex = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int startIndex = %d, unsigned int primitiveCount = %d", type, baseVertexIndex, minIndex, numVertices, startIndex, primitiveCount);
+
+		if(!indexData)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!bindResources(indexData) || !primitiveCount)
+		{
+			return D3D_OK;
+		}
+
+		unsigned int indexOffset = startIndex * (indexData->is32Bit() ? 4 : 2);   // FIXME: Doesn't take stream frequencies into account
+
+		sw::DrawType drawType;
+
+		if(indexData->is32Bit())
+		{
+			switch(type)
+			{
+			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;
+			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;
+			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;
+			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;
+			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
+			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;   break;
+			default:
+				ASSERT(false);
+			}
+		}
+		else
+		{
+			switch(type)
+			{
+			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;
+			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;
+			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;
+			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;
+			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
+			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;
+			default:
+				ASSERT(false);
+			}
+		}
+
+		if((streamSourceFreq[0] & D3DSTREAMSOURCE_INDEXEDDATA) && instanceData())
+		{
+			int instanceCount = (streamSourceFreq[0] & ~D3DSTREAMSOURCE_INDEXEDDATA);
+
+			for(int instance = 0; instance < instanceCount; instance++)
+			{
+				bindVertexStreams(baseVertexIndex, true, instance);
+				renderer->draw(drawType, indexOffset, primitiveCount, instance == 0);
+			}
+		}
+		else
+		{
+			bindVertexStreams(baseVertexIndex, false, 0);
+			renderer->draw(drawType, indexOffset, primitiveCount);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int primitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DPRIMITIVETYPE type = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int primitiveCount = %d, const void *indexData = 0x%0.8p, D3DFORMAT indexDataFormat = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", type, minIndex, numVertices, primitiveCount, indexData, indexDataFormat, vertexStreamZeroData, vertexStreamZeroStride);
+
+		if(!vertexStreamZeroData || !indexData)
+		{
+			return INVALIDCALL();
+		}
+
+		int length = (minIndex + numVertices) * vertexStreamZeroStride;
+
+		Direct3DVertexBuffer9 *vertexBuffer = new Direct3DVertexBuffer9(this, length, 0, 0, D3DPOOL_DEFAULT);
+
+		void *data;
+		vertexBuffer->Lock(0, 0, &data, 0);
+		memcpy(data, vertexStreamZeroData, length);
+		vertexBuffer->Unlock();
+
+		SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
+
+		switch(type)
+		{
+		case D3DPT_POINTLIST:		length = primitiveCount;		break;
+		case D3DPT_LINELIST:		length = primitiveCount * 2;	break;
+		case D3DPT_LINESTRIP:		length = primitiveCount + 1;	break;
+		case D3DPT_TRIANGLELIST:	length = primitiveCount * 3;	break;
+		case D3DPT_TRIANGLESTRIP:	length = primitiveCount + 2;	break;
+		case D3DPT_TRIANGLEFAN:		length = primitiveCount + 2;	break;
+		default:
+			ASSERT(false);
+		}
+
+		length *= indexDataFormat == D3DFMT_INDEX32 ? 4 : 2;
+
+		Direct3DIndexBuffer9 *indexBuffer = new Direct3DIndexBuffer9(this, length, 0, indexDataFormat, D3DPOOL_DEFAULT);
+
+		indexBuffer->Lock(0, 0, &data, 0);
+		memcpy(data, indexData, length);
+		indexBuffer->Unlock();
+
+		SetIndices(indexBuffer);
+
+		if(!bindResources(indexBuffer) || !primitiveCount)
+		{
+			vertexBuffer->Release();
+
+			return D3D_OK;
+		}
+
+		sw::DrawType drawType;
+
+		if(indexDataFormat == D3DFMT_INDEX32)
+		{
+			switch(type)
+			{
+			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;
+			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;
+			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;
+			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;
+			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
+			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;   break;
+			default:
+				ASSERT(false);
+			}
+		}
+		else
+		{
+			switch(type)
+			{
+			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;
+			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;
+			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;
+			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;
+			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
+			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;
+			default:
+				ASSERT(false);
+			}
+		}
+
+		bindVertexStreams(0, false, 0);
+		renderer->draw(drawType, 0, primitiveCount);
+
+		SetStreamSource(0, 0, 0, 0);
+		SetIndices(0);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int startVertex = %d, unsigned int primitiveCount = %d", primitiveType, startVertex, primitiveCount);
+
+		if(!bindResources(0) || !primitiveCount)
+		{
+			return D3D_OK;
+		}
+
+		sw::DrawType drawType;
+
+		switch(primitiveType)
+		{
+		case D3DPT_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;
+		case D3DPT_LINELIST:      drawType = sw::DRAW_LINELIST;      break;
+		case D3DPT_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;
+		case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;
+		case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
+		case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;
+		default:
+			ASSERT(false);
+		}
+
+		bindVertexStreams(startVertex, false, 0);
+		renderer->draw(drawType, 0, primitiveCount);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int primitiveCount = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", primitiveType, primitiveCount, vertexStreamZeroData, vertexStreamZeroStride);
+
+		if(!vertexStreamZeroData)
+		{
+			return INVALIDCALL();
+		}
+
+		IDirect3DVertexBuffer9 *vertexBuffer = 0;
+		int length = 0;
+
+		switch(primitiveType)
+		{
+		case D3DPT_POINTLIST:		length = primitiveCount;		break;
+		case D3DPT_LINELIST:		length = primitiveCount * 2;	break;
+		case D3DPT_LINESTRIP:		length = primitiveCount + 1;	break;
+		case D3DPT_TRIANGLELIST:	length = primitiveCount * 3;	break;
+		case D3DPT_TRIANGLESTRIP:	length = primitiveCount + 2;	break;
+		case D3DPT_TRIANGLEFAN:		length = primitiveCount + 2;	break;
+		default:
+			ASSERT(false);
+		}
+
+		length *= vertexStreamZeroStride;
+
+		CreateVertexBuffer(length, 0, 0, D3DPOOL_DEFAULT, &vertexBuffer, 0);
+
+		void *data;
+		vertexBuffer->Lock(0, 0, &data, 0);
+		memcpy(data, vertexStreamZeroData, length);
+		vertexBuffer->Unlock();
+
+		SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
+
+		if(!bindResources(0) || !primitiveCount)
+		{
+			vertexBuffer->Release();
+
+			return D3D_OK;
+		}
+
+		sw::DrawType drawType;
+
+		switch(primitiveType)
+		{
+		case D3DPT_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;
+		case D3DPT_LINELIST:      drawType = sw::DRAW_LINELIST;      break;
+		case D3DPT_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;
+		case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;
+		case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
+		case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;
+		default:
+			ASSERT(false);
+		}
+
+		bindVertexStreams(0, false, 0);
+		renderer->draw(drawType, 0, primitiveCount);
+
+		SetStreamSource(0, 0, 0, 0);
+		vertexBuffer->Release();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DRECTPATCH_INFO *rectPatchInfo = 0x%0.8p", handle, numSegs, rectPatchInfo);
+
+		if(!numSegs || !rectPatchInfo)
+		{
+			return INVALIDCALL();
+		}
+
+		UNIMPLEMENTED();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DTRIPATCH_INFO *triPatchInfo = 0x%0.8p", handle, numSegs, triPatchInfo);
+
+		if(!numSegs || !triPatchInfo)
+		{
+			return INVALIDCALL();
+		}
+
+		UNIMPLEMENTED();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::EndScene()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::EndStateBlock(IDirect3DStateBlock9 **stateBlock)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DStateBlock9 **stateBlock = 0x%0.8p", stateBlock);
+
+		if(!stateBlock)
+		{
+			return INVALIDCALL();
+		}
+
+		*stateBlock = 0;
+
+		if(!stateRecorder)
+		{
+			return INVALIDCALL();
+		}
+
+		*stateBlock = stateRecorder;
+		stateRecorder->AddRef();
+		stateRecorder->unbind();
+		stateRecorder = 0;   // Stop recording
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::EvictManagedResources()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		//	UNIMPLEMENTED();   // FIXME
+
+		return D3D_OK;
+	}
+
+	unsigned int Direct3DDevice9::GetAvailableTextureMem()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		int availableMemory = textureMemory - Direct3DResource9::getMemoryUsage();
+		if(availableMemory < 0) availableMemory = 0;
+
+		// Round to nearest MB
+		return (availableMemory + 0x80000) & 0xFFF00000;
+	}
+
+	long Direct3DDevice9::GetBackBuffer(unsigned int swapChainIndex, unsigned int backBufferIndex, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int swapChainIndex = %d, unsigned int backBufferIndex = %d, D3DBACKBUFFER_TYPE type = %d, IDirect3DSurface9 **backBuffer = 0x%0.8p", swapChainIndex, backBufferIndex, type, backBuffer);
+
+		if(swapChainIndex >= GetNumberOfSwapChains())
+		{
+			return INVALIDCALL();
+		}
+
+		return swapChain->GetBackBuffer(backBufferIndex, type, backBuffer);
+	}
+
+	long Direct3DDevice9::GetClipPlane(unsigned long index, float *plane)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, float *plane = 0x%0.8p", index, plane);
+
+		if(!plane || index >= 6)
+		{
+			return INVALIDCALL();
+		}
+
+		plane[0] = this->plane[index][0];
+		plane[1] = this->plane[index][1];
+		plane[2] = this->plane[index][2];
+		plane[3] = this->plane[index][3];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetClipStatus(D3DCLIPSTATUS9 *clipStatus)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
+
+		if(!clipStatus)
+		{
+			return INVALIDCALL();
+		}
+
+		*clipStatus = this->clipStatus;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DDEVICE_CREATION_PARAMETERS *parameters = 0x%0.8p", parameters);
+
+		if(!parameters)
+		{
+			return INVALIDCALL();
+		}
+
+		parameters->AdapterOrdinal = adapter;
+		parameters->BehaviorFlags = behaviourFlags;
+		parameters->DeviceType = deviceType;
+		parameters->hFocusWindow = focusWindow;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetCurrentTexturePalette(unsigned int *paletteNumber)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int *paletteNumber = 0x%0.8p", paletteNumber);
+
+		if(!paletteNumber)
+		{
+			return INVALIDCALL();
+		}
+
+		*paletteNumber = currentPalette;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DSurface9 **depthStencilSurface = 0x%0.8p", depthStencilSurface);
+
+		if(!depthStencilSurface)
+		{
+			return INVALIDCALL();
+		}
+
+		*depthStencilSurface = depthStencil;
+
+		if(depthStencil)
+		{
+			depthStencil->AddRef();
+		}
+		else
+		{
+			return NOTFOUND();
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetDeviceCaps(D3DCAPS9 *caps)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DCAPS9 *caps = 0x%0.8p", caps);
+
+		return d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps);
+	}
+
+	long Direct3DDevice9::GetDirect3D(IDirect3D9 **d3d9)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3D9 **d3d9 = 0x%0.8p", d3d9);
+
+		if(!d3d9)
+		{
+			return INVALIDCALL();
+		}
+
+		*d3d9 = this->d3d9;
+		this->d3d9->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetDisplayMode(unsigned int index, D3DDISPLAYMODE *mode)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", index, mode);
+
+		if(index >= GetNumberOfSwapChains())
+		{
+			return INVALIDCALL();
+		}
+
+		return swapChain->GetDisplayMode(mode);
+	}
+
+	long Direct3DDevice9::GetFrontBufferData(unsigned int index, IDirect3DSurface9 *destSurface)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int index = %d, IDirect3DSurface9 *destSurface = %p", index, destSurface);
+
+		if(index >= GetNumberOfSwapChains())
+		{
+			return INVALIDCALL();
+		}
+
+		return swapChain->GetFrontBufferData(destSurface);
+	}
+
+	long Direct3DDevice9::GetFVF(unsigned long *FVF)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long *FVF = 0x%0.8p", FVF);
+
+		if(!FVF)
+		{
+			return INVALIDCALL();
+		}
+
+		if(vertexDeclaration)
+		{
+			*FVF = vertexDeclaration->getFVF();
+		}
+		else
+		{
+			*FVF = 0;
+		}
+
+		return D3D_OK;
+	}
+
+	void Direct3DDevice9::GetGammaRamp(unsigned int index, D3DGAMMARAMP *ramp)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int index = %d, D3DGAMMARAMP *ramp = 0x%0.8p", index, ramp);
+
+		if(!ramp || index >= GetNumberOfSwapChains())
+		{
+			return;
+		}
+
+		swapChain->getGammaRamp((sw::GammaRamp*)ramp);
+	}
+
+	long Direct3DDevice9::GetIndices(IDirect3DIndexBuffer9 **indexData)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DIndexBuffer9 **indexData = 0x%0.8p", indexData);
+
+		if(!indexData)
+		{
+			return INVALIDCALL();
+		}
+
+		*indexData = this->indexData;
+
+		if(this->indexData)
+		{
+			this->indexData->AddRef();
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetLight(unsigned long index, D3DLIGHT9 *light)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, D3DLIGHT9 *light = 0x%0.8p", index, light);
+
+		if(!light)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!this->light.exists(index))
+		{
+			return INVALIDCALL();
+		}
+
+		*light = this->light[index];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetLightEnable(unsigned long index, int *enable)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, int *enable = 0x%0.8p", index, enable);
+
+		if(!enable)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!light.exists(index))
+		{
+			return INVALIDCALL();
+		}
+
+		*enable = light[index].enable ? 128 : 0;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetMaterial(D3DMATERIAL9 *material)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DMATERIAL9 *material = 0x%0.8p", material);
+
+		if(!material)
+		{
+			return INVALIDCALL();
+		}
+
+		*material = this->material;
+
+		return D3D_OK;
+	}
+
+	float Direct3DDevice9::GetNPatchMode()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		return 0.0f;   // FIXME: Unimplemented
+	}
+
+	unsigned int Direct3DDevice9::GetNumberOfSwapChains()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		return 1;
+	}
+
+	long Direct3DDevice9::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int paletteNumber = %d, PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
+
+		if(paletteNumber > 0xFFFF || !entries)
+		{
+			return INVALIDCALL();
+		}
+
+		for(int i = 0; i < 256; i++)
+		{
+			entries[i] = palette[paletteNumber].entry[i];
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetPixelShader(IDirect3DPixelShader9 **shader)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DPixelShader9 **shader = 0x%0.8p", shader);
+
+		if(!shader)
+		{
+			return INVALIDCALL();
+		}
+
+		if(pixelShader)
+		{
+			pixelShader->AddRef();
+		}
+
+		*shader = pixelShader;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		for(unsigned int i = 0; i < count; i++)
+		{
+			constantData[i] = pixelShaderConstantB[startRegister + i];
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		for(unsigned int i = 0; i < count; i++)
+		{
+			constantData[i * 4 + 0] = pixelShaderConstantF[startRegister + i][0];
+			constantData[i * 4 + 1] = pixelShaderConstantF[startRegister + i][1];
+			constantData[i * 4 + 2] = pixelShaderConstantF[startRegister + i][2];
+			constantData[i * 4 + 3] = pixelShaderConstantF[startRegister + i][3];
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		for(unsigned int i = 0; i < count; i++)
+		{
+			constantData[i * 4 + 0] = pixelShaderConstantI[startRegister + i][0];
+			constantData[i * 4 + 1] = pixelShaderConstantI[startRegister + i][1];
+			constantData[i * 4 + 2] = pixelShaderConstantI[startRegister + i][2];
+			constantData[i * 4 + 3] = pixelShaderConstantI[startRegister + i][3];
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetRasterStatus(unsigned int index, D3DRASTER_STATUS *rasterStatus)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int swapChain = %d, D3DRASTER_STATUS *rasterStatus = 0x%0.8p", index, rasterStatus);
+
+		if(index >= GetNumberOfSwapChains())
+		{
+			return INVALIDCALL();
+		}
+
+		return swapChain->GetRasterStatus(rasterStatus);
+	}
+
+	long Direct3DDevice9::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DRENDERSTATETYPE state = %d, unsigned long *value = 0x%0.8p", state, value);
+
+		if(!value)
+		{
+			return INVALIDCALL();
+		}
+
+		*value = renderState[state];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, IDirect3DSurface9 **renderTarget = 0x%0.8p", index, renderTarget);
+
+		if(index >= 4 || !renderTarget)
+		{
+			return INVALIDCALL();
+		}
+
+		*renderTarget = 0;
+
+		if(!this->renderTarget[index])
+		{
+			return NOTFOUND();
+		}
+
+		*renderTarget = this->renderTarget[index];
+		this->renderTarget[index]->AddRef();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DSurface9 *renderTarget = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p", renderTarget, destSurface);
+
+		if(!renderTarget || !destSurface)
+		{
+			return INVALIDCALL();
+		}
+
+		D3DSURFACE_DESC sourceDescription;
+		D3DSURFACE_DESC destinationDescription;
+
+		renderTarget->GetDesc(&sourceDescription);
+		destSurface->GetDesc(&destinationDescription);
+
+		if(sourceDescription.Width  != destinationDescription.Width ||
+		   sourceDescription.Height != destinationDescription.Height ||
+		   sourceDescription.Format != destinationDescription.Format ||
+		   sourceDescription.MultiSampleType != D3DMULTISAMPLE_NONE)
+		{
+			return INVALIDCALL();
+		}
+
+		if(sourceDescription.Format == D3DFMT_A8R8G8B8 ||
+		   sourceDescription.Format == D3DFMT_X8R8G8B8)
+		{
+			sw::Surface *source = static_cast<Direct3DSurface9*>(renderTarget);
+			sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);
+
+			void *sourceBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+			void *destBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
+
+			static void (__cdecl *blitFunction)(void *dst, void *src);
+			static sw::Routine *blitRoutine;
+			static sw::BlitState blitState = {0};
+
+			sw::BlitState update;
+			update.width = sourceDescription.Width;
+			update.height = sourceDescription.Height;
+			update.sourceFormat = sw::FORMAT_A8R8G8B8;
+			update.destFormat = sw::FORMAT_A8R8G8B8;
+			update.stride = dest->getExternalPitchB();
+			update.cursorHeight = 0;
+			update.cursorWidth = 0;
+
+			if(memcmp(&blitState, &update, sizeof(sw::BlitState)) != 0)
+			{
+				blitState = update;
+				delete blitRoutine;
+
+				blitRoutine = sw::FrameBuffer::copyRoutine(blitState);
+				blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();
+			}
+
+			blitFunction(destBuffer, sourceBuffer);
+
+			dest->unlockExternal();
+			source->unlockExternal();
+		}
+		else
+		{
+			return UpdateSurface(renderTarget, 0, destSurface, 0);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE type = %d, unsigned long *value = 0x%0.8p", sampler, state, value);
+
+		if(!value || state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)   // FIXME: Set *value to 0?
+		{
+			return INVALIDCALL();
+		}
+
+		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+		{
+			return INVALIDCALL();
+		}
+
+		if(sampler >= D3DVERTEXTEXTURESAMPLER0)
+		{
+			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
+		}
+
+		*value = samplerState[sampler][state];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetScissorRect(RECT *rect)
+	{
+		CriticalSection cs(this);
+
+		TRACE("RECT *rect = 0x%0.8p", rect);
+
+		if(!rect)
+		{
+			return INVALIDCALL();
+		}
+
+		*rect = scissorRect;
+
+		return D3D_OK;
+	}
+
+	int Direct3DDevice9::GetSoftwareVertexProcessing()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		return softwareVertexProcessing ? TRUE : FALSE;
+	}
+
+	long Direct3DDevice9::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int streamNumber = %d, IDirect3DVertexBuffer9 **streamData = 0x%0.8p, unsigned int *offset = 0x%0.8p, unsigned int *stride = 0x%0.8p", streamNumber, streamData, offset, stride);
+
+		if(streamNumber >= 16 || !streamData || !offset || !stride)
+		{
+			return INVALIDCALL();
+		}
+
+		*streamData = dataStream[streamNumber];
+
+		if(dataStream[streamNumber])
+		{
+			dataStream[streamNumber]->AddRef();
+		}
+
+		*offset = streamOffset[streamNumber];
+		*stride = streamStride[streamNumber];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int streamNumber = %d, unsigned int *divider = 0x%0.8p", streamNumber, divider);
+
+		if(streamNumber >= 16 || !divider)
+		{
+			return INVALIDCALL();
+		}
+
+		*divider = streamSourceFreq[streamNumber];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int index = %d, IDirect3DSwapChain9 **swapChain = 0x%0.8p", index, swapChain);
+
+		if(!swapChain || index >= GetNumberOfSwapChains())
+		{
+			return INVALIDCALL();
+		}
+
+		*swapChain = this->swapChain;
+
+		if(*swapChain)
+		{
+			(*swapChain)->AddRef();
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 **texture = 0x%0.8p", sampler, texture);
+
+		if(!texture)
+		{
+			return INVALIDCALL();
+		}
+
+		*texture = 0;
+
+		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+		{
+			return INVALIDCALL();
+		}
+
+		*texture = this->texture[sampler];
+
+		if(this->texture[sampler])
+		{
+			this->texture[sampler]->AddRef();
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long *value = 0x%0.8p", stage, type, value);
+
+		if(!value)
+		{
+			return INVALIDCALL();
+		}
+
+		*value = textureStageState[stage][type];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DTRANSFORMSTATETYPE state = %d, D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+		if(!matrix || state < 0 || state > 511)
+		{
+			return INVALIDCALL();
+		}
+
+		*matrix = this->matrix[state];
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", declaration);
+
+		if(!declaration)
+		{
+			return INVALIDCALL();
+		}
+
+		*declaration = vertexDeclaration;
+
+		if(vertexDeclaration)
+		{
+			vertexDeclaration->AddRef();
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetVertexShader(IDirect3DVertexShader9 **shader)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DVertexShader9 **shader = 0x%0.8p", shader);
+
+		if(!shader)
+		{
+			return INVALIDCALL();
+		}
+
+		*shader = vertexShader;
+
+		if(vertexShader)
+		{
+			vertexShader->AddRef();
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		for(unsigned int i = 0; i < count; i++)
+		{
+			constantData[i] = vertexShaderConstantB[startRegister + i];
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		for(unsigned int i = 0; i < count; i++)
+		{
+			constantData[i * 4 + 0] = vertexShaderConstantF[startRegister + i][0];
+			constantData[i * 4 + 1] = vertexShaderConstantF[startRegister + i][1];
+			constantData[i * 4 + 2] = vertexShaderConstantF[startRegister + i][2];
+			constantData[i * 4 + 3] = vertexShaderConstantF[startRegister + i][3];
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		for(unsigned int i = 0; i < count; i++)
+		{
+			constantData[i * 4 + 0] = vertexShaderConstantI[startRegister + i][0];
+			constantData[i * 4 + 1] = vertexShaderConstantI[startRegister + i][1];
+			constantData[i * 4 + 2] = vertexShaderConstantI[startRegister + i][2];
+			constantData[i * 4 + 3] = vertexShaderConstantI[startRegister + i][3];
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::GetViewport(D3DVIEWPORT9 *viewport)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
+
+		if(!viewport)
+		{
+			return INVALIDCALL();
+		}
+
+		*viewport = this->viewport;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::LightEnable(unsigned long index, int enable)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, int enable = %d", index, enable);
+
+		if(!light.exists(index))   // Insert default light
+		{
+			D3DLIGHT9 light;
+
+			light.Type = D3DLIGHT_DIRECTIONAL;
+			light.Diffuse.r = 1;
+			light.Diffuse.g = 1;
+			light.Diffuse.b = 1;
+			light.Diffuse.a = 0;
+			light.Specular.r = 0;
+			light.Specular.g = 0;
+			light.Specular.b = 0;
+			light.Specular.a = 0;
+			light.Ambient.r = 0;
+			light.Ambient.g = 0;
+			light.Ambient.b = 0;
+			light.Ambient.a = 0;
+			light.Position.x = 0;
+			light.Position.y = 0;
+			light.Position.z = 0;
+			light.Direction.x = 0;
+			light.Direction.y = 0;
+			light.Direction.z = 1;
+			light.Range = 0;
+			light.Falloff = 0;
+			light.Attenuation0 = 0;
+			light.Attenuation1 = 0;
+			light.Attenuation2 = 0;
+			light.Theta = 0;
+			light.Phi = 0;
+
+			this->light[index] = light;
+			this->light[index].enable = false;
+		}
+
+		if(!stateRecorder)
+		{
+			light[index].enable = (enable != FALSE);
+
+			lightsDirty = true;
+		}
+		else
+		{
+			stateRecorder->lightEnable(index, enable);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+		if(!matrix)
+		{
+			return INVALIDCALL();
+		}
+
+		D3DMATRIX *current = &this->matrix[state];
+
+		sw::Matrix C(current->_11, current->_21, current->_31, current->_41,
+		             current->_12, current->_22, current->_32, current->_42,
+		             current->_13, current->_23, current->_33, current->_43,
+		             current->_14, current->_24, current->_34, current->_44);
+
+		sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
+		             matrix->_12, matrix->_22, matrix->_32, matrix->_42,
+		             matrix->_13, matrix->_23, matrix->_33, matrix->_43,
+		             matrix->_14, matrix->_24, matrix->_34, matrix->_44);
+
+		switch(state)
+		{
+		case D3DTS_WORLD:
+			renderer->setModelMatrix(C * M);
+			break;
+		case D3DTS_VIEW:
+			renderer->setViewMatrix(C * M);
+			break;
+		case D3DTS_PROJECTION:
+			renderer->setProjectionMatrix(C * M);
+			break;
+		case D3DTS_TEXTURE0:
+			renderer->setTextureMatrix(0, C * M);
+			break;
+		case D3DTS_TEXTURE1:
+			renderer->setTextureMatrix(1, C * M);
+			break;
+		case D3DTS_TEXTURE2:
+			renderer->setTextureMatrix(2, C * M);
+			break;
+		case D3DTS_TEXTURE3:
+			renderer->setTextureMatrix(3, C * M);
+			break;
+		case D3DTS_TEXTURE4:
+			renderer->setTextureMatrix(4, C * M);
+			break;
+		case D3DTS_TEXTURE5:
+			renderer->setTextureMatrix(5, C * M);
+			break;
+		case D3DTS_TEXTURE6:
+			renderer->setTextureMatrix(6, C * M);
+			break;
+		case D3DTS_TEXTURE7:
+			renderer->setTextureMatrix(7, C * M);
+			break;
+		default:
+			if(state > 256 && state < 512)
+			{
+				renderer->setModelMatrix(C * M, state - 256);
+			}
+			else ASSERT(false);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const RECT *sourceRect = 0x%0.8p, const RECT *destRect = 0x%0.8p, HWND destWindowOverride = %d, const RGNDATA *dirtyRegion = 0x%0.8p", sourceRect, destRect, destWindowOverride, dirtyRegion);
+
+		return swapChain->Present(sourceRect, destRect, destWindowOverride, dirtyRegion, 0);
+	}
+
+	long Direct3DDevice9::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int srcStartIndex = %d, unsigned int destIndex = %d, unsigned int vertexCount = %d, IDirect3DVertexBuffer9 *destBuffer = 0x%0.8p, IDirect3DVertexDeclaration9 *vertexDeclaration = 0x%0.8p, unsigned long flags = %d", srcStartIndex, destIndex, vertexCount, destBuffer, vertexDeclaration, flags);
+
+		if(!destBuffer)
+		{
+			return INVALIDCALL();
+		}
+
+		UNIMPLEMENTED();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::Reset(D3DPRESENT_PARAMETERS *presentParameters)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p", presentParameters);
+
+		if(!presentParameters)
+		{
+			return INVALIDCALL();
+		}
+
+		deviceWindow = presentParameters->hDeviceWindow;
+
+		if(depthStencil)
+		{
+			depthStencil->unbind();
+			depthStencil = 0;
+		}
+
+		if(autoDepthStencil)
+		{
+			autoDepthStencil->unbind();
+			autoDepthStencil = 0;
+		}
+
+		for(int index = 0; index < 4; index++)
+		{
+			if(renderTarget[index])
+			{
+				renderTarget[index]->unbind();
+				renderTarget[index] = 0;
+			}
+		}
+
+		if(!swapChain)
+		{
+			swapChain = new Direct3DSwapChain9(this, presentParameters);
+			swapChain->bind();
+		}
+		else
+		{
+			swapChain->reset(presentParameters);
+		}
+
+		if(presentParameters->EnableAutoDepthStencil != FALSE)
+		{
+			bool lockable = false;
+
+			switch(presentParameters->AutoDepthStencilFormat)
+			{
+			case D3DFMT_D15S1:
+			case D3DFMT_D24S8:
+			case D3DFMT_D24X8:
+			case D3DFMT_D24X4S4:
+			case D3DFMT_D24FS8:
+			case D3DFMT_D32:
+			case D3DFMT_D16:
+			case D3DFMT_DF24:
+			case D3DFMT_DF16:
+			case D3DFMT_INTZ:
+				lockable = false;
+				break;
+			case D3DFMT_S8_LOCKABLE:
+			case D3DFMT_D16_LOCKABLE:
+			case D3DFMT_D32F_LOCKABLE:
+			case D3DFMT_D32_LOCKABLE:
+				lockable = true;
+				break;
+			default:
+				ASSERT(false);
+			}
+
+			autoDepthStencil = new Direct3DSurface9(this, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
+			autoDepthStencil->bind();
+
+			SetDepthStencilSurface(autoDepthStencil);
+		}
+
+		IDirect3DSurface9 *renderTarget;
+		swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget);
+		SetRenderTarget(0, renderTarget);
+		renderTarget->Release();
+
+		SetRenderTarget(1, 0);
+		SetRenderTarget(2, 0);
+		SetRenderTarget(3, 0);
+
+		softwareVertexProcessing = (behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+
+		SetRenderState(D3DRS_ZENABLE, presentParameters->EnableAutoDepthStencil != FALSE ? D3DZB_TRUE : D3DZB_FALSE);
+		SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+		SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
+		SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+		SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+		SetRenderState(D3DRS_LASTPIXEL, TRUE);
+		SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+		SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+		SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
+		SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+		SetRenderState(D3DRS_ALPHAREF, 0);
+		SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
+		SetRenderState(D3DRS_DITHERENABLE, FALSE);
+		SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+		SetRenderState(D3DRS_FOGENABLE, FALSE);
+		SetRenderState(D3DRS_SPECULARENABLE, FALSE);
+	//	SetRenderState(D3DRS_ZVISIBLE, 0);
+		SetRenderState(D3DRS_FOGCOLOR, 0);
+		SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
+		SetRenderState(D3DRS_FOGSTART, FtoDW(0.0f));
+		SetRenderState(D3DRS_FOGEND, FtoDW(1.0f));
+		SetRenderState(D3DRS_FOGDENSITY, FtoDW(1.0f));
+		SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
+		SetRenderState(D3DRS_STENCILENABLE, FALSE);
+		SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
+		SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
+		SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
+		SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+		SetRenderState(D3DRS_STENCILREF, 0);
+		SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
+		SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
+		SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
+		SetRenderState(D3DRS_WRAP0, 0);
+		SetRenderState(D3DRS_WRAP1, 0);
+		SetRenderState(D3DRS_WRAP2, 0);
+		SetRenderState(D3DRS_WRAP3, 0);
+		SetRenderState(D3DRS_WRAP4, 0);
+		SetRenderState(D3DRS_WRAP5, 0);
+		SetRenderState(D3DRS_WRAP6, 0);
+		SetRenderState(D3DRS_WRAP7, 0);
+		SetRenderState(D3DRS_CLIPPING, TRUE);
+		SetRenderState(D3DRS_LIGHTING, TRUE);
+		SetRenderState(D3DRS_AMBIENT, 0);
+		SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
+		SetRenderState(D3DRS_COLORVERTEX, TRUE);
+		SetRenderState(D3DRS_LOCALVIEWER, TRUE);
+		SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
+		SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
+		SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
+		SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
+		SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
+		SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
+		SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+		SetRenderState(D3DRS_POINTSIZE, FtoDW(1.0f));
+		SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(1.0f));
+		SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
+		SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
+		SetRenderState(D3DRS_POINTSCALE_A, FtoDW(1.0f));
+		SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
+		SetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.0f));
+		SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+		SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+		SetRenderState(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
+		SetRenderState(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE);
+		SetRenderState(D3DRS_POINTSIZE_MAX, FtoDW(64.0f));
+		SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
+		SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F);
+		SetRenderState(D3DRS_TWEENFACTOR, FtoDW(0.0f));
+		SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+		SetRenderState(D3DRS_POSITIONDEGREE, D3DDEGREE_CUBIC);
+		SetRenderState(D3DRS_NORMALDEGREE, D3DDEGREE_LINEAR);
+		SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+		SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FtoDW(0.0f));
+		SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE);
+		SetRenderState(D3DRS_MINTESSELLATIONLEVEL, FtoDW(1.0f));
+		SetRenderState(D3DRS_MAXTESSELLATIONLEVEL, FtoDW(1.0f));
+		SetRenderState(D3DRS_ADAPTIVETESS_X, FtoDW(0.0f));
+		SetRenderState(D3DRS_ADAPTIVETESS_Y, FtoDW(0.0f));
+		SetRenderState(D3DRS_ADAPTIVETESS_Z, FtoDW(1.0f));
+		SetRenderState(D3DRS_ADAPTIVETESS_W, FtoDW(0.0f));
+		SetRenderState(D3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
+		SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+		SetRenderState(D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP);
+		SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP);
+		SetRenderState(D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP);
+		SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS);
+		SetRenderState(D3DRS_COLORWRITEENABLE1, 0x0000000F);
+		SetRenderState(D3DRS_COLORWRITEENABLE2, 0x0000000F);
+		SetRenderState(D3DRS_COLORWRITEENABLE3, 0x0000000F);
+		SetRenderState(D3DRS_BLENDFACTOR, 0xFFFFFFFF);
+		SetRenderState(D3DRS_SRGBWRITEENABLE, 0);
+		SetRenderState(D3DRS_DEPTHBIAS, FtoDW(0.0f));
+		SetRenderState(D3DRS_WRAP8, 0);
+		SetRenderState(D3DRS_WRAP9, 0);
+		SetRenderState(D3DRS_WRAP10, 0);
+		SetRenderState(D3DRS_WRAP11, 0);
+		SetRenderState(D3DRS_WRAP12, 0);
+		SetRenderState(D3DRS_WRAP13, 0);
+		SetRenderState(D3DRS_WRAP14, 0);
+		SetRenderState(D3DRS_WRAP15, 0);
+		SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
+		SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
+		SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
+		SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
+
+		for(int i = 0; i < 8; i++)
+		{
+			SetTextureStageState(i, D3DTSS_COLOROP, i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE);
+			SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+			SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
+			SetTextureStageState(i, D3DTSS_ALPHAOP, i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE);
+			SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+			SetTextureStageState(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
+			SetTextureStageState(i, D3DTSS_BUMPENVMAT00, FtoDW(0.0f));
+			SetTextureStageState(i, D3DTSS_BUMPENVMAT01, FtoDW(0.0f));
+			SetTextureStageState(i, D3DTSS_BUMPENVMAT10, FtoDW(0.0f));
+			SetTextureStageState(i, D3DTSS_BUMPENVMAT11, FtoDW(0.0f));
+			SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i);
+			SetTextureStageState(i, D3DTSS_BUMPENVLSCALE, FtoDW(0.0f));
+			SetTextureStageState(i, D3DTSS_BUMPENVLOFFSET, FtoDW(0.0f));
+			SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
+			SetTextureStageState(i, D3DTSS_COLORARG0, D3DTA_CURRENT);
+			SetTextureStageState(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT);
+			SetTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT);
+			SetTextureStageState(i, D3DTSS_CONSTANT, 0x00000000);
+		}
+
+		for(int i = 0; i <= D3DVERTEXTEXTURESAMPLER3; i = (i != 15) ? (i + 1) : D3DVERTEXTEXTURESAMPLER0)
+		{
+			SetTexture(i, 0);
+
+			SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
+			SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
+			SetSamplerState(i, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
+			SetSamplerState(i, D3DSAMP_BORDERCOLOR, 0x00000000);
+			SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+			SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+			SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+			SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, 0);
+			SetSamplerState(i, D3DSAMP_MAXMIPLEVEL, 0);
+			SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 1);
+			SetSamplerState(i, D3DSAMP_SRGBTEXTURE, 0);
+			SetSamplerState(i, D3DSAMP_ELEMENTINDEX, 0);
+			SetSamplerState(i, D3DSAMP_DMAPOFFSET, 0);
+		}
+
+		for(int i = 0; i < 6; i++)
+		{
+			float plane[4] = {0, 0, 0, 0};
+
+			SetClipPlane(i, plane);
+		}
+
+		currentPalette = 0xFFFF;
+
+		ShowCursor(FALSE);
+		delete cursor;
+		cursor = 0;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetClipPlane(unsigned long index, const float *plane)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, const float *plane = 0x%0.8p", index, plane);
+
+		if(!plane || index >= 6)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			this->plane[index][0] = plane[0];
+			this->plane[index][1] = plane[1];
+			this->plane[index][2] = plane[2];
+			this->plane[index][3] = plane[3];
+
+			renderer->setClipPlane(index, plane);
+		}
+		else
+		{
+			stateRecorder->setClipPlane(index, plane);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetClipStatus(const D3DCLIPSTATUS9 *clipStatus)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
+
+		if(!clipStatus)
+		{
+			return INVALIDCALL();
+		}
+
+		this->clipStatus = *clipStatus;
+
+		UNIMPLEMENTED();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetCurrentTexturePalette(unsigned int paletteNumber)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int paletteNumber = %d", paletteNumber);
+
+		if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end())
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			currentPalette = paletteNumber;
+
+			sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
+		}
+		else
+		{
+			stateRecorder->setCurrentTexturePalette(paletteNumber);
+		}
+
+		return D3D_OK;
+	}
+
+	void Direct3DDevice9::SetCursorPosition(int x, int y, unsigned long flags)
+	{
+		CriticalSection cs(this);
+
+		TRACE("int x = %d, int y = %d, unsigned long flags = 0x%0.8X", x, y, flags);
+
+		POINT point = {x, y};
+		HWND window = deviceWindow ? deviceWindow : focusWindow;
+		ScreenToClient(window, &point);
+
+		sw::FrameBuffer::setCursorPosition(point.x, point.y);
+	}
+
+	long Direct3DDevice9::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface9 *cursorBitmap)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int x0 = %d, unsigned int y0 = %d, IDirect3DSurface9 *cursorBitmap = 0x%0.8p", x0, y0, cursorBitmap);
+
+		if(!cursorBitmap)
+		{
+			return INVALIDCALL();
+		}
+
+		sw::Surface *cursorSurface = static_cast<Direct3DSurface9*>(cursorBitmap);
+
+		int width = cursorSurface->getWidth();
+		int height = cursorSurface->getHeight();
+		void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+
+		delete cursor;
+		cursor = new sw::Surface(0, width, height, 1, sw::FORMAT_A8R8G8B8, false, false);
+
+		void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
+		memcpy(buffer, bitmap, width * height * sizeof(unsigned int));
+		cursor->unlockExternal();
+
+		cursorSurface->unlockExternal();
+
+		if(showCursor)
+		{
+			sw::FrameBuffer::setCursorImage(cursor);
+		}
+		else
+		{
+			sw::FrameBuffer::setCursorImage(0);
+		}
+
+		sw::FrameBuffer::setCursorOrigin(x0, y0);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *iDepthStencil)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DSurface9 *newDepthStencil = 0x%0.8p", iDepthStencil);
+
+		Direct3DSurface9 *depthStencil = static_cast<Direct3DSurface9*>(iDepthStencil);
+
+		if(this->depthStencil == depthStencil)
+		{
+			return D3D_OK;
+		}
+
+		if(depthStencil)
+		{
+			depthStencil->bind();
+		}
+
+		if(this->depthStencil)
+		{
+			this->depthStencil->unbind();
+		}
+
+		this->depthStencil = depthStencil;
+
+		renderer->setDepthBuffer(depthStencil);
+		renderer->setStencilBuffer(depthStencil);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetDialogBoxMode(int enableDialogs)
+	{
+		CriticalSection cs(this);
+
+		TRACE("int enableDialogs = %d", enableDialogs);
+
+		UNIMPLEMENTED();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetFVF(unsigned long FVF)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long FVF = 0x%0.8X", FVF);
+
+		if(!stateRecorder)
+		{
+			if(FVF != 0 || !this->vertexDeclaration)
+			{
+				Direct3DVertexDeclaration9 *vertexDeclaration = new Direct3DVertexDeclaration9(this, FVF);
+				vertexDeclaration->bind();
+
+				if(this->vertexDeclaration)
+				{
+					this->vertexDeclaration->unbind();
+				}
+
+				this->vertexDeclaration = vertexDeclaration;
+			}
+		}
+		else
+		{
+			stateRecorder->setFVF(FVF);
+		}
+
+		return D3D_OK;
+	}
+
+	void Direct3DDevice9::SetGammaRamp(unsigned int index, unsigned long flags, const D3DGAMMARAMP *ramp)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int index = %d, unsigned long flags = 0x%0.8X, const D3DGAMMARAMP *ramp = 0x%0.8p", index, flags, ramp);
+
+		if(!ramp || index >= GetNumberOfSwapChains())
+		{
+			return;
+		}
+
+		swapChain->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE);
+	}
+
+	long Direct3DDevice9::SetIndices(IDirect3DIndexBuffer9* iIndexBuffer)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DIndexBuffer9* indexData = 0x%0.8p", iIndexBuffer);
+
+		Direct3DIndexBuffer9 *indexBuffer = static_cast<Direct3DIndexBuffer9*>(iIndexBuffer);
+
+		if(!stateRecorder)
+		{
+			if(this->indexData == indexBuffer)
+			{
+				return D3D_OK;
+			}
+
+			if(indexBuffer)
+			{
+				indexBuffer->bind();
+			}
+
+			if(this->indexData)
+			{
+				this->indexData->unbind();
+			}
+
+			this->indexData = indexBuffer;
+		}
+		else
+		{
+			stateRecorder->setIndices(indexBuffer);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetLight(unsigned long index, const D3DLIGHT9 *light)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, const D3DLIGHT9 *light = 0x%0.8p", index, light);
+
+		if(!light)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			this->light[index] = *light;
+
+			lightsDirty = true;
+		}
+		else
+		{
+			stateRecorder->setLight(index, light);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetMaterial(const D3DMATERIAL9 *material)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const D3DMATERIAL9 *material = 0x%0.8p", material);
+
+		if(!material)
+		{
+			return INVALIDCALL();   // FIXME: Correct behaviour?
+		}
+
+		if(!stateRecorder)
+		{
+			this->material = *material;
+
+			renderer->setMaterialAmbient(sw::Color<float>(material->Ambient.r, material->Ambient.g, material->Ambient.b, material->Ambient.a));
+			renderer->setMaterialDiffuse(sw::Color<float>(material->Diffuse.r, material->Diffuse.g, material->Diffuse.b, material->Diffuse.a));
+			renderer->setMaterialEmission(sw::Color<float>(material->Emissive.r, material->Emissive.g, material->Emissive.b, material->Emissive.a));
+			renderer->setMaterialShininess(material->Power);
+			renderer->setMaterialSpecular(sw::Color<float>(material->Specular.r, material->Specular.g, material->Specular.b, material->Specular.a));
+		}
+		else
+		{
+			stateRecorder->setMaterial(material);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetNPatchMode(float segments)
+	{
+		CriticalSection cs(this);
+
+		TRACE("float segments = %f", segments);
+
+		if(!stateRecorder)
+		{
+			if(segments < 1)
+			{
+				// NOTE: Disable
+			}
+			else
+			{
+				UNIMPLEMENTED();
+			}
+		}
+		else
+		{
+			stateRecorder->setNPatchMode(segments);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int paletteNumber = %d, const PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
+
+		if(paletteNumber > 0xFFFF || !entries)
+		{
+			return INVALIDCALL();
+		}
+
+		for(int i = 0; i < 256; i++)
+		{
+			palette[paletteNumber].entry[i] = entries[i];
+		}
+
+		if(paletteNumber == currentPalette)
+		{
+			sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetPixelShader(IDirect3DPixelShader9 *iPixelShader)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DPixelShader9 *shader = 0x%0.8p", iPixelShader);
+
+		Direct3DPixelShader9 *pixelShader = static_cast<Direct3DPixelShader9*>(iPixelShader);
+
+		if(!stateRecorder)
+		{
+			if(this->pixelShader == pixelShader)
+			{
+				return D3D_OK;
+			}
+
+			if(pixelShader)
+			{
+				pixelShader->bind();
+			}
+
+			if(this->pixelShader)
+			{
+				this->pixelShader->unbind();
+			}
+
+			this->pixelShader = pixelShader;
+			pixelShaderDirty = true;
+		}
+		else
+		{
+			stateRecorder->setPixelShader(pixelShader);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!stateRecorder)
+		{
+			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+			{
+				pixelShaderConstantB[startRegister + i] = constantData[i];
+			}
+
+			pixelShaderConstantsBDirty = sw::max(startRegister + count, pixelShaderConstantsBDirty);
+			pixelShaderDirty = true;   // Reload DEF constants
+		}
+		else
+		{
+			stateRecorder->setPixelShaderConstantB(startRegister, constantData, count);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!stateRecorder)
+		{
+			for(unsigned int i = 0; i < count && startRegister + i < MAX_PIXEL_SHADER_CONST; 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 = sw::max(startRegister + count, pixelShaderConstantsFDirty);
+			pixelShaderDirty = true;   // Reload DEF constants
+		}
+		else
+		{
+			stateRecorder->setPixelShaderConstantF(startRegister, constantData, count);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!stateRecorder)
+		{
+			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+			{
+				pixelShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
+				pixelShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
+				pixelShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
+				pixelShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
+			}
+
+			pixelShaderConstantsIDirty = sw::max(startRegister + count, pixelShaderConstantsIDirty);
+			pixelShaderDirty = true;   // Reload DEF constants
+		}
+		else
+		{
+			stateRecorder->setPixelShaderConstantI(startRegister, constantData, count);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);
+
+		if(state < D3DRS_ZENABLE || state > D3DRS_BLENDOPALPHA)
+		{
+			return D3D_OK;   // FIXME: Warning
+		}
+
+		if(!stateRecorder)
+		{
+			if(!init && renderState[state] == value)
+			{
+				return D3D_OK;
+			}
+
+			renderState[state] = value;
+
+			switch(state)
+			{
+			case D3DRS_ZENABLE:
+				switch(value)
+				{
+				case D3DZB_TRUE:
+				case D3DZB_USEW:
+					renderer->setDepthBufferEnable(true);
+					break;
+				case D3DZB_FALSE:
+					renderer->setDepthBufferEnable(false);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_FILLMODE:
+				switch(value)
+				{
+				case D3DFILL_POINT:
+					renderer->setFillMode(sw::FILL_VERTEX);
+					break;
+				case D3DFILL_WIREFRAME:
+					renderer->setFillMode(sw::FILL_WIREFRAME);
+					break;
+				case D3DFILL_SOLID:
+					renderer->setFillMode(sw::FILL_SOLID);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_SHADEMODE:
+				switch(value)
+				{
+				case D3DSHADE_FLAT:
+					renderer->setShadingMode(sw::SHADING_FLAT);
+					break;
+				case D3DSHADE_GOURAUD:
+					renderer->setShadingMode(sw::SHADING_GOURAUD);
+					break;
+				case D3DSHADE_PHONG:
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_ZWRITEENABLE:
+				renderer->setDepthWriteEnable(value != FALSE);
+				break;
+			case D3DRS_ALPHATESTENABLE:
+				renderer->setAlphaTestEnable(value != FALSE);
+				break;
+			case D3DRS_LASTPIXEL:
+			//	if(!init) UNIMPLEMENTED();   // FIXME
+				break;
+			case D3DRS_SRCBLEND:
+				switch(value)
+				{
+				case D3DBLEND_ZERO:
+					renderer->setSourceBlendFactor(sw::BLEND_ZERO);
+					break;
+				case D3DBLEND_ONE:
+					renderer->setSourceBlendFactor(sw::BLEND_ONE);
+					break;
+				case D3DBLEND_SRCCOLOR:
+					renderer->setSourceBlendFactor(sw::BLEND_SOURCE);
+					break;
+				case D3DBLEND_INVSRCCOLOR:
+					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCE);
+					break;
+				case D3DBLEND_SRCALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_INVSRCALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_DESTALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_DESTALPHA);
+					break;
+				case D3DBLEND_INVDESTALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_INVDESTALPHA);
+					break;
+				case D3DBLEND_DESTCOLOR:
+					renderer->setSourceBlendFactor(sw::BLEND_DEST);
+					break;
+				case D3DBLEND_INVDESTCOLOR:
+					renderer->setSourceBlendFactor(sw::BLEND_INVDEST);
+					break;
+				case D3DBLEND_SRCALPHASAT:
+					renderer->setSourceBlendFactor(sw::BLEND_SRCALPHASAT);
+					break;
+				case D3DBLEND_BOTHSRCALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
+					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_BOTHINVSRCALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
+					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_BLENDFACTOR:
+					renderer->setSourceBlendFactor(sw::BLEND_CONSTANT);
+					break;
+				case D3DBLEND_INVBLENDFACTOR:
+					renderer->setSourceBlendFactor(sw::BLEND_INVCONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_DESTBLEND:
+				switch(value)
+				{
+				case D3DBLEND_ZERO:
+					renderer->setDestBlendFactor(sw::BLEND_ZERO);
+					break;
+				case D3DBLEND_ONE:
+					renderer->setDestBlendFactor(sw::BLEND_ONE);
+					break;
+				case D3DBLEND_SRCCOLOR:
+					renderer->setDestBlendFactor(sw::BLEND_SOURCE);
+					break;
+				case D3DBLEND_INVSRCCOLOR:
+					renderer->setDestBlendFactor(sw::BLEND_INVSOURCE);
+					break;
+				case D3DBLEND_SRCALPHA:
+					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_INVSRCALPHA:
+					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_DESTALPHA:
+					renderer->setDestBlendFactor(sw::BLEND_DESTALPHA);
+					break;
+				case D3DBLEND_INVDESTALPHA:
+					renderer->setDestBlendFactor(sw::BLEND_INVDESTALPHA);
+					break;
+				case D3DBLEND_DESTCOLOR:
+					renderer->setDestBlendFactor(sw::BLEND_DEST);
+					break;
+				case D3DBLEND_INVDESTCOLOR:
+					renderer->setDestBlendFactor(sw::BLEND_INVDEST);
+					break;
+				case D3DBLEND_SRCALPHASAT:
+					renderer->setDestBlendFactor(sw::BLEND_SRCALPHASAT);
+					break;
+				case D3DBLEND_BOTHSRCALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
+					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_BOTHINVSRCALPHA:
+					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
+					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_BLENDFACTOR:
+					renderer->setDestBlendFactor(sw::BLEND_CONSTANT);
+					break;
+				case D3DBLEND_INVBLENDFACTOR:
+					renderer->setDestBlendFactor(sw::BLEND_INVCONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_CULLMODE:
+				switch(value)
+				{
+				case D3DCULL_NONE:
+					renderer->setCullMode(sw::CULL_NONE);
+					break;
+				case D3DCULL_CCW:
+					renderer->setCullMode(sw::CULL_COUNTERCLOCKWISE);
+					break;
+				case D3DCULL_CW:
+					renderer->setCullMode(sw::CULL_CLOCKWISE);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_ZFUNC:
+				switch(value)
+				{
+				case D3DCMP_NEVER:
+					renderer->setDepthCompare(sw::DEPTH_NEVER);
+					break;
+				case D3DCMP_LESS:
+					renderer->setDepthCompare(sw::DEPTH_LESS);
+					break;
+				case D3DCMP_EQUAL:
+					renderer->setDepthCompare(sw::DEPTH_EQUAL);
+					break;
+				case D3DCMP_LESSEQUAL:
+					renderer->setDepthCompare(sw::DEPTH_LESSEQUAL);
+					break;
+				case D3DCMP_GREATER:
+					renderer->setDepthCompare(sw::DEPTH_GREATER);
+					break;
+				case D3DCMP_NOTEQUAL:
+					renderer->setDepthCompare(sw::DEPTH_NOTEQUAL);
+					break;
+				case D3DCMP_GREATEREQUAL:
+					renderer->setDepthCompare(sw::DEPTH_GREATEREQUAL);
+					break;
+				case D3DCMP_ALWAYS:
+					renderer->setDepthCompare(sw::DEPTH_ALWAYS);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_ALPHAREF:
+				renderer->setAlphaReference(value & 0x000000FF);
+				break;
+			case D3DRS_ALPHAFUNC:
+				switch(value)
+				{
+				case D3DCMP_NEVER:
+					renderer->setAlphaCompare(sw::ALPHA_NEVER);
+					break;
+				case D3DCMP_LESS:
+					renderer->setAlphaCompare(sw::ALPHA_LESS);
+					break;
+				case D3DCMP_EQUAL:
+					renderer->setAlphaCompare(sw::ALPHA_EQUAL);
+					break;
+				case D3DCMP_LESSEQUAL:
+					renderer->setAlphaCompare(sw::ALPHA_LESSEQUAL);
+					break;
+				case D3DCMP_GREATER:
+					renderer->setAlphaCompare(sw::ALPHA_GREATER);
+					break;
+				case D3DCMP_NOTEQUAL:
+					renderer->setAlphaCompare(sw::ALPHA_NOTEQUAL);
+					break;
+				case D3DCMP_GREATEREQUAL:
+					renderer->setAlphaCompare(sw::ALPHA_GREATEREQUAL);
+					break;
+				case D3DCMP_ALWAYS:
+					renderer->setAlphaCompare(sw::ALPHA_ALWAYS);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_DITHERENABLE:
+			//	if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_ALPHABLENDENABLE:
+				renderer->setAlphaBlendEnable(value != FALSE);
+				break;
+			case D3DRS_FOGENABLE:
+				renderer->setFogEnable(value != FALSE);
+				break;
+			case D3DRS_FOGCOLOR:
+				renderer->setFogColor(value);
+				break;
+			case D3DRS_FOGTABLEMODE:
+				switch(value)
+				{
+				case D3DFOG_NONE:
+					renderer->setPixelFogMode(sw::FOG_NONE);
+					break;
+				case D3DFOG_LINEAR:
+					renderer->setPixelFogMode(sw::FOG_LINEAR);
+					break;
+				case D3DFOG_EXP:
+					renderer->setPixelFogMode(sw::FOG_EXP);
+					break;
+				case D3DFOG_EXP2:
+					renderer->setPixelFogMode(sw::FOG_EXP2);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_FOGSTART:
+				renderer->setFogStart((float&)value);
+				break;
+			case D3DRS_FOGEND:
+				renderer->setFogEnd((float&)value);
+				break;
+			case D3DRS_FOGDENSITY:
+				renderer->setFogDensity((float&)value);
+				break;
+			case D3DRS_RANGEFOGENABLE:
+				renderer->setRangeFogEnable(value != FALSE);
+				break;
+			case D3DRS_SPECULARENABLE:
+				renderer->setSpecularEnable(value != FALSE);
+				break;
+			case D3DRS_STENCILENABLE:
+				renderer->setStencilEnable(value != FALSE);
+				break;
+			case D3DRS_STENCILFAIL:
+				switch(value)
+				{
+				case D3DSTENCILOP_KEEP:
+					renderer->setStencilFailOperation(sw::OPERATION_KEEP);
+					break;
+				case D3DSTENCILOP_ZERO:
+					renderer->setStencilFailOperation(sw::OPERATION_ZERO);
+					break;
+				case D3DSTENCILOP_REPLACE:
+					renderer->setStencilFailOperation(sw::OPERATION_REPLACE);
+					break;
+				case D3DSTENCILOP_INCRSAT:
+					renderer->setStencilFailOperation(sw::OPERATION_INCRSAT);
+					break;
+				case D3DSTENCILOP_DECRSAT:
+					renderer->setStencilFailOperation(sw::OPERATION_DECRSAT);
+					break;
+				case D3DSTENCILOP_INVERT:
+					renderer->setStencilFailOperation(sw::OPERATION_INVERT);
+					break;
+				case D3DSTENCILOP_INCR:
+					renderer->setStencilFailOperation(sw::OPERATION_INCR);
+					break;
+				case D3DSTENCILOP_DECR:
+					renderer->setStencilFailOperation(sw::OPERATION_DECR);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_STENCILZFAIL:
+				switch(value)
+				{
+				case D3DSTENCILOP_KEEP:
+					renderer->setStencilZFailOperation(sw::OPERATION_KEEP);
+					break;
+				case D3DSTENCILOP_ZERO:
+					renderer->setStencilZFailOperation(sw::OPERATION_ZERO);
+					break;
+				case D3DSTENCILOP_REPLACE:
+					renderer->setStencilZFailOperation(sw::OPERATION_REPLACE);
+					break;
+				case D3DSTENCILOP_INCRSAT:
+					renderer->setStencilZFailOperation(sw::OPERATION_INCRSAT);
+					break;
+				case D3DSTENCILOP_DECRSAT:
+					renderer->setStencilZFailOperation(sw::OPERATION_DECRSAT);
+					break;
+				case D3DSTENCILOP_INVERT:
+					renderer->setStencilZFailOperation(sw::OPERATION_INVERT);
+					break;
+				case D3DSTENCILOP_INCR:
+					renderer->setStencilZFailOperation(sw::OPERATION_INCR);
+					break;
+				case D3DSTENCILOP_DECR:
+					renderer->setStencilZFailOperation(sw::OPERATION_DECR);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_STENCILPASS:
+				switch(value)
+				{
+				case D3DSTENCILOP_KEEP:
+					renderer->setStencilPassOperation(sw::OPERATION_KEEP);
+					break;
+				case D3DSTENCILOP_ZERO:
+					renderer->setStencilPassOperation(sw::OPERATION_ZERO);
+					break;
+				case D3DSTENCILOP_REPLACE:
+					renderer->setStencilPassOperation(sw::OPERATION_REPLACE);
+					break;
+				case D3DSTENCILOP_INCRSAT:
+					renderer->setStencilPassOperation(sw::OPERATION_INCRSAT);
+					break;
+				case D3DSTENCILOP_DECRSAT:
+					renderer->setStencilPassOperation(sw::OPERATION_DECRSAT);
+					break;
+				case D3DSTENCILOP_INVERT:
+					renderer->setStencilPassOperation(sw::OPERATION_INVERT);
+					break;
+				case D3DSTENCILOP_INCR:
+					renderer->setStencilPassOperation(sw::OPERATION_INCR);
+					break;
+				case D3DSTENCILOP_DECR:
+					renderer->setStencilPassOperation(sw::OPERATION_DECR);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_STENCILFUNC:
+				switch(value)
+				{
+				case D3DCMP_NEVER:
+					renderer->setStencilCompare(sw::STENCIL_NEVER);
+					break;
+				case D3DCMP_LESS:
+					renderer->setStencilCompare(sw::STENCIL_LESS);
+					break;
+				case D3DCMP_EQUAL:
+					renderer->setStencilCompare(sw::STENCIL_EQUAL);
+					break;
+				case D3DCMP_LESSEQUAL:
+					renderer->setStencilCompare(sw::STENCIL_LESSEQUAL);
+					break;
+				case D3DCMP_GREATER:
+					renderer->setStencilCompare(sw::STENCIL_GREATER);
+					break;
+				case D3DCMP_NOTEQUAL:
+					renderer->setStencilCompare(sw::STENCIL_NOTEQUAL);
+					break;
+				case D3DCMP_GREATEREQUAL:
+					renderer->setStencilCompare(sw::STENCIL_GREATEREQUAL);
+					break;
+				case D3DCMP_ALWAYS:
+					renderer->setStencilCompare(sw::STENCIL_ALWAYS);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_STENCILREF:
+				renderer->setStencilReference(value);
+				renderer->setStencilReferenceCCW(value);
+				break;
+			case D3DRS_STENCILMASK:
+				renderer->setStencilMask(value);
+				renderer->setStencilMaskCCW(value);
+				break;
+			case D3DRS_STENCILWRITEMASK:
+				renderer->setStencilWriteMask(value);
+				renderer->setStencilWriteMaskCCW(value);
+				break;
+			case D3DRS_TEXTUREFACTOR:
+				renderer->setTextureFactor(value);
+				break;
+			case D3DRS_WRAP0:
+				renderer->setTextureWrap(0, value);
+				break;
+			case D3DRS_WRAP1:
+				renderer->setTextureWrap(1, value);
+				break;
+			case D3DRS_WRAP2:
+				renderer->setTextureWrap(2, value);
+				break;
+			case D3DRS_WRAP3:
+				renderer->setTextureWrap(3, value);
+				break;
+			case D3DRS_WRAP4:
+				renderer->setTextureWrap(4, value);
+				break;
+			case D3DRS_WRAP5:
+				renderer->setTextureWrap(5, value);
+				break;
+			case D3DRS_WRAP6:
+				renderer->setTextureWrap(6, value);
+				break;
+			case D3DRS_WRAP7:
+				renderer->setTextureWrap(7, value);
+				break;
+			case D3DRS_CLIPPING:
+				// Ignored, clipping is always performed
+				break;
+			case D3DRS_LIGHTING:
+				renderer->setLightingEnable(value != FALSE);
+				break;
+			case D3DRS_AMBIENT:
+				renderer->setGlobalAmbient(value);
+				break;
+			case D3DRS_FOGVERTEXMODE:
+				switch(value)
+				{
+				case D3DFOG_NONE:
+					renderer->setVertexFogMode(sw::FOG_NONE);
+					break;
+				case D3DFOG_LINEAR:
+					renderer->setVertexFogMode(sw::FOG_LINEAR);
+					break;
+				case D3DFOG_EXP:
+					renderer->setVertexFogMode(sw::FOG_EXP);
+					break;
+				case D3DFOG_EXP2:
+					renderer->setVertexFogMode(sw::FOG_EXP2);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_COLORVERTEX:
+				renderer->setColorVertexEnable(value != FALSE);
+				break;
+			case D3DRS_LOCALVIEWER:
+				renderer->setLocalViewer(value != FALSE);
+				break;
+			case D3DRS_NORMALIZENORMALS:
+				renderer->setNormalizeNormals(value != FALSE);
+				break;
+			case D3DRS_DIFFUSEMATERIALSOURCE:
+				switch(value)
+				{
+				case D3DMCS_MATERIAL:
+					renderer->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
+					break;
+				case D3DMCS_COLOR1:
+					renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
+					break;
+				case D3DMCS_COLOR2:
+					renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR2);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_SPECULARMATERIALSOURCE:
+				switch(value)
+				{
+				case D3DMCS_MATERIAL:
+					renderer->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+					break;
+				case D3DMCS_COLOR1:
+					renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
+					break;
+				case D3DMCS_COLOR2:
+					renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR2);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_AMBIENTMATERIALSOURCE:
+				switch(value)
+				{
+				case D3DMCS_MATERIAL:
+					renderer->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
+					break;
+				case D3DMCS_COLOR1:
+					renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
+					break;
+				case D3DMCS_COLOR2:
+					renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR2);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_EMISSIVEMATERIALSOURCE:
+				switch(value)
+				{
+				case D3DMCS_MATERIAL:
+					renderer->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+					break;
+				case D3DMCS_COLOR1:
+					renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
+					break;
+				case D3DMCS_COLOR2:
+					renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR2);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_VERTEXBLEND:
+				switch(value)
+				{
+				case D3DVBF_DISABLE:
+					renderer->setVertexBlendMatrixCount(0);
+					break;
+				case D3DVBF_1WEIGHTS:
+					renderer->setVertexBlendMatrixCount(2);
+					break;
+				case D3DVBF_2WEIGHTS:
+					renderer->setVertexBlendMatrixCount(3);
+					break;
+				case D3DVBF_3WEIGHTS:
+					renderer->setVertexBlendMatrixCount(4);
+					break;
+				case D3DVBF_TWEENING:
+					UNIMPLEMENTED();
+					break;
+				case D3DVBF_0WEIGHTS:
+					renderer->setVertexBlendMatrixCount(1);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_CLIPPLANEENABLE:
+				renderer->setClipFlags(value);
+				break;
+			case D3DRS_POINTSIZE:
+				if(value == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0))   // ATI hack to enable instancing on SM 2.0 hardware
+				{
+					instancingEnabled = true;
+				}
+				else if(value == D3DFMT_A2M1)   // ATI hack to enable transparency anti-aliasing
+				{
+					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
+					renderer->setAlphaTestEnable(true);
+				}
+				else if(value == D3DFMT_A2M0)   // ATI hack to disable transparency anti-aliasing
+				{
+					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
+					renderer->setAlphaTestEnable(false);
+				}
+				else
+				{
+					renderer->setPointSize((float&)value);
+				}
+				break;
+			case D3DRS_POINTSIZE_MIN:
+				renderer->setPointSizeMin((float&)value);
+				break;
+			case D3DRS_POINTSPRITEENABLE:
+				renderer->setPointSpriteEnable(value != FALSE);
+				break;
+			case D3DRS_POINTSCALEENABLE:
+				renderer->setPointScaleEnable(value != FALSE);
+				break;
+			case D3DRS_POINTSCALE_A:
+				renderer->setPointScaleA((float&)value);
+				break;
+			case D3DRS_POINTSCALE_B:
+				renderer->setPointScaleB((float&)value);
+				break;
+			case D3DRS_POINTSCALE_C:
+				renderer->setPointScaleC((float&)value);
+				break;
+			case D3DRS_MULTISAMPLEANTIALIAS:
+			//	if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_MULTISAMPLEMASK:
+				SetRenderTarget(0, renderTarget[0]);   // Sets the multi-sample mask, if maskable
+				break;
+			case D3DRS_PATCHEDGESTYLE:
+				if(!init) if(value != D3DPATCHEDGE_DISCRETE) UNIMPLEMENTED();
+				break;
+			case D3DRS_DEBUGMONITORTOKEN:
+				if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_POINTSIZE_MAX:
+				renderer->setPointSizeMax((float&)value);
+				break;
+			case D3DRS_INDEXEDVERTEXBLENDENABLE:
+				renderer->setIndexedVertexBlendEnable(value != FALSE);
+				break;
+			case D3DRS_COLORWRITEENABLE:
+				renderer->setColorWriteMask(0, value & 0x0000000F);
+				break;
+			case D3DRS_TWEENFACTOR:
+				if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_BLENDOP:
+				switch(value)
+				{
+				case D3DBLENDOP_ADD:
+					renderer->setBlendOperation(sw::BLENDOP_ADD);
+					break;
+				case D3DBLENDOP_SUBTRACT:
+					renderer->setBlendOperation(sw::BLENDOP_SUB);
+					break;
+				case D3DBLENDOP_REVSUBTRACT:
+					renderer->setBlendOperation(sw::BLENDOP_INVSUB);
+					break;
+				case D3DBLENDOP_MIN:
+					renderer->setBlendOperation(sw::BLENDOP_MIN);
+					break;
+				case D3DBLENDOP_MAX:
+					renderer->setBlendOperation(sw::BLENDOP_MAX);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_POSITIONDEGREE:
+				if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_NORMALDEGREE:
+				if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_SCISSORTESTENABLE:
+				scissorEnable = (value != FALSE);
+				break;
+			case D3DRS_SLOPESCALEDEPTHBIAS:
+				renderer->setSlopeDepthBias((float&)value);
+				break;
+			case D3DRS_ANTIALIASEDLINEENABLE:
+				if(!init) if(value != FALSE) UNIMPLEMENTED();
+				break;
+			case D3DRS_MINTESSELLATIONLEVEL:
+				if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_MAXTESSELLATIONLEVEL:
+				if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_ADAPTIVETESS_X:
+				if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
+				break;
+			case D3DRS_ADAPTIVETESS_Y:
+				if(value == D3DFMT_ATOC)   // NVIDIA hack to enable transparency anti-aliasing
+				{
+					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
+				}
+				else if(value == D3DFMT_UNKNOWN)   // NVIDIA hack to disable transparency anti-aliasing
+				{
+					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
+				}
+				else
+				{
+					if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
+				}
+				break;
+			case D3DRS_ADAPTIVETESS_Z:
+				if(!init) if((float&)value != 1.0f) UNIMPLEMENTED();
+				break;
+			case D3DRS_ADAPTIVETESS_W:
+				if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
+				break;
+			case D3DRS_ENABLEADAPTIVETESSELLATION:
+				if(!init) UNIMPLEMENTED();
+				break;
+			case D3DRS_TWOSIDEDSTENCILMODE:
+				renderer->setTwoSidedStencil(value != FALSE);
+				break;
+			case D3DRS_CCW_STENCILFAIL:
+				switch(value)
+				{
+				case D3DSTENCILOP_KEEP:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_KEEP);
+					break;
+				case D3DSTENCILOP_ZERO:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_ZERO);
+					break;
+				case D3DSTENCILOP_REPLACE:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_REPLACE);
+					break;
+				case D3DSTENCILOP_INCRSAT:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_INCRSAT);
+					break;
+				case D3DSTENCILOP_DECRSAT:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_DECRSAT);
+					break;
+				case D3DSTENCILOP_INVERT:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_INVERT);
+					break;
+				case D3DSTENCILOP_INCR:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_INCR);
+					break;
+				case D3DSTENCILOP_DECR:
+					renderer->setStencilFailOperationCCW(sw::OPERATION_DECR);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_CCW_STENCILZFAIL:
+				switch(value)
+				{
+				case D3DSTENCILOP_KEEP:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_KEEP);
+					break;
+				case D3DSTENCILOP_ZERO:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_ZERO);
+					break;
+				case D3DSTENCILOP_REPLACE:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_REPLACE);
+					break;
+				case D3DSTENCILOP_INCRSAT:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_INCRSAT);
+					break;
+				case D3DSTENCILOP_DECRSAT:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_DECRSAT);
+					break;
+				case D3DSTENCILOP_INVERT:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_INVERT);
+					break;
+				case D3DSTENCILOP_INCR:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_INCR);
+					break;
+				case D3DSTENCILOP_DECR:
+					renderer->setStencilZFailOperationCCW(sw::OPERATION_DECR);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_CCW_STENCILPASS:
+				switch(value)
+				{
+				case D3DSTENCILOP_KEEP:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_KEEP);
+					break;
+				case D3DSTENCILOP_ZERO:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_ZERO);
+					break;
+				case D3DSTENCILOP_REPLACE:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_REPLACE);
+					break;
+				case D3DSTENCILOP_INCRSAT:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_INCRSAT);
+					break;
+				case D3DSTENCILOP_DECRSAT:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_DECRSAT);
+					break;
+				case D3DSTENCILOP_INVERT:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_INVERT);
+					break;
+				case D3DSTENCILOP_INCR:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_INCR);
+					break;
+				case D3DSTENCILOP_DECR:
+					renderer->setStencilPassOperationCCW(sw::OPERATION_DECR);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_CCW_STENCILFUNC:
+				switch(value)
+				{
+				case D3DCMP_NEVER:
+					renderer->setStencilCompareCCW(sw::STENCIL_NEVER);
+					break;
+				case D3DCMP_LESS:
+					renderer->setStencilCompareCCW(sw::STENCIL_LESS);
+					break;
+				case D3DCMP_EQUAL:
+					renderer->setStencilCompareCCW(sw::STENCIL_EQUAL);
+					break;
+				case D3DCMP_LESSEQUAL:
+					renderer->setStencilCompareCCW(sw::STENCIL_LESSEQUAL);
+					break;
+				case D3DCMP_GREATER:
+					renderer->setStencilCompareCCW(sw::STENCIL_GREATER);
+					break;
+				case D3DCMP_NOTEQUAL:
+					renderer->setStencilCompareCCW(sw::STENCIL_NOTEQUAL);
+					break;
+				case D3DCMP_GREATEREQUAL:
+					renderer->setStencilCompareCCW(sw::STENCIL_GREATEREQUAL);
+					break;
+				case D3DCMP_ALWAYS:
+					renderer->setStencilCompareCCW(sw::STENCIL_ALWAYS);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_COLORWRITEENABLE1:
+				renderer->setColorWriteMask(1, value);
+				break;
+			case D3DRS_COLORWRITEENABLE2:
+				renderer->setColorWriteMask(2, value);
+				break;
+			case D3DRS_COLORWRITEENABLE3:
+				renderer->setColorWriteMask(3, value);
+				break;
+			case D3DRS_BLENDFACTOR:
+				renderer->setBlendConstant(sw::Color<float>(value));
+				break;
+			case D3DRS_SRGBWRITEENABLE:
+				renderer->setWriteSRGB(value != FALSE);
+				break;
+			case D3DRS_DEPTHBIAS:
+				renderer->setDepthBias((float&)value);
+				break;
+			case D3DRS_WRAP8:
+				renderer->setTextureWrap(8, value);
+				break;
+			case D3DRS_WRAP9:
+				renderer->setTextureWrap(9, value);
+				break;
+			case D3DRS_WRAP10:
+				renderer->setTextureWrap(10, value);
+				break;
+			case D3DRS_WRAP11:
+				renderer->setTextureWrap(11, value);
+				break;
+			case D3DRS_WRAP12:
+				renderer->setTextureWrap(12, value);
+				break;
+			case D3DRS_WRAP13:
+				renderer->setTextureWrap(13, value);
+				break;
+			case D3DRS_WRAP14:
+				renderer->setTextureWrap(14, value);
+				break;
+			case D3DRS_WRAP15:
+				renderer->setTextureWrap(15, value);
+				break;
+			case D3DRS_SEPARATEALPHABLENDENABLE:
+				renderer->setSeparateAlphaBlendEnable(value != FALSE);
+				break;
+			case D3DRS_SRCBLENDALPHA:
+				switch(value)
+				{
+				case D3DBLEND_ZERO:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_ZERO);
+					break;
+				case D3DBLEND_ONE:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_ONE);
+					break;
+				case D3DBLEND_SRCCOLOR:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCE);
+					break;
+				case D3DBLEND_INVSRCCOLOR:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCE);
+					break;
+				case D3DBLEND_SRCALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_INVSRCALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_DESTALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_DESTALPHA);
+					break;
+				case D3DBLEND_INVDESTALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
+					break;
+				case D3DBLEND_DESTCOLOR:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_DEST);
+					break;
+				case D3DBLEND_INVDESTCOLOR:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDEST);
+					break;
+				case D3DBLEND_SRCALPHASAT:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
+					break;
+				case D3DBLEND_BOTHSRCALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
+					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_BOTHINVSRCALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
+					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_BLENDFACTOR:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_CONSTANT);
+					break;
+				case D3DBLEND_INVBLENDFACTOR:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVCONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_DESTBLENDALPHA:
+				switch(value)
+				{
+				case D3DBLEND_ZERO:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_ZERO);
+					break;
+				case D3DBLEND_ONE:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_ONE);
+					break;
+				case D3DBLEND_SRCCOLOR:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCE);
+					break;
+				case D3DBLEND_INVSRCCOLOR:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCE);
+					break;
+				case D3DBLEND_SRCALPHA:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_INVSRCALPHA:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_DESTALPHA:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_DESTALPHA);
+					break;
+				case D3DBLEND_INVDESTALPHA:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
+					break;
+				case D3DBLEND_DESTCOLOR:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_DEST);
+					break;
+				case D3DBLEND_INVDESTCOLOR:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_INVDEST);
+					break;
+				case D3DBLEND_SRCALPHASAT:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
+					break;
+				case D3DBLEND_BOTHSRCALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
+					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
+					break;
+				case D3DBLEND_BOTHINVSRCALPHA:
+					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
+					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
+					break;
+				case D3DBLEND_BLENDFACTOR:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_CONSTANT);
+					break;
+				case D3DBLEND_INVBLENDFACTOR:
+					renderer->setDestBlendFactorAlpha(sw::BLEND_INVCONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DRS_BLENDOPALPHA:
+				switch(value)
+				{
+				case D3DBLENDOP_ADD:
+					renderer->setBlendOperationAlpha(sw::BLENDOP_ADD);
+					break;
+				case D3DBLENDOP_SUBTRACT:
+					renderer->setBlendOperationAlpha(sw::BLENDOP_SUB);
+					break;
+				case D3DBLENDOP_REVSUBTRACT:
+					renderer->setBlendOperationAlpha(sw::BLENDOP_INVSUB);
+					break;
+				case D3DBLENDOP_MIN:
+					renderer->setBlendOperationAlpha(sw::BLENDOP_MIN);
+					break;
+				case D3DBLENDOP_MAX:
+					renderer->setBlendOperationAlpha(sw::BLENDOP_MAX);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			default:
+				ASSERT(false);
+			}
+		}
+		else   // stateRecorder
+		{
+			stateRecorder->setRenderState(state, value);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetRenderTarget(unsigned long index, IDirect3DSurface9 *iRenderTarget)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long index = %d, IDirect3DSurface9 *newRenderTarget = 0x%0.8p", index, iRenderTarget);
+
+		// FIXME: Check for D3DUSAGE_RENDERTARGET
+
+		if(index >= 4 || (index == 0 && !iRenderTarget))
+		{
+			return INVALIDCALL();
+		}
+
+		Direct3DSurface9 *renderTarget = static_cast<Direct3DSurface9*>(iRenderTarget);
+
+		if(renderTarget)
+		{
+			renderTarget->bind();
+		}
+
+		if(this->renderTarget[index])
+		{
+			this->renderTarget[index]->unbind();
+		}
+
+		this->renderTarget[index] = renderTarget;
+
+		if(renderTarget && index == 0)
+		{
+			D3DSURFACE_DESC renderTargetDesc;
+			renderTarget->GetDesc(&renderTargetDesc);
+
+			// Reset viewport to size of current render target
+			viewport.X = 0;
+			viewport.Y = 0;
+			viewport.Width = renderTargetDesc.Width;
+			viewport.Height = renderTargetDesc.Height;
+			viewport.MinZ = 0;
+			viewport.MaxZ = 1;
+
+			// Reset scissor rectangle to size of current render target
+			scissorRect.left = 0;
+			scissorRect.top = 0;
+			scissorRect.right = renderTargetDesc.Width;
+			scissorRect.bottom = renderTargetDesc.Height;
+
+			// Set the multi-sample mask, if maskable
+			if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE &&
+			   renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONMASKABLE)
+			{
+				renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]);
+			}
+			else
+			{
+				renderer->setMultiSampleMask(0xFFFFFFFF);
+			}
+		}
+
+		renderer->setRenderTarget(index, renderTarget);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE state = %d, unsigned long value = %d", sampler, state, value);
+
+		if(state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)
+		{
+			return INVALIDCALL();
+		}
+
+		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+		{
+			return INVALIDCALL();
+		}
+
+		if(sampler >= D3DVERTEXTEXTURESAMPLER0)
+		{
+			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
+		}
+
+		if(!stateRecorder)
+		{
+			if(!init && samplerState[sampler][state] == value)
+			{
+				return D3D_OK;
+			}
+
+			samplerState[sampler][state] = value;
+
+			sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
+			int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group
+
+			switch(state)
+			{
+			case D3DSAMP_ADDRESSU:
+				switch(value)
+				{
+				case D3DTADDRESS_WRAP:
+					renderer->setAddressingModeU(type, index, sw::ADDRESSING_WRAP);
+					break;
+				case D3DTADDRESS_MIRROR:
+					renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRROR);
+					break;
+				case D3DTADDRESS_CLAMP:
+					renderer->setAddressingModeU(type, index, sw::ADDRESSING_CLAMP);
+					break;
+				case D3DTADDRESS_BORDER:
+					renderer->setAddressingModeU(type, index, sw::ADDRESSING_BORDER);
+					break;
+				case D3DTADDRESS_MIRRORONCE:
+					renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRRORONCE);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DSAMP_ADDRESSV:
+				switch(value)
+				{
+				case D3DTADDRESS_WRAP:
+					renderer->setAddressingModeV(type, index, sw::ADDRESSING_WRAP);
+					break;
+				case D3DTADDRESS_MIRROR:
+					renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRROR);
+					break;
+				case D3DTADDRESS_CLAMP:
+					renderer->setAddressingModeV(type, index, sw::ADDRESSING_CLAMP);
+					break;
+				case D3DTADDRESS_BORDER:
+					renderer->setAddressingModeV(type, index, sw::ADDRESSING_BORDER);
+					break;
+				case D3DTADDRESS_MIRRORONCE:
+					renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRRORONCE);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DSAMP_ADDRESSW:
+				switch(value)
+				{
+				case D3DTADDRESS_WRAP:
+					renderer->setAddressingModeW(type, index, sw::ADDRESSING_WRAP);
+					break;
+				case D3DTADDRESS_MIRROR:
+					renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRROR);
+					break;
+				case D3DTADDRESS_CLAMP:
+					renderer->setAddressingModeW(type, index, sw::ADDRESSING_CLAMP);
+					break;
+				case D3DTADDRESS_BORDER:
+					renderer->setAddressingModeW(type, index, sw::ADDRESSING_BORDER);
+					break;
+				case D3DTADDRESS_MIRRORONCE:
+					renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRRORONCE);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DSAMP_BORDERCOLOR:
+				renderer->setBorderColor(type, index, value);
+				break;
+			case D3DSAMP_MAGFILTER:
+				// NOTE: SwiftShader does not differentiate between minification and magnification filter
+				switch(value)
+				{
+				case D3DTEXF_NONE:
+					renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter
+					break;
+				case D3DTEXF_POINT:
+					renderer->setTextureFilter(type, index, sw::FILTER_POINT);
+					break;
+				case D3DTEXF_LINEAR:
+					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
+					break;
+				case D3DTEXF_ANISOTROPIC:
+					renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
+					break;
+				case D3DTEXF_PYRAMIDALQUAD:
+					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
+					break;
+				case D3DTEXF_GAUSSIANQUAD:
+					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
+					break;
+				default:
+					return INVALIDCALL();
+				};
+				break;
+			case D3DSAMP_MINFILTER:
+				// NOTE: SwiftShader does not differentiate between minification and magnification filter
+				switch(value)
+				{
+				case D3DTEXF_NONE:
+					renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter
+					break;
+				case D3DTEXF_POINT:
+					renderer->setTextureFilter(type, index, sw::FILTER_POINT);
+					break;
+				case D3DTEXF_LINEAR:
+					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
+					break;
+				case D3DTEXF_ANISOTROPIC:
+					renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
+					break;
+				case D3DTEXF_PYRAMIDALQUAD:
+					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
+					break;
+				case D3DTEXF_GAUSSIANQUAD:
+					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
+					break;
+				default:
+					return INVALIDCALL();
+				};
+				break;
+			case D3DSAMP_MIPFILTER:
+				switch(value)
+				{
+				case D3DTEXF_NONE:
+					renderer->setMipmapFilter(type, index, sw::MIPMAP_NONE);
+					break;
+				case D3DTEXF_POINT:
+					renderer->setMipmapFilter(type, index, sw::MIPMAP_POINT);
+					break;
+				case D3DTEXF_LINEAR:
+					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);
+					break;
+				case D3DTEXF_ANISOTROPIC:
+					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
+					break;
+				case D3DTEXF_PYRAMIDALQUAD:
+					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
+					break;
+				case D3DTEXF_GAUSSIANQUAD:
+					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
+					break;
+				default:
+					return INVALIDCALL();
+				};
+				break;
+			case D3DSAMP_MIPMAPLODBIAS:
+				if(value == D3DFMT_GET4)   // ATI hack to enable Fetch4
+				{
+					renderer->setGatherEnable(type, index, true);
+				}
+				else if(value == D3DFMT_GET1)   // ATI hack to disable Fetch4
+				{
+					renderer->setGatherEnable(type, index, false);
+				}
+				else
+				{
+					float LOD = (float&)value - sw::log2((float)context->renderTarget[0]->getSuperSampleCount());   // FIXME: Update when render target changes
+					renderer->setMipmapLOD(type, index, LOD);
+				}
+				break;
+			case D3DSAMP_MAXMIPLEVEL:
+				break;
+			case D3DSAMP_MAXANISOTROPY:
+				renderer->setMaxAnisotropy(type, index, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy));
+				break;
+			case D3DSAMP_SRGBTEXTURE:
+				renderer->setReadSRGB(type, index, value != FALSE);
+				break;
+			case D3DSAMP_ELEMENTINDEX:
+				if(!init) UNIMPLEMENTED();   // Multi-element textures deprecated in favor of multiple render targets
+				break;
+			case D3DSAMP_DMAPOFFSET:
+			//	if(!init) UNIMPLEMENTED();
+				break;
+			default:
+				ASSERT(false);
+			}
+		}
+		else   // stateRecorder
+		{
+			stateRecorder->setSamplerState(sampler, state, value);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetScissorRect(const RECT *rect)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const RECT *rect = 0x%0.8p", rect);
+
+		if(!rect)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			scissorRect = *rect;
+		}
+		else
+		{
+			stateRecorder->setScissorRect(rect);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetSoftwareVertexProcessing(int software)
+	{
+		CriticalSection cs(this);
+
+		TRACE("int software = %d", software);
+
+		if(behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING && software == FALSE)
+		{
+			return INVALIDCALL();
+		}
+
+		if(behaviourFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && software == TRUE)
+		{
+			return INVALIDCALL();
+		}
+
+		softwareVertexProcessing = (software != FALSE);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *iVertexBuffer, unsigned int offset, unsigned int stride)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int stream = %d, IDirect3DVertexBuffer9 *data = 0x%0.8p, unsigned int offset = %d, unsigned int stride = %d", stream, iVertexBuffer, offset, stride);
+
+		Direct3DVertexBuffer9 *vertexBuffer = static_cast<Direct3DVertexBuffer9*>(iVertexBuffer);
+
+		if(!stateRecorder)
+		{
+			if(dataStream[stream] == vertexBuffer && streamOffset[stream] == offset && streamStride[stream] == stride)
+			{
+				return D3D_OK;
+			}
+
+			if(vertexBuffer)
+			{
+				vertexBuffer->bind();
+			}
+
+			if(dataStream[stream])
+			{
+				dataStream[stream]->unbind();
+			}
+
+			dataStream[stream] = vertexBuffer;
+			streamOffset[stream] = offset;
+			streamStride[stream] = stride;
+		}
+		else
+		{
+			stateRecorder->setStreamSource(stream, vertexBuffer, offset, stride);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int streamNumber = %d, unsigned int divider = %d", streamNumber, divider);
+
+		if(!instancingEnabled)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			streamSourceFreq[streamNumber] = divider;
+		}
+		else
+		{
+			stateRecorder->setStreamSourceFreq(streamNumber, divider);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);
+
+		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+		{
+			return INVALIDCALL();
+		}
+
+		if(sampler >= D3DVERTEXTEXTURESAMPLER0)
+		{
+			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
+		}
+
+		Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(iBaseTexture);
+
+		if(!stateRecorder)
+		{
+			if(texture[sampler] == baseTexture)
+			{
+				return D3D_OK;
+			}
+
+			if(baseTexture)
+			{
+				baseTexture->bind();   // FIXME: Bind individual sub-surfaces?
+			}
+
+			if(texture[sampler])
+			{
+				texture[sampler]->unbind();
+			}
+
+			texture[sampler] = baseTexture;
+		}
+		else
+		{
+			stateRecorder->setTexture(sampler, baseTexture);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);
+
+		if(stage < 0 || stage >= 8 || type < D3DTSS_COLOROP || type > D3DTSS_CONSTANT)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			if(!init && textureStageState[stage][type] == value)
+			{
+				return D3D_OK;
+			}
+
+			textureStageState[stage][type] = value;
+
+			switch(type)
+			{
+			case D3DTSS_COLOROP:
+				switch(value)
+				{
+				case D3DTOP_DISABLE:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE);
+					break;
+				case D3DTOP_SELECTARG1:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1);
+					break;
+				case D3DTOP_SELECTARG2:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2);
+					break;
+				case D3DTOP_MODULATE:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE);
+					break;
+				case D3DTOP_MODULATE2X:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X);
+					break;
+				case D3DTOP_MODULATE4X:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X);
+					break;
+				case D3DTOP_ADD:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD);
+					break;
+				case D3DTOP_ADDSIGNED:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED);
+					break;
+				case D3DTOP_ADDSIGNED2X:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
+					break;
+				case D3DTOP_SUBTRACT:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT);
+					break;
+				case D3DTOP_ADDSMOOTH:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH);
+					break;
+				case D3DTOP_BLENDDIFFUSEALPHA:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
+					break;
+				case D3DTOP_BLENDTEXTUREALPHA:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
+					break;
+				case D3DTOP_BLENDFACTORALPHA:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
+					break;
+				case D3DTOP_BLENDTEXTUREALPHAPM:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
+					break;
+				case D3DTOP_BLENDCURRENTALPHA:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
+					break;
+				case D3DTOP_PREMODULATE:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE);
+					break;
+				case D3DTOP_MODULATEALPHA_ADDCOLOR:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
+					break;
+				case D3DTOP_MODULATECOLOR_ADDALPHA:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
+					break;
+				case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
+					break;
+				case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
+					break;
+				case D3DTOP_BUMPENVMAP:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP);
+					break;
+				case D3DTOP_BUMPENVMAPLUMINANCE:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
+					break;
+				case D3DTOP_DOTPRODUCT3:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3);
+					break;
+				case D3DTOP_MULTIPLYADD:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD);
+					break;
+				case D3DTOP_LERP:
+					renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_COLORARG1:
+				switch(value & D3DTA_SELECTMASK)
+				{
+				case D3DTA_DIFFUSE:
+					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
+					break;
+				case D3DTA_CURRENT:
+					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT);
+					break;
+				case D3DTA_TEXTURE:
+					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
+					break;
+				case D3DTA_TFACTOR:
+					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
+					break;
+				case D3DTA_SPECULAR:
+					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
+					break;
+				case D3DTA_TEMP:
+					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP);
+					break;
+				case D3DTA_CONSTANT:
+					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+
+				switch(value & ~D3DTA_SELECTMASK)
+				{
+				case 0:
+					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR);
+					break;
+				case D3DTA_COMPLEMENT:
+					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+					break;
+				case D3DTA_ALPHAREPLICATE:
+					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
+					break;
+				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_COLORARG2:
+				switch(value & D3DTA_SELECTMASK)
+				{
+				case D3DTA_DIFFUSE:
+					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
+					break;
+				case D3DTA_CURRENT:
+					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT);
+					break;
+				case D3DTA_TEXTURE:
+					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
+					break;
+				case D3DTA_TFACTOR:
+					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
+					break;
+				case D3DTA_SPECULAR:
+					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
+					break;
+				case D3DTA_TEMP:
+					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP);
+					break;
+				case D3DTA_CONSTANT:
+					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+
+				switch(value & ~D3DTA_SELECTMASK)
+				{
+				case 0:
+					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR);
+					break;
+				case D3DTA_COMPLEMENT:
+					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+					break;
+				case D3DTA_ALPHAREPLICATE:
+					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
+					break;
+				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_ALPHAOP:
+				switch(value)
+				{
+				case D3DTOP_DISABLE:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE);
+					break;
+				case D3DTOP_SELECTARG1:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1);
+					break;
+				case D3DTOP_SELECTARG2:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2);
+					break;
+				case D3DTOP_MODULATE:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE);
+					break;
+				case D3DTOP_MODULATE2X:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X);
+					break;
+				case D3DTOP_MODULATE4X:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X);
+					break;
+				case D3DTOP_ADD:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD);
+					break;
+				case D3DTOP_ADDSIGNED:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED);
+					break;
+				case D3DTOP_ADDSIGNED2X:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
+					break;
+				case D3DTOP_SUBTRACT:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT);
+					break;
+				case D3DTOP_ADDSMOOTH:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH);
+					break;
+				case D3DTOP_BLENDDIFFUSEALPHA:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
+					break;
+				case D3DTOP_BLENDTEXTUREALPHA:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
+					break;
+				case D3DTOP_BLENDFACTORALPHA:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
+					break;
+				case D3DTOP_BLENDTEXTUREALPHAPM:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
+					break;
+				case D3DTOP_BLENDCURRENTALPHA:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
+					break;
+				case D3DTOP_PREMODULATE:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE);
+					break;
+				case D3DTOP_MODULATEALPHA_ADDCOLOR:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
+					break;
+				case D3DTOP_MODULATECOLOR_ADDALPHA:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
+					break;
+				case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
+					break;
+				case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
+					break;
+				case D3DTOP_BUMPENVMAP:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP);
+					break;
+				case D3DTOP_BUMPENVMAPLUMINANCE:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
+					break;
+				case D3DTOP_DOTPRODUCT3:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3);
+					break;
+				case D3DTOP_MULTIPLYADD:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD);
+					break;
+				case D3DTOP_LERP:
+					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_ALPHAARG1:
+				switch(value & D3DTA_SELECTMASK)
+				{
+				case D3DTA_DIFFUSE:
+					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
+					break;
+				case D3DTA_CURRENT:
+					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
+					break;
+				case D3DTA_TEXTURE:
+					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
+					break;
+				case D3DTA_TFACTOR:
+					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
+					break;
+				case D3DTA_SPECULAR:
+					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
+					break;
+				case D3DTA_TEMP:
+					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
+					break;
+				case D3DTA_CONSTANT:
+					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+
+				switch(value & ~D3DTA_SELECTMASK)
+				{
+				case 0:
+					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
+					break;
+				case D3DTA_COMPLEMENT:
+					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+					break;
+				case D3DTA_ALPHAREPLICATE:
+					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
+					break;
+				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_ALPHAARG2:
+				switch(value & D3DTA_SELECTMASK)
+				{
+				case D3DTA_DIFFUSE:
+					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
+					break;
+				case D3DTA_CURRENT:
+					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
+					break;
+				case D3DTA_TEXTURE:
+					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
+					break;
+				case D3DTA_TFACTOR:
+					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
+					break;
+				case D3DTA_SPECULAR:
+					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
+					break;
+				case D3DTA_TEMP:
+					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
+					break;
+				case D3DTA_CONSTANT:
+					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+
+				switch(value & ~D3DTA_SELECTMASK)
+				{
+				case 0:
+					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
+					break;
+				case D3DTA_COMPLEMENT:
+					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+					break;
+				case D3DTA_ALPHAREPLICATE:
+					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
+					break;
+				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_BUMPENVMAT00:
+				renderer->setBumpmapMatrix(stage, 0, (float&)value);
+				break;
+			case D3DTSS_BUMPENVMAT01:
+				renderer->setBumpmapMatrix(stage, 1, (float&)value);
+				break;
+			case D3DTSS_BUMPENVMAT10:
+				renderer->setBumpmapMatrix(stage, 2, (float&)value);
+				break;
+			case D3DTSS_BUMPENVMAT11:
+				renderer->setBumpmapMatrix(stage, 3, (float&)value);
+				break;
+			case D3DTSS_TEXCOORDINDEX:
+				renderer->setTexCoordIndex(stage, value & 0x0000FFFF);
+
+				switch(value & 0xFFFF0000)
+				{
+				case D3DTSS_TCI_PASSTHRU:
+					renderer->setTexGen(stage, sw::TEXGEN_PASSTHRU);
+					break;
+				case D3DTSS_TCI_CAMERASPACENORMAL:
+					renderer->setTexCoordIndex(stage, stage);
+					renderer->setTexGen(stage, sw::TEXGEN_NORMAL);
+					break;
+				case D3DTSS_TCI_CAMERASPACEPOSITION:
+					renderer->setTexCoordIndex(stage, stage);
+					renderer->setTexGen(stage, sw::TEXGEN_POSITION);
+					break;
+				case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
+					renderer->setTexCoordIndex(stage, stage);
+					renderer->setTexGen(stage, sw::TEXGEN_REFLECTION);
+					break;
+				case D3DTSS_TCI_SPHEREMAP:
+					renderer->setTexCoordIndex(stage, stage);
+					renderer->setTexGen(stage, sw::TEXGEN_SPHEREMAP);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_BUMPENVLSCALE:
+				renderer->setLuminanceScale(stage, (float&)value);
+				break;
+			case D3DTSS_BUMPENVLOFFSET:
+				renderer->setLuminanceOffset(stage, (float&)value);
+				break;
+			case D3DTSS_TEXTURETRANSFORMFLAGS:
+				switch(value & ~D3DTTFF_PROJECTED)
+				{
+				case D3DTTFF_DISABLE:
+					renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+					break;
+				case D3DTTFF_COUNT1:
+					renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+					break;
+				case D3DTTFF_COUNT2:
+					renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+					break;
+				case D3DTTFF_COUNT3:
+					renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+					break;
+				case D3DTTFF_COUNT4:
+					renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_COLORARG0:
+				switch(value & D3DTA_SELECTMASK)
+				{
+				case D3DTA_CURRENT:
+					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT);
+					break;
+				case D3DTA_DIFFUSE:
+					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
+					break;
+				case D3DTA_SPECULAR:
+					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
+					break;
+				case D3DTA_TEMP:
+					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP);
+					break;
+				case D3DTA_TEXTURE:
+					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
+					break;
+				case D3DTA_TFACTOR:
+					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
+					break;
+				default:
+					ASSERT(false);
+				}
+
+				switch(value & ~D3DTA_SELECTMASK)
+				{
+				case 0:
+					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR);
+					break;
+				case D3DTA_COMPLEMENT:
+					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+					break;
+				case D3DTA_ALPHAREPLICATE:
+					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
+					break;
+				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_ALPHAARG0:
+				switch(value & D3DTA_SELECTMASK)
+				{
+				case D3DTA_DIFFUSE:
+					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
+					break;
+				case D3DTA_CURRENT:
+					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
+					break;
+				case D3DTA_TEXTURE:
+					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
+					break;
+				case D3DTA_TFACTOR:
+					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
+					break;
+				case D3DTA_SPECULAR:
+					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
+					break;
+				case D3DTA_TEMP:
+					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
+					break;
+				case D3DTA_CONSTANT:
+					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
+					break;
+				default:
+					ASSERT(false);
+				}
+
+				switch(value & ~D3DTA_SELECTMASK)
+				{
+				case 0:
+					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
+					break;
+				case D3DTA_COMPLEMENT:
+					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+					break;
+				case D3DTA_ALPHAREPLICATE:
+					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
+					break;
+				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_RESULTARG:
+				switch(value & D3DTA_SELECTMASK)
+				{
+				case D3DTA_CURRENT:
+					renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT);
+					break;
+				case D3DTA_TEMP:
+					renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP);
+					break;
+				default:
+					ASSERT(false);
+				}
+				break;
+			case D3DTSS_CONSTANT:
+				renderer->setConstantColor(stage, value);
+				break;
+			default:
+				ASSERT(false);
+			}
+		}
+		else   // stateRecorder
+		{
+			stateRecorder->setTextureStageState(stage, type, value);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+	{
+		CriticalSection cs(this);
+
+		TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+		if(!matrix)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			this->matrix[state] = *matrix;
+
+			sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
+			             matrix->_12, matrix->_22, matrix->_32, matrix->_42,
+			             matrix->_13, matrix->_23, matrix->_33, matrix->_43,
+			             matrix->_14, matrix->_24, matrix->_34, matrix->_44);
+
+			switch(state)
+			{
+			case D3DTS_WORLD:
+				renderer->setModelMatrix(M);
+				break;
+			case D3DTS_VIEW:
+				renderer->setViewMatrix(M);
+				break;
+			case D3DTS_PROJECTION:
+				renderer->setProjectionMatrix(M);
+				break;
+			case D3DTS_TEXTURE0:
+				renderer->setTextureMatrix(0, M);
+				break;
+			case D3DTS_TEXTURE1:
+				renderer->setTextureMatrix(1, M);
+				break;
+			case D3DTS_TEXTURE2:
+				renderer->setTextureMatrix(2, M);
+				break;
+			case D3DTS_TEXTURE3:
+				renderer->setTextureMatrix(3, M);
+				break;
+			case D3DTS_TEXTURE4:
+				renderer->setTextureMatrix(4, M);
+				break;
+			case D3DTS_TEXTURE5:
+				renderer->setTextureMatrix(5, M);
+				break;
+			case D3DTS_TEXTURE6:
+				renderer->setTextureMatrix(6, M);
+				break;
+			case D3DTS_TEXTURE7:
+				renderer->setTextureMatrix(7, M);
+				break;
+			default:
+				if(state > 256 && state < 512)
+				{
+					renderer->setModelMatrix(M, state - 256);
+				}
+				else ASSERT(false);
+			}
+		}
+		else   // stateRecorder
+		{
+			stateRecorder->setTransform(state, matrix);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *iVertexDeclaration)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DVertexDeclaration9 *declaration = 0x%0.8p", iVertexDeclaration);
+
+		Direct3DVertexDeclaration9 *vertexDeclaration = static_cast<Direct3DVertexDeclaration9*>(iVertexDeclaration);
+
+		if(!stateRecorder)
+		{
+			if(this->vertexDeclaration == vertexDeclaration)
+			{
+				return D3D_OK;
+			}
+
+			if(vertexDeclaration)
+			{
+				vertexDeclaration->bind();
+			}
+
+			if(this->vertexDeclaration)
+			{
+				this->vertexDeclaration->unbind();
+			}
+
+			this->vertexDeclaration = vertexDeclaration;
+		}
+		else
+		{
+			stateRecorder->setVertexDeclaration(vertexDeclaration);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetVertexShader(IDirect3DVertexShader9 *iVertexShader)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DVertexShader9 *shader = 0x%0.8p", iVertexShader);
+
+		Direct3DVertexShader9 *vertexShader = static_cast<Direct3DVertexShader9*>(iVertexShader);
+
+		if(!stateRecorder)
+		{
+			if(this->vertexShader == vertexShader)
+			{
+				return D3D_OK;
+			}
+
+			if(vertexShader)
+			{
+				vertexShader->bind();
+			}
+
+			if(this->vertexShader)
+			{
+				this->vertexShader->unbind();
+			}
+
+			this->vertexShader = vertexShader;
+			vertexShaderDirty = true;
+		}
+		else
+		{
+			stateRecorder->setVertexShader(vertexShader);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+			{
+				vertexShaderConstantB[startRegister + i] = constantData[i];
+			}
+
+			vertexShaderConstantsBDirty = sw::max(startRegister + count, vertexShaderConstantsBDirty);
+			vertexShaderDirty = true;   // Reload DEF constants
+		}
+		else
+		{
+			stateRecorder->setVertexShaderConstantB(startRegister, constantData, count);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			for(unsigned int i = 0; i < count && startRegister + i < MAX_VERTEX_SHADER_CONST; 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 = sw::max(startRegister + count, vertexShaderConstantsFDirty);
+			vertexShaderDirty = true;   // Reload DEF constants
+		}
+		else
+		{
+			stateRecorder->setVertexShaderConstantF(startRegister, constantData, count);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		if(!constantData)
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+			{
+				vertexShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
+				vertexShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
+				vertexShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
+				vertexShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
+			}
+
+			vertexShaderConstantsIDirty = sw::max(startRegister + count, vertexShaderConstantsIDirty);
+			vertexShaderDirty = true;   // Reload DEF constants
+		}
+		else
+		{
+			stateRecorder->setVertexShaderConstantI(startRegister, constantData, count);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::SetViewport(const D3DVIEWPORT9 *viewport)
+	{
+		CriticalSection cs(this);
+
+		TRACE("const D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
+
+		if(!viewport)   // FIXME: Check if valid
+		{
+			return INVALIDCALL();
+		}
+
+		if(!stateRecorder)
+		{
+			this->viewport = *viewport;
+		}
+		else
+		{
+			stateRecorder->setViewport(viewport);
+		}
+
+		return D3D_OK;
+	}
+
+	int Direct3DDevice9::ShowCursor(int show)
+	{
+		CriticalSection cs(this);
+
+		TRACE("int show = %d", show);
+
+		int oldValue = showCursor ? TRUE : FALSE;
+		showCursor = show != FALSE;
+
+		if(showCursor)
+		{
+			sw::FrameBuffer::setCursorImage(cursor);
+		}
+		else
+		{
+			sw::FrameBuffer::setCursorImage(0);
+		}
+
+		return oldValue;
+	}
+
+	long Direct3DDevice9::StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p, const RECT *destRect = 0x%0.8p, D3DTEXTUREFILTERTYPE filter = %d", sourceSurface, sourceRect, destSurface, destRect, filter);
+
+		if(!sourceSurface || !destSurface || !validRectangle(sourceRect, sourceSurface) || !validRectangle(destRect, destSurface))
+		{
+			return INVALIDCALL();
+		}
+
+		D3DSURFACE_DESC sourceDescription;
+		D3DSURFACE_DESC destDescription;
+
+		sourceSurface->GetDesc(&sourceDescription);
+		destSurface->GetDesc(&destDescription);
+
+		if(sourceDescription.Pool != D3DPOOL_DEFAULT || destDescription.Pool != D3DPOOL_DEFAULT)
+		{
+			return INVALIDCALL();
+		}
+
+		Direct3DSurface9 *source = static_cast<Direct3DSurface9*>(sourceSurface);
+		Direct3DSurface9 *dest = static_cast<Direct3DSurface9*>(destSurface);
+
+		stretchRect(source, sourceRect, dest, destRect, filter);
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::TestCooperativeLevel()
+	{
+		CriticalSection cs(this);
+
+		TRACE("void");
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destinationSurface = 0x%0.8p, const POINT *destPoint = 0x%0.8p", sourceSurface, sourceRect, destinationSurface, destPoint);
+
+		if(!sourceSurface || !destinationSurface)
+		{
+			return INVALIDCALL();
+		}
+
+		D3DSURFACE_DESC sourceDescription;
+		D3DSURFACE_DESC destinationDescription;
+
+		sourceSurface->GetDesc(&sourceDescription);
+		destinationSurface->GetDesc(&destinationDescription);
+
+		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 = sourceDescription.Width;
+			sRect.bottom = sourceDescription.Height;
+		}
+
+		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))
+		{
+			return INVALIDCALL();
+		}
+
+		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(sourceDescription.MultiSampleType      != D3DMULTISAMPLE_NONE ||
+		   destinationDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||
+		// sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||   // FIXME: Check back buffer and depth buffer memory pool flags
+		// destinationDescription.Pool != D3DPOOL_DEFAULT ||
+		   sourceDescription.Format != destinationDescription.Format)
+		{
+			return INVALIDCALL();
+		}
+
+		sw::Surface *source = static_cast<Direct3DSurface9*>(sourceSurface);
+		sw::Surface *dest = static_cast<Direct3DSurface9*>(destinationSurface);
+
+		unsigned char *sBuffer = (unsigned char*)source->lockExternal(sRect.left, sRect.top, 0, sw::LOCK_READONLY, sw::PUBLIC);
+		unsigned char *dBuffer = (unsigned char*)dest->lockExternal(dRect.left, dRect.top, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
+		int sPitch = source->getExternalPitchB();
+		int dPitch = dest->getExternalPitchB();
+
+		unsigned int width;
+		unsigned int height;
+		unsigned int bytes;
+
+		switch(sourceDescription.Format)
+		{
+		case D3DFMT_DXT1:
+		case D3DFMT_ATI1:
+			width = (dWidth + 3) / 4;
+			height = (dHeight + 3) / 4;
+			bytes = width * 8;   // 64 bit per 4x4 block
+			break;
+		case D3DFMT_DXT2:
+		case D3DFMT_DXT3:
+		case D3DFMT_DXT4:
+		case D3DFMT_DXT5:
+		case D3DFMT_ATI2:
+			width = (dWidth + 3) / 4;
+			height = (dHeight + 3) / 4;
+			bytes = width * 16;   // 128 bit per 4x4 block
+			break;
+		default:
+			width = dWidth;
+			height = dHeight;
+			bytes = width * Direct3DSurface9::bytes(sourceDescription.Format);
+		}
+
+		if(sourceDescription.Format == D3DFMT_ATI1 || sourceDescription.Format == D3DFMT_ATI2)
+		{
+			// Make the pitch correspond to 4 rows
+			sPitch *= 4;
+			dPitch *= 4;
+		}
+
+		for(unsigned int y = 0; y < height; y++)
+		{
+			memcpy(dBuffer, sBuffer, bytes);
+
+			sBuffer += sPitch;
+			dBuffer += dPitch;
+		}
+
+		source->unlockExternal();
+		dest->unlockExternal();
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture)
+	{
+		CriticalSection cs(this);
+
+		TRACE("IDirect3DBaseTexture9 *sourceTexture = 0x%0.8p, IDirect3DBaseTexture9 *destinationTexture = 0x%0.8p", sourceTexture, destinationTexture);
+
+		if(!sourceTexture || !destinationTexture)
+		{
+			return INVALIDCALL();
+		}
+
+		// FIXME: Check memory pools
+
+		D3DRESOURCETYPE type = sourceTexture->GetType();
+
+		if(type != destinationTexture->GetType())
+		{
+			return INVALIDCALL();
+		}
+
+		switch(type)
+		{
+		case D3DRTYPE_TEXTURE:
+			{
+				IDirect3DTexture9 *source;
+				IDirect3DTexture9 *dest;
+
+				sourceTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&source);
+				destinationTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&dest);
+
+				ASSERT(source && dest);
+
+				for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
+				{
+					IDirect3DSurface9 *sourceSurface;
+					IDirect3DSurface9 *destinationSurface;
+
+					source->GetSurfaceLevel(level, &sourceSurface);
+					dest->GetSurfaceLevel(level, &destinationSurface);
+
+					UpdateSurface(sourceSurface, 0, destinationSurface, 0);
+
+					sourceSurface->Release();
+					destinationSurface->Release();
+				}
+
+				source->Release();
+				dest->Release();
+			}
+			break;
+		case D3DRTYPE_VOLUMETEXTURE:
+			{
+				IDirect3DVolumeTexture9 *source;
+				IDirect3DVolumeTexture9 *dest;
+
+				sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&source);
+				destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&dest);
+
+				ASSERT(source && dest);
+
+				for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
+				{
+					IDirect3DVolume9 *sourceVolume;
+					IDirect3DVolume9 *destinationVolume;
+
+					source->GetVolumeLevel(level, &sourceVolume);
+					dest->GetVolumeLevel(level, &destinationVolume);
+
+					updateVolume(sourceVolume, destinationVolume);
+
+					sourceVolume->Release();
+					destinationVolume->Release();
+				}
+
+				source->Release();
+				dest->Release();
+			}
+			break;
+		case D3DRTYPE_CUBETEXTURE:
+			{
+				IDirect3DCubeTexture9 *source;
+				IDirect3DCubeTexture9 *dest;
+
+				sourceTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&source);
+				destinationTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&dest);
+
+				ASSERT(source && dest);
+
+				for(int face = 0; face < 6; face++)
+				{
+					for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
+					{
+						IDirect3DSurface9 *sourceSurface;
+						IDirect3DSurface9 *destinationSurface;
+
+						source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface);
+						dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface);
+
+						UpdateSurface(sourceSurface, 0, destinationSurface, 0);
+
+						sourceSurface->Release();
+						destinationSurface->Release();
+					}
+				}
+
+				source->Release();
+				dest->Release();
+			}
+			break;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::ValidateDevice(unsigned long *numPasses)
+	{
+		CriticalSection cs(this);
+
+		TRACE("unsigned long *numPasses = 0x%0.8p", numPasses);
+
+		if(!numPasses)
+		{
+			return INVALIDCALL();
+		}
+
+		*numPasses = 1;
+
+		return D3D_OK;
+	}
+
+	long Direct3DDevice9::getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
+	{
+		return d3d9->GetAdapterDisplayMode(adapter, mode);
+	}
+
+	int Direct3DDevice9::typeStride(unsigned char streamType)
+	{
+		static int LUT[] =
+		{
+			4,	// D3DDECLTYPE_FLOAT1    =  0,  // 1D float expanded to (value, 0., 0., 1.)
+			8,	// D3DDECLTYPE_FLOAT2    =  1,  // 2D float expanded to (value, value, 0., 1.)
+			12,	// D3DDECLTYPE_FLOAT3    =  2,  // 3D float expanded to (value, value, value, 1.)
+			16,	// D3DDECLTYPE_FLOAT4    =  3,  // 4D float
+			4,	// D3DDECLTYPE_D3DCOLOR  =  4,  // 4D packed unsigned bytes mapped to 0. to 1. range. Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
+			4,	// D3DDECLTYPE_UBYTE4    =  5,  // 4D unsigned byte
+			4,	// D3DDECLTYPE_SHORT2    =  6,  // 2D signed short expanded to (value, value, 0., 1.)
+			8,	// D3DDECLTYPE_SHORT4    =  7,  // 4D signed short
+			4,	// D3DDECLTYPE_UBYTE4N   =  8,  // Each of 4 bytes is normalized by dividing to 255.0
+			4,	// D3DDECLTYPE_SHORT2N   =  9,  // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
+			8,	// D3DDECLTYPE_SHORT4N   = 10,  // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
+			4,	// D3DDECLTYPE_USHORT2N  = 11,  // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
+			8,	// D3DDECLTYPE_USHORT4N  = 12,  // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
+			4,	// D3DDECLTYPE_UDEC3     = 13,  // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
+			4,	// D3DDECLTYPE_DEC3N     = 14,  // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
+			4,	// D3DDECLTYPE_FLOAT16_2 = 15,  // Two 16-bit floating point values, expanded to (value, value, 0, 1)
+			8,	// D3DDECLTYPE_FLOAT16_4 = 16,  // Four 16-bit floating point values
+			0,	// D3DDECLTYPE_UNUSED    = 17,  // When the type field in a decl is unused.
+		};
+
+		return LUT[streamType];
+	}
+
+	bool Direct3DDevice9::instanceData()
+	{
+		ASSERT(vertexDeclaration);
+
+		D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
+		unsigned int numElements;
+		vertexDeclaration->GetDeclaration(vertexElement, &numElements);
+
+		bool instanceData = false;
+
+		for(unsigned int i = 0; i < numElements - 1; i++)
+		{
+			unsigned short stream = vertexElement[i].Stream;
+
+			if(stream != 0)
+			{
+				instanceData = instanceData || (streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA) != 0;
+			}
+		}
+
+		return instanceData;
+	}
+
+	bool Direct3DDevice9::bindResources(Direct3DIndexBuffer9 *indexBuffer)
+	{
+		if(!bindViewport())
+		{
+			return false;   // Zero-area target region
+		}
+
+		bindTextures();
+		bindIndexBuffer(indexBuffer);
+		bindShaderConstants();
+		bindLights();
+
+		return true;
+	}
+
+	void Direct3DDevice9::bindVertexStreams(int base, bool instancing, int instance)
+	{
+		ASSERT(vertexDeclaration);
+
+		renderer->resetInputStreams(vertexDeclaration->isPreTransformed());
+
+		D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
+		unsigned int numElements;
+		vertexDeclaration->GetDeclaration(vertexElement, &numElements);
+
+		// Bind vertex data streams
+		for(unsigned int i = 0; i < numElements - 1; i++)
+		{
+			unsigned short stream = vertexElement[i].Stream;
+			unsigned short offset = vertexElement[i].Offset;
+			unsigned char type = vertexElement[i].Type;
+			unsigned char method = vertexElement[i].Method;
+			unsigned char usage = vertexElement[i].Usage;
+			unsigned char index = vertexElement[i].UsageIndex;
+
+			ASSERT(method == D3DDECLMETHOD_DEFAULT);	// FIXME: Unimplemented
+
+			if(!dataStream[stream])
+			{
+				continue;
+			}
+
+			Direct3DVertexBuffer9 *streamBuffer = dataStream[stream];
+			sw::Resource *resource = streamBuffer->getResource();
+			const void *buffer = ((char*)resource->data() + streamOffset[stream]) + offset;
+
+			int stride = streamStride[stream];
+
+			if(instancing && streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA)
+			{
+				int instanceFrequency = streamSourceFreq[stream] & ~D3DSTREAMSOURCE_INSTANCEDATA;
+				buffer = (char*)buffer + stride * (instance / instanceFrequency);
+
+				stride = 0;
+			}
+			else
+			{
+				buffer = (char*)buffer + stride * base;
+			}
+
+			sw::Stream attribute(resource, buffer, stride);
+
+			switch(type)
+			{
+			case D3DDECLTYPE_FLOAT1:    attribute.define(sw::STREAMTYPE_FLOAT, 1, false);  break;
+			case D3DDECLTYPE_FLOAT2:    attribute.define(sw::STREAMTYPE_FLOAT, 2, false);  break;
+			case D3DDECLTYPE_FLOAT3:    attribute.define(sw::STREAMTYPE_FLOAT, 3, false);  break;
+			case D3DDECLTYPE_FLOAT4:    attribute.define(sw::STREAMTYPE_FLOAT, 4, false);  break;
+			case D3DDECLTYPE_D3DCOLOR:  attribute.define(sw::STREAMTYPE_COLOR, 4, false);  break;
+			case D3DDECLTYPE_UBYTE4:    attribute.define(sw::STREAMTYPE_BYTE, 4, false);   break;
+			case D3DDECLTYPE_SHORT2:    attribute.define(sw::STREAMTYPE_SHORT, 2, false);  break;
+			case D3DDECLTYPE_SHORT4:    attribute.define(sw::STREAMTYPE_SHORT, 4, false);  break;
+			case D3DDECLTYPE_UBYTE4N:   attribute.define(sw::STREAMTYPE_BYTE, 4, true);    break;
+			case D3DDECLTYPE_SHORT2N:   attribute.define(sw::STREAMTYPE_SHORT, 2, true);   break;
+			case D3DDECLTYPE_SHORT4N:   attribute.define(sw::STREAMTYPE_SHORT, 4, true);   break;
+			case D3DDECLTYPE_USHORT2N:  attribute.define(sw::STREAMTYPE_USHORT, 2, true);  break;
+			case D3DDECLTYPE_USHORT4N:  attribute.define(sw::STREAMTYPE_USHORT, 4, true);  break;
+			case D3DDECLTYPE_UDEC3:     attribute.define(sw::STREAMTYPE_UDEC3, 3, false);  break;
+			case D3DDECLTYPE_DEC3N:     attribute.define(sw::STREAMTYPE_DEC3N, 3, true);   break;
+			case D3DDECLTYPE_FLOAT16_2: attribute.define(sw::STREAMTYPE_HALF, 2, false);   break;
+			case D3DDECLTYPE_FLOAT16_4: attribute.define(sw::STREAMTYPE_HALF, 4, false);   break;
+			case D3DDECLTYPE_UNUSED:    attribute.defaults();                              break;
+			default:
+				ASSERT(false);
+			}
+
+			if(vertexShader)
+			{
+				const sw::VertexShader *shader = vertexShader->getVertexShader();
+
+				if(!vertexDeclaration->isPreTransformed())
+				{
+					for(int i = 0; i < 16; i++)
+					{
+						if(usage == shader->input[i].usage &&
+						   index == shader->input[i].index)
+						{
+							renderer->setInputStream(i, attribute);
+
+							break;
+						}
+					}
+				}
+				else   // Bind directly to the output
+				{
+					for(int i = 0; i < 12; i++)
+					{
+						if((usage == shader->output[i][0].usage || (usage == D3DDECLUSAGE_POSITIONT && shader->output[i][0].usage == D3DDECLUSAGE_POSITION)) &&
+						    index == shader->output[i][0].index)
+						{
+							renderer->setInputStream(i, attribute);
+
+							break;
+						}
+					}
+				}
+			}
+			else
+			{
+				switch(usage)
+				{
+				case D3DDECLUSAGE_POSITION:     renderer->setInputStream(sw::Position, attribute);                                       break;
+				case D3DDECLUSAGE_BLENDWEIGHT:  renderer->setInputStream(sw::BlendWeight, attribute);                                    break;
+				case D3DDECLUSAGE_BLENDINDICES: renderer->setInputStream(sw::BlendIndices, attribute.define(sw::STREAMTYPE_INDICES, 1)); break;
+				case D3DDECLUSAGE_NORMAL:       renderer->setInputStream(sw::Normal, attribute.define(sw::STREAMTYPE_FLOAT, 3));         break;
+				case D3DDECLUSAGE_PSIZE:        renderer->setInputStream(sw::PointSize, attribute.define(sw::STREAMTYPE_FLOAT, 1));      break;
+				case D3DDECLUSAGE_TEXCOORD:     renderer->setInputStream(sw::TexCoord0 + index, attribute);                              break;
+				case D3DDECLUSAGE_TANGENT:      /* Ignored */                                                                            break;
+				case D3DDECLUSAGE_BINORMAL:     /* Ignored */                                                                            break;
+				case D3DDECLUSAGE_TESSFACTOR:   UNIMPLEMENTED();                                                                         break;
+				case D3DDECLUSAGE_POSITIONT:    renderer->setInputStream(sw::PositionT, attribute.define(sw::STREAMTYPE_FLOAT, 4));      break;
+				case D3DDECLUSAGE_COLOR:        renderer->setInputStream(sw::Color0 + index, attribute.define(sw::STREAMTYPE_COLOR, 4)); break;
+				case D3DDECLUSAGE_FOG:          /* Ignored */                                                                            break;
+				case D3DDECLUSAGE_DEPTH:        /* Ignored */                                                                            break;
+				case D3DDECLUSAGE_SAMPLE:       UNIMPLEMENTED();                                                                         break;
+				default:
+					ASSERT(false);
+				}
+			}
+		}
+	}
+
+	void Direct3DDevice9::bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer)
+	{
+		sw::Resource *resource = 0;
+
+		if(indexBuffer)
+		{
+			resource = indexBuffer->getResource();
+		}
+
+		renderer->setIndexBuffer(resource);
+	}
+
+	void Direct3DDevice9::bindShaderConstants()
+	{
+		if(pixelShaderDirty)
+		{
+			if(pixelShader)
+			{
+				if(pixelShaderConstantsBDirty)
+				{
+					renderer->setPixelShaderConstantB(0, pixelShaderConstantB, pixelShaderConstantsBDirty);
+				}
+
+				if(pixelShaderConstantsFDirty)
+				{
+					renderer->setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
+				}
+
+				if(pixelShaderConstantsIDirty)
+				{
+					renderer->setPixelShaderConstantI(0, pixelShaderConstantI[0], pixelShaderConstantsIDirty);
+				}
+
+				renderer->setPixelShader(pixelShader->getPixelShader());   // Loads shader constants set with DEF
+				pixelShaderConstantsBDirty = pixelShader->getPixelShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty
+				pixelShaderConstantsFDirty = pixelShader->getPixelShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty
+				pixelShaderConstantsIDirty = pixelShader->getPixelShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty
+			}
+			else
+			{
+				renderer->setPixelShader(0);
+			}
+
+			pixelShaderDirty = false;
+		}
+
+		if(vertexShaderDirty)
+		{
+			if(vertexShader)
+			{
+				if(vertexShaderConstantsBDirty)
+				{
+					renderer->setVertexShaderConstantB(0, vertexShaderConstantB, vertexShaderConstantsBDirty);
+				}
+
+				if(vertexShaderConstantsFDirty)
+				{
+					renderer->setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
+				}
+
+				if(vertexShaderConstantsIDirty)
+				{
+					renderer->setVertexShaderConstantI(0, vertexShaderConstantI[0], vertexShaderConstantsIDirty);
+				}
+
+				renderer->setVertexShader(vertexShader->getVertexShader());   // Loads shader constants set with DEF
+				vertexShaderConstantsBDirty = vertexShader->getVertexShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty
+				vertexShaderConstantsFDirty = vertexShader->getVertexShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty
+				vertexShaderConstantsIDirty = vertexShader->getVertexShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty
+			}
+			else
+			{
+				renderer->setVertexShader(0);
+			}
+
+			vertexShaderDirty = false;
+		}
+	}
+
+	void Direct3DDevice9::bindLights()
+	{
+		if(!lightsDirty) return;
+
+		Lights::iterator i = light.begin();
+		int active = 0;
+
+		// Set and enable renderer lights
+		while(active < 8)
+		{
+			while(i != light.end() && !i->second.enable)
+			{
+				i++;
+			}
+
+			if(i == light.end())
+			{
+				break;
+			}
+
+			const Light &l = i->second;
+
+			sw::Point position(l.Position.x, l.Position.y, l.Position.z);
+			sw::Color<float> diffuse(l.Diffuse.r, l.Diffuse.g, l.Diffuse.b, l.Diffuse.a);
+			sw::Color<float> specular(l.Specular.r, l.Specular.g, l.Specular.b, l.Specular.a);
+			sw::Color<float> ambient(l.Ambient.r, l.Ambient.g, l.Ambient.b, l.Ambient.a);
+			sw::Vector direction(l.Direction.x, l.Direction.y, l.Direction.z);
+
+			renderer->setLightDiffuse(active, diffuse);
+			renderer->setLightSpecular(active, specular);
+			renderer->setLightAmbient(active, ambient);
+
+			if(l.Type == D3DLIGHT_DIRECTIONAL)
+			{
+				// FIXME: Unsupported, make it a positional light far away without falloff
+				renderer->setLightPosition(active, -1e10f * direction);
+				renderer->setLightRange(active, l.Range);
+				renderer->setLightAttenuation(active, 1, 0, 0);
+			}
+			else if(l.Type == D3DLIGHT_SPOT)
+			{
+				// FIXME: Unsupported, make it a positional light
+				renderer->setLightPosition(active, position);
+				renderer->setLightRange(active, l.Range);
+				renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
+			}
+			else
+			{
+				renderer->setLightPosition(active, position);
+				renderer->setLightRange(active, l.Range);
+				renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
+			}
+
+			renderer->setLightEnable(active, true);
+
+			active++;
+			i++;
+		}
+
+		// Remaining lights are disabled
+		while(active < 8)
+		{
+			renderer->setLightEnable(active, false);
+
+			active++;
+		}
+
+		lightsDirty = false;
+	}
+
+	bool Direct3DDevice9::bindViewport()
+	{
+		if(viewport.Width <= 0 || viewport.Height <= 0)
+		{
+			return false;
+		}
+
+		if(scissorEnable)
+		{
+			if(scissorRect.left >= scissorRect.right || scissorRect.top >= scissorRect.bottom)
+			{
+				return false;
+			}
+
+			sw::Rect scissor;
+			scissor.x0 = scissorRect.left;
+			scissor.x1 = scissorRect.right;
+			scissor.y0 = scissorRect.top;
+			scissor.y1 = scissorRect.bottom;
+
+			renderer->setScissor(scissor);
+		}
+		else
+		{
+			sw::Rect scissor;
+			scissor.x0 = viewport.X;
+			scissor.x1 = viewport.X + viewport.Width;
+			scissor.y0 = viewport.Y;
+			scissor.y1 = viewport.Y + viewport.Height;
+
+			renderer->setScissor(scissor);
+		}
+
+		sw::Viewport view;
+		view.x0 = (float)viewport.X;
+		view.y0 = (float)viewport.Y + viewport.Height;
+		view.width = (float)viewport.Width;
+		view.height = -(float)viewport.Height;
+		view.minZ = viewport.MinZ;
+		view.maxZ = viewport.MaxZ;
+
+		renderer->setViewport(view);
+
+		return true;
+	}
+
+	void Direct3DDevice9::bindTextures()
+	{
+		for(int sampler = 0; sampler < 16 + 4; sampler++)
+		{
+			Direct3DBaseTexture9 *baseTexture = texture[sampler];
+
+			sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
+			int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group
+
+			bool textureUsed = false;
+
+			if(type == sw::SAMPLER_PIXEL && pixelShader)
+			{
+				textureUsed = pixelShader->getPixelShader()->usesSampler(index);
+			}
+			else if(type == sw::SAMPLER_VERTEX && vertexShader)
+			{
+				textureUsed = vertexShader->getVertexShader()->usesSampler(index);
+			}
+			else
+			{
+				textureUsed = true;   // FIXME: Check fixed-function use?
+			}
+
+			sw::Resource *resource = 0;
+
+			if(baseTexture && textureUsed)
+			{
+				resource = baseTexture->getResource();
+			}
+
+			renderer->setTextureResource(sampler, resource);
+
+			if(baseTexture && textureUsed)
+			{
+				baseTexture->GenerateMipSubLevels();
+			}
+
+			if(baseTexture && textureUsed)
+			{
+				int levelCount = baseTexture->getInternalLevelCount();
+
+				int textureLOD = baseTexture->GetLOD();
+				int samplerLOD = samplerState[sampler][D3DSAMP_MAXMIPLEVEL];
+				int LOD = textureLOD > samplerLOD ? textureLOD : samplerLOD;
+
+				if(samplerState[sampler][D3DSAMP_MIPFILTER] == D3DTEXF_NONE)
+				{
+					LOD = 0;
+				}
+
+				switch(baseTexture->GetType())
+				{
+				case D3DRTYPE_TEXTURE:
+					{
+						Direct3DTexture9 *texture = dynamic_cast<Direct3DTexture9*>(baseTexture);
+						Direct3DSurface9 *surface;
+
+						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+						{
+							int surfaceLevel = mipmapLevel;
+
+							if(surfaceLevel < LOD)
+							{
+								surfaceLevel = LOD;
+							}
+
+							if(surfaceLevel < 0)
+							{
+								surfaceLevel = 0;
+							}
+							else if(surfaceLevel >= levelCount)
+							{
+								surfaceLevel = levelCount - 1;
+							}
+
+							surface = texture->getInternalSurfaceLevel(surfaceLevel);
+							renderer->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
+						}
+					}
+					break;
+				case D3DRTYPE_CUBETEXTURE:
+					for(int face = 0; face < 6; face++)
+					{
+						Direct3DCubeTexture9 *cubeTexture = dynamic_cast<Direct3DCubeTexture9*>(baseTexture);
+						Direct3DSurface9 *surface;
+
+						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+						{
+							int surfaceLevel = mipmapLevel;
+
+							if(surfaceLevel < LOD)
+							{
+								surfaceLevel = LOD;
+							}
+
+							if(surfaceLevel < 0)
+							{
+								surfaceLevel = 0;
+							}
+							else if(surfaceLevel >= levelCount)
+							{
+								surfaceLevel = levelCount - 1;
+							}
+
+							surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel);
+							renderer->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
+						}
+					}
+					break;
+				case D3DRTYPE_VOLUMETEXTURE:
+					{
+						Direct3DVolumeTexture9 *volumeTexture = dynamic_cast<Direct3DVolumeTexture9*>(baseTexture);
+						Direct3DVolume9 *volume;
+
+						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+						{
+							int surfaceLevel = mipmapLevel;
+
+							if(surfaceLevel < LOD)
+							{
+								surfaceLevel = LOD;
+							}
+
+							if(surfaceLevel < 0)
+							{
+								surfaceLevel = 0;
+							}
+							else if(surfaceLevel >= levelCount)
+							{
+								surfaceLevel = levelCount - 1;
+							}
+
+							volume = volumeTexture->getInternalVolumeLevel(surfaceLevel);
+							renderer->setTextureLevel(sampler, 0, mipmapLevel, volume, sw::TEXTURE_3D);
+						}
+					}
+					break;
+				default:
+					UNIMPLEMENTED();
+				}
+			}
+			else
+			{
+				renderer->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
+			}
+		}
+	}
+
+	bool Direct3DDevice9::isRecording() const
+	{
+		return stateRecorder != 0;
+	}
+
+	void Direct3DDevice9::setOcclusionEnabled(bool enable)
+	{
+		renderer->setOcclusionEnabled(enable);
+	}
+
+	void Direct3DDevice9::removeQuery(sw::Query *query)
+	{
+		renderer->removeQuery(query);
+	}
+
+	void Direct3DDevice9::addQuery(sw::Query *query)
+	{
+		renderer->addQuery(query);
+	}
+
+	void Direct3DDevice9::stretchRect(Direct3DSurface9 *source, const RECT *sourceRect, Direct3DSurface9 *dest, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
+	{
+		D3DSURFACE_DESC sourceDescription;
+		D3DSURFACE_DESC destDescription;
+
+		source->GetDesc(&sourceDescription);
+		dest->GetDesc(&destDescription);
+
+		int sWidth = source->getWidth();
+		int sHeight = source->getHeight();
+		int dWidth = dest->getWidth();
+		int dHeight = dest->getHeight();
+
+		sw::Rect sRect(0, 0, sWidth, sHeight);
+		sw::Rect dRect(0, 0, dWidth, dHeight);
+
+		if(sourceRect)
+		{
+			sRect.x0 = sourceRect->left;
+			sRect.y0 = sourceRect->top;
+			sRect.x1 = sourceRect->right;
+			sRect.y1 = sourceRect->bottom;
+		}
+
+		if(destRect)
+		{
+			dRect.x0 = destRect->left;
+			dRect.y0 = destRect->top;
+			dRect.x1 = destRect->right;
+			dRect.y1 = destRect->bottom;
+		}
+
+		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
+		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
+		bool depthStencil = (sourceDescription.Usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL;
+		bool alpha0xFF = false;
+
+		if((sourceDescription.Format == D3DFMT_A8R8G8B8 && destDescription.Format == D3DFMT_X8R8G8B8) ||
+		   (sourceDescription.Format == D3DFMT_X8R8G8B8 && destDescription.Format == D3DFMT_A8R8G8B8))
+		{
+			equalFormats = true;
+			alpha0xFF = true;
+		}
+
+		if(depthStencil)   // Copy entirely, internally   // FIXME: Check
+		{
+			if(source->hasDepth())
+			{
+				byte *sourceBuffer = (byte*)source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+				byte *destBuffer = (byte*)dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getInternalPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockInternal();
+				dest->unlockInternal();
+			}
+
+			if(source->hasStencil())
+			{
+				byte *sourceBuffer = (byte*)source->lockStencil(0, sw::PUBLIC);
+				byte *destBuffer = (byte*)dest->lockStencil(0, sw::PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getStencilPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockStencil();
+				dest->unlockStencil();
+			}
+		}
+		else if(!scaling && equalFormats)
+		{
+			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, 0, sw::LOCK_READWRITE, sw::PUBLIC);
+			unsigned int sourcePitch = source->getInternalPitchB();
+			unsigned int destPitch = dest->getInternalPitchB();
+
+			unsigned int width = dRect.x1 - dRect.x0;
+			unsigned int height = dRect.y1 - dRect.y0;
+			unsigned int bytes = width * sw::Surface::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
+		{
+			renderer->blit(source, sRect, dest, dRect, filter >= D3DTEXF_LINEAR);
+		}
+	}
+
+	long Direct3DDevice9::updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume)
+	{
+		TRACE("IDirect3DVolume9 *sourceVolume = 0x%0.8p, IDirect3DVolume9 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume);
+
+		if(!sourceVolume || !destinationVolume)
+		{
+			return INVALIDCALL();
+		}
+
+		D3DVOLUME_DESC sourceDescription;
+		D3DVOLUME_DESC destinationDescription;
+
+		sourceVolume->GetDesc(&sourceDescription);
+		destinationVolume->GetDesc(&destinationDescription);
+
+		if(sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||
+		   destinationDescription.Pool != D3DPOOL_DEFAULT ||
+		   sourceDescription.Format != destinationDescription.Format ||
+		   sourceDescription.Width  != destinationDescription.Width ||
+		   sourceDescription.Height != destinationDescription.Height ||
+		   sourceDescription.Depth  != destinationDescription.Depth)
+		{
+			return INVALIDCALL();
+		}
+
+		sw::Surface *source = static_cast<Direct3DVolume9*>(sourceVolume);
+		sw::Surface *dest = static_cast<Direct3DVolume9*>(destinationVolume);
+
+		if(source->getExternalPitchB() != dest->getExternalPitchB() ||
+		   source->getExternalSliceB() != dest->getExternalSliceB())
+		{
+			UNIMPLEMENTED();
+		}
+
+		void *sBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+		void *dBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
+
+		memcpy(dBuffer, sBuffer, source->getExternalSliceB() * sourceDescription.Depth);
+
+		source->unlockExternal();
+		dest->unlockExternal();
+
+		return D3D_OK;
+	}
+
+	bool Direct3DDevice9::validRectangle(const RECT *rect, IDirect3DSurface9 *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;
+		}
+
+		D3DSURFACE_DESC description;
+		surface->GetDesc(&description);
+
+		if(rect->right > (int)description.Width || rect->bottom > (int)description.Height)
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	void Direct3DDevice9::configureFPU()
+	{
+	//	_controlfp(_PC_24, _MCW_PC);     // Single-precision
+		_controlfp(_MCW_EM, _MCW_EM);    // Mask all exceptions
+		_controlfp(_RC_NEAR, _MCW_RC);   // Round to nearest
+	}
+}
diff --git a/src/D3D9/Direct3DDevice9.hpp b/src/D3D9/Direct3DDevice9.hpp
index 06bad2d..cf9c7d6 100644
--- a/src/D3D9/Direct3DDevice9.hpp
+++ b/src/D3D9/Direct3DDevice9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DDevice9_hpp
 #define D3D9_Direct3DDevice9_hpp
diff --git a/src/D3D9/Direct3DDevice9Ex.cpp b/src/D3D9/Direct3DDevice9Ex.cpp
index 9f4b3ba..346c3e3 100644
--- a/src/D3D9/Direct3DDevice9Ex.cpp
+++ b/src/D3D9/Direct3DDevice9Ex.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DDevice9Ex.hpp"
 
@@ -82,7 +85,7 @@
 
 		return Direct3DDevice9::AddRef();
 	}
-	
+
 	unsigned long Direct3DDevice9Ex::Release()
 	{
 		TRACE("void");
@@ -796,7 +799,7 @@
 
 		return Direct3DDevice9::SetStreamSourceFreq(streamNumber, divider);
 	}
-	
+
 	long Direct3DDevice9Ex::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)
 	{
 		TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);
diff --git a/src/D3D9/Direct3DDevice9Ex.hpp b/src/D3D9/Direct3DDevice9Ex.hpp
index e83d432..ce34a95 100644
--- a/src/D3D9/Direct3DDevice9Ex.hpp
+++ b/src/D3D9/Direct3DDevice9Ex.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DDevice9Ex_hpp
 #define D3D9_Direct3DDevice9Ex_hpp
diff --git a/src/D3D9/Direct3DIndexBuffer9.cpp b/src/D3D9/Direct3DIndexBuffer9.cpp
index a1a839e..d48efdf 100644
--- a/src/D3D9/Direct3DIndexBuffer9.cpp
+++ b/src/D3D9/Direct3DIndexBuffer9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DIndexBuffer9.hpp"
 
@@ -213,7 +216,7 @@
 	}
 
 	sw::Resource *Direct3DIndexBuffer9::getResource() const
-	{	
+	{
 		return indexBuffer;
 	}
 
diff --git a/src/D3D9/Direct3DIndexBuffer9.hpp b/src/D3D9/Direct3DIndexBuffer9.hpp
index 39108a3..4f6e100 100644
--- a/src/D3D9/Direct3DIndexBuffer9.hpp
+++ b/src/D3D9/Direct3DIndexBuffer9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DIndexBuffer9_hpp
 #define D3D9_Direct3DIndexBuffer9_hpp
diff --git a/src/D3D9/Direct3DPixelShader9.cpp b/src/D3D9/Direct3DPixelShader9.cpp
index 810c1fb..bb6daa5 100644
--- a/src/D3D9/Direct3DPixelShader9.cpp
+++ b/src/D3D9/Direct3DPixelShader9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DPixelShader9.hpp"
 
@@ -63,7 +66,7 @@
 
 		return Unknown::AddRef();
 	}
-	
+
 	unsigned long Direct3DPixelShader9::Release()
 	{
 		TRACE("");
diff --git a/src/D3D9/Direct3DPixelShader9.hpp b/src/D3D9/Direct3DPixelShader9.hpp
index 312a6b7..03c6cd8 100644
--- a/src/D3D9/Direct3DPixelShader9.hpp
+++ b/src/D3D9/Direct3DPixelShader9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DPixelShader9_hpp
 #define D3D9_Direct3DPixelShader9_hpp
diff --git a/src/D3D9/Direct3DQuery9.cpp b/src/D3D9/Direct3DQuery9.cpp
index 703d9e0..f5d52a5 100644
--- a/src/D3D9/Direct3DQuery9.cpp
+++ b/src/D3D9/Direct3DQuery9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DQuery9.hpp"
 
@@ -68,7 +71,7 @@
 
 		return Unknown::AddRef();
 	}
-	
+
 	unsigned long Direct3DQuery9::Release()
 	{
 		TRACE("");
@@ -193,7 +196,7 @@
 			return INVALIDCALL();
 		}
 
-		bool signaled = !query || query->reference == 0; 
+		bool signaled = !query || query->reference == 0;
 
 		if(size && signaled)
 		{
diff --git a/src/D3D9/Direct3DQuery9.hpp b/src/D3D9/Direct3DQuery9.hpp
index c5f51cf..775e40e 100644
--- a/src/D3D9/Direct3DQuery9.hpp
+++ b/src/D3D9/Direct3DQuery9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DQuery9_hpp
 #define D3D9_Direct3DQuery9_hpp
diff --git a/src/D3D9/Direct3DResource9.cpp b/src/D3D9/Direct3DResource9.cpp
index 94af0fb..f5b2e15 100644
--- a/src/D3D9/Direct3DResource9.cpp
+++ b/src/D3D9/Direct3DResource9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DResource9.hpp"
 
@@ -184,7 +187,7 @@
 		{
 			return D3DERR_NOTFOUND;
 		}
-		
+
 		privateData.erase(guid);
 
 		return D3D_OK;
diff --git a/src/D3D9/Direct3DResource9.hpp b/src/D3D9/Direct3DResource9.hpp
index 46d4c19..525f1a3 100644
--- a/src/D3D9/Direct3DResource9.hpp
+++ b/src/D3D9/Direct3DResource9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DResource9_hpp
 #define D3D9_Direct3DResource9_hpp
diff --git a/src/D3D9/Direct3DStateBlock9.cpp b/src/D3D9/Direct3DStateBlock9.cpp
index 1ad9ffa..3971413 100644
--- a/src/D3D9/Direct3DStateBlock9.cpp
+++ b/src/D3D9/Direct3DStateBlock9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DStateBlock9.hpp"
 
diff --git a/src/D3D9/Direct3DStateBlock9.hpp b/src/D3D9/Direct3DStateBlock9.hpp
index e831a04..31fa6e8 100644
--- a/src/D3D9/Direct3DStateBlock9.hpp
+++ b/src/D3D9/Direct3DStateBlock9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DStateBlock9_hpp
 #define D3D9_Direct3DStateBlock9_hpp
@@ -86,7 +89,7 @@
 		void capturePixelTextureStates();
 		void capturePixelSamplerStates();
 		void capturePixelShaderStates();
-	
+
 		// Vertex states
 		void captureVertexRenderStates();
 		void captureVertexSamplerStates();
@@ -97,7 +100,7 @@
 		void captureStreamSourceFrequencies();
 		void captureVertexDeclaration();
 		void captureFVF();
-	
+
 		// All (remaining) states
 		void captureTextures();
 		void captureTexturePalette();
diff --git a/src/D3D9/Direct3DSurface9.cpp b/src/D3D9/Direct3DSurface9.cpp
index 6a686fb..ef4d717 100644
--- a/src/D3D9/Direct3DSurface9.cpp
+++ b/src/D3D9/Direct3DSurface9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DSurface9.hpp"
 
diff --git a/src/D3D9/Direct3DSurface9.hpp b/src/D3D9/Direct3DSurface9.hpp
index 4b9bf87..f1f40d1 100644
--- a/src/D3D9/Direct3DSurface9.hpp
+++ b/src/D3D9/Direct3DSurface9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DSurface9_hpp
 #define D3D9_Direct3DSurface9_hpp
diff --git a/src/D3D9/Direct3DSwapChain9.cpp b/src/D3D9/Direct3DSwapChain9.cpp
index c8ceaa4..b3d1586 100644
--- a/src/D3D9/Direct3DSwapChain9.cpp
+++ b/src/D3D9/Direct3DSwapChain9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DSwapChain9.hpp"
 
@@ -199,14 +202,14 @@
 		{
 			return INVALIDCALL();
 		}
-		
+
 		sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);
 		void *buffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PRIVATE);
 
 		frameBuffer->screenshot(buffer);
 
 		dest->unlockExternal();
-		
+
 		return D3D_OK;
 	}
 
@@ -390,7 +393,7 @@
 	{
 		return backBuffer[index]->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC);   // FIXME: External
 	}
-	
+
 	void Direct3DSwapChain9::unlockBackBuffer(int index)
 	{
 		backBuffer[index]->unlockInternal();   // FIXME: External
diff --git a/src/D3D9/Direct3DSwapChain9.hpp b/src/D3D9/Direct3DSwapChain9.hpp
index 6927fa5..bdf6407 100644
--- a/src/D3D9/Direct3DSwapChain9.hpp
+++ b/src/D3D9/Direct3DSwapChain9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DSwapChain9_hpp
 #define D3D9_Direct3DSwapChain9_hpp
diff --git a/src/D3D9/Direct3DTexture9.cpp b/src/D3D9/Direct3DTexture9.cpp
index 2d7dcda..1b8a562 100644
--- a/src/D3D9/Direct3DTexture9.cpp
+++ b/src/D3D9/Direct3DTexture9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DTexture9.hpp"
 
@@ -281,7 +284,7 @@
 		*surface = surfaceLevel[level];
 
 		return D3D_OK;
-	}		
+	}
 
 	long Direct3DTexture9::UnlockRect(unsigned int level)
 	{
diff --git a/src/D3D9/Direct3DTexture9.hpp b/src/D3D9/Direct3DTexture9.hpp
index 2c19834..506741e 100644
--- a/src/D3D9/Direct3DTexture9.hpp
+++ b/src/D3D9/Direct3DTexture9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DTexture9_hpp
 #define D3D9_Direct3DTexture9_hpp
diff --git a/src/D3D9/Direct3DVertexBuffer9.cpp b/src/D3D9/Direct3DVertexBuffer9.cpp
index 0de6806..752dfb8 100644
--- a/src/D3D9/Direct3DVertexBuffer9.cpp
+++ b/src/D3D9/Direct3DVertexBuffer9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DVertexBuffer9.hpp"
 
@@ -198,7 +201,7 @@
 		{
 			vertexBuffer->destruct();
 			vertexBuffer = new sw::Resource(length + 192 + 1024);   // NOTE: Applications can 'overshoot' while writing vertices
-			
+
 			buffer = (void*)vertexBuffer->data();
 		}
 		else if(flags & D3DLOCK_NOOVERWRITE/* && usage & D3DUSAGE_DYNAMIC*/)
diff --git a/src/D3D9/Direct3DVertexBuffer9.hpp b/src/D3D9/Direct3DVertexBuffer9.hpp
index 690ee43..d35c31e 100644
--- a/src/D3D9/Direct3DVertexBuffer9.hpp
+++ b/src/D3D9/Direct3DVertexBuffer9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DVertexBuffer9_hpp
 #define D3D9_Direct3DVertexBuffer9_hpp
diff --git a/src/D3D9/Direct3DVertexDeclaration9.cpp b/src/D3D9/Direct3DVertexDeclaration9.cpp
index 79b2f56..1cb5b2b 100644
--- a/src/D3D9/Direct3DVertexDeclaration9.cpp
+++ b/src/D3D9/Direct3DVertexDeclaration9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DVertexDeclaration9.hpp"
 
@@ -215,7 +218,7 @@
 
 		if(FVF & D3DFVF_DIFFUSE)
 		{
-			vertexElement[numElements].Stream = 0;			
+			vertexElement[numElements].Stream = 0;
 			vertexElement[numElements].Offset = offset;
 			vertexElement[numElements].Type = D3DDECLTYPE_D3DCOLOR;
 			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
@@ -239,7 +242,7 @@
 
 		int numTexCoord = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
 		int textureFormats = (FVF >> 16) & 0xFFFF;
-		
+
 		static const int textureSize[4] =
 		{
 			2 * 4,   // D3DFVF_TEXTUREFORMAT2
@@ -247,7 +250,7 @@
 			4 * 4,   // D3DFVF_TEXTUREFORMAT4
 			1 * 4    // D3DFVF_TEXTUREFORMAT1
 		};
-		
+
 		static const D3DDECLTYPE textureType[4] =
 		{
 			D3DDECLTYPE_FLOAT2,   // D3DFVF_TEXTUREFORMAT2
@@ -311,7 +314,7 @@
 
 		return Unknown::AddRef();
 	}
-	
+
 	unsigned long Direct3DVertexDeclaration9::Release()
 	{
 		TRACE("");
@@ -373,7 +376,7 @@
 
 		int textureBits = 0;
 		int numBlendWeights = 0;
-	    
+
 		for(int i = 0; i < numElements - 1; i++)
 		{
 			D3DVERTEXELEMENT9 &element = vertexElement[i];
@@ -460,16 +463,16 @@
 				{
 					return 0;
 				}
-				
+
 				int bit = 1 << element.UsageIndex;
-				
+
 				if(textureBits & bit)
 				{
 					return 0;
 				}
 
 				textureBits |= bit;
-				
+
 				switch(element.Type)
 				{
 				case D3DDECLTYPE_FLOAT1:
@@ -501,14 +504,14 @@
 		{
 			return 0;
 		}
-	        
+
 		int positionMask = isTransformed ? 0x2 : 0x1;
 
 		if(numBlendWeights)
 		{
 			positionMask += numBlendWeights + 1;
 		}
-	        
+
 		int numTexCoord = 0;
 
 		while(textureBits & 1)
diff --git a/src/D3D9/Direct3DVertexDeclaration9.hpp b/src/D3D9/Direct3DVertexDeclaration9.hpp
index 8c40d09..ab0621f 100644
--- a/src/D3D9/Direct3DVertexDeclaration9.hpp
+++ b/src/D3D9/Direct3DVertexDeclaration9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DVertexDeclaration9_hpp
 #define D3D9_Direct3DVertexDeclaration9_hpp
diff --git a/src/D3D9/Direct3DVertexShader9.cpp b/src/D3D9/Direct3DVertexShader9.cpp
index 6a1220b..40e3fc5 100644
--- a/src/D3D9/Direct3DVertexShader9.cpp
+++ b/src/D3D9/Direct3DVertexShader9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DVertexShader9.hpp"
 
@@ -63,7 +66,7 @@
 
 		return Unknown::AddRef();
 	}
-	
+
 	unsigned long Direct3DVertexShader9::Release()
 	{
 		TRACE("");
diff --git a/src/D3D9/Direct3DVertexShader9.hpp b/src/D3D9/Direct3DVertexShader9.hpp
index f582810..fcd8eed 100644
--- a/src/D3D9/Direct3DVertexShader9.hpp
+++ b/src/D3D9/Direct3DVertexShader9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DVertexShader9_hpp
 #define D3D9_Direct3DVertexShader9_hpp
diff --git a/src/D3D9/Direct3DVolume9.cpp b/src/D3D9/Direct3DVolume9.cpp
index e45ff09..fc67ecd 100644
--- a/src/D3D9/Direct3DVolume9.cpp
+++ b/src/D3D9/Direct3DVolume9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DVolume9.hpp"
 
diff --git a/src/D3D9/Direct3DVolume9.hpp b/src/D3D9/Direct3DVolume9.hpp
index 004c3da..eb6e166 100644
--- a/src/D3D9/Direct3DVolume9.hpp
+++ b/src/D3D9/Direct3DVolume9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DVolume9_hpp
 #define D3D9_Direct3DVolume9_hpp
diff --git a/src/D3D9/Direct3DVolumeTexture9.cpp b/src/D3D9/Direct3DVolumeTexture9.cpp
index fff5288..efe3d57 100644
--- a/src/D3D9/Direct3DVolumeTexture9.cpp
+++ b/src/D3D9/Direct3DVolumeTexture9.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Direct3DVolumeTexture9.hpp"
 
diff --git a/src/D3D9/Direct3DVolumeTexture9.hpp b/src/D3D9/Direct3DVolumeTexture9.hpp
index e4dda38..d90b637 100644
--- a/src/D3D9/Direct3DVolumeTexture9.hpp
+++ b/src/D3D9/Direct3DVolumeTexture9.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Direct3DVolumeTexture9_hpp
 #define D3D9_Direct3DVolumeTexture9_hpp
diff --git a/src/D3D9/Unknown.cpp b/src/D3D9/Unknown.cpp
index 191d44d..f6c4ca2 100644
--- a/src/D3D9/Unknown.cpp
+++ b/src/D3D9/Unknown.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Unknown.hpp"
 
@@ -36,7 +39,7 @@
 
 			return S_OK;
 		}
-			
+
 		*object = 0;
 
 		return NOINTERFACE(iid);
@@ -50,7 +53,7 @@
 	unsigned long Unknown::Release()
 	{
 		int current = referenceCount;
-		
+
 		if(referenceCount > 0)
 		{
 			current = InterlockedDecrement(&referenceCount);
diff --git a/src/D3D9/Unknown.hpp b/src/D3D9/Unknown.hpp
index c032cc9..3064999 100644
--- a/src/D3D9/Unknown.hpp
+++ b/src/D3D9/Unknown.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef D3D9_Unknown_hpp
 #define D3D9_Unknown_hpp
diff --git a/src/Main/Config.cpp b/src/Main/Config.cpp
index becea9c..cee01ee 100644
--- a/src/Main/Config.cpp
+++ b/src/Main/Config.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Config.hpp"
 
diff --git a/src/Main/Config.hpp b/src/Main/Config.hpp
index 2ceec37..7150750 100644
--- a/src/Main/Config.hpp
+++ b/src/Main/Config.hpp
@@ -1,98 +1,101 @@
-// 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.

-//

-

-#ifndef sw_Config_hpp

-#define sw_Config_hpp

-

-#include "Common/Types.hpp"

-

-#define PERF_HUD 0       // Display time spent on vertex, setup and pixel processing for each thread

-#define PERF_PROFILE 0   // Profile various pipeline stages and display the timing in SwiftConfig

-

-#if defined(_WIN32)

-#define S3TC_SUPPORT 1

-#else

-#define S3TC_SUPPORT 0

-#endif

-

-// Worker thread count when not set by SwiftConfig

-// 0 = process affinity count (recommended)

-// 1 = rendering on main thread (no worker threads), useful for debugging

-#ifndef DEFAULT_THREAD_COUNT

-#define DEFAULT_THREAD_COUNT 0

-#endif

-

-namespace sw

-{

-	enum

-	{

-		PERF_PIXEL,

-		PERF_PIPE,

-		PERF_INTERP,

-		PERF_SHADER,

-		PERF_TEX,

-		PERF_ROP,

-

-		PERF_TIMERS

-	};

-

-	struct Profiler

-	{

-		Profiler();

-

-		void reset();

-		void nextFrame();

-

-		int framesSec;

-		int framesTotal;

-		double FPS;

-

-		#if PERF_PROFILE

-		double cycles[PERF_TIMERS];

-

-		int64_t ropOperations;

-		int64_t ropOperationsTotal;

-		int64_t ropOperationsFrame;

-

-		int64_t texOperations;

-		int64_t texOperationsTotal;

-		int64_t texOperationsFrame;

-

-		int64_t compressedTex;

-		int64_t compressedTexTotal;

-		int64_t compressedTexFrame;

-		#endif

-	};

-

-	extern Profiler profiler;

-

-	enum

-	{

-		OUTLINE_RESOLUTION = 4096,   // Maximum vertical resolution of the render target

-		MIPMAP_LEVELS = 14,

-		VERTEX_ATTRIBUTES = 16,

-		TEXTURE_IMAGE_UNITS = 16,

-		VERTEX_TEXTURE_IMAGE_UNITS = 16,

-		TOTAL_IMAGE_UNITS = TEXTURE_IMAGE_UNITS + VERTEX_TEXTURE_IMAGE_UNITS,

-		FRAGMENT_UNIFORM_VECTORS = 224,

-		VERTEX_UNIFORM_VECTORS = 256,

-		MAX_FRAGMENT_UNIFORM_BLOCKS = 12,

-		MAX_VERTEX_UNIFORM_BLOCKS = 12,

-		MAX_UNIFORM_BUFFER_BINDINGS = MAX_FRAGMENT_UNIFORM_BLOCKS + MAX_VERTEX_UNIFORM_BLOCKS,   // Limited to 127 by SourceParameter.bufferIndex in Shader.hpp

-		MAX_UNIFORM_BLOCK_SIZE = 16384,

-		MAX_CLIP_PLANES = 6,

-		MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 64,

-		MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 64,

-		RENDERTARGETS = 8,

-	};

-}

-

-#endif   // sw_Config_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Config_hpp
+#define sw_Config_hpp
+
+#include "Common/Types.hpp"
+
+#define PERF_HUD 0       // Display time spent on vertex, setup and pixel processing for each thread
+#define PERF_PROFILE 0   // Profile various pipeline stages and display the timing in SwiftConfig
+
+#if defined(_WIN32)
+#define S3TC_SUPPORT 1
+#else
+#define S3TC_SUPPORT 0
+#endif
+
+// Worker thread count when not set by SwiftConfig
+// 0 = process affinity count (recommended)
+// 1 = rendering on main thread (no worker threads), useful for debugging
+#ifndef DEFAULT_THREAD_COUNT
+#define DEFAULT_THREAD_COUNT 0
+#endif
+
+namespace sw
+{
+	enum
+	{
+		PERF_PIXEL,
+		PERF_PIPE,
+		PERF_INTERP,
+		PERF_SHADER,
+		PERF_TEX,
+		PERF_ROP,
+
+		PERF_TIMERS
+	};
+
+	struct Profiler
+	{
+		Profiler();
+
+		void reset();
+		void nextFrame();
+
+		int framesSec;
+		int framesTotal;
+		double FPS;
+
+		#if PERF_PROFILE
+		double cycles[PERF_TIMERS];
+
+		int64_t ropOperations;
+		int64_t ropOperationsTotal;
+		int64_t ropOperationsFrame;
+
+		int64_t texOperations;
+		int64_t texOperationsTotal;
+		int64_t texOperationsFrame;
+
+		int64_t compressedTex;
+		int64_t compressedTexTotal;
+		int64_t compressedTexFrame;
+		#endif
+	};
+
+	extern Profiler profiler;
+
+	enum
+	{
+		OUTLINE_RESOLUTION = 4096,   // Maximum vertical resolution of the render target
+		MIPMAP_LEVELS = 14,
+		VERTEX_ATTRIBUTES = 16,
+		TEXTURE_IMAGE_UNITS = 16,
+		VERTEX_TEXTURE_IMAGE_UNITS = 16,
+		TOTAL_IMAGE_UNITS = TEXTURE_IMAGE_UNITS + VERTEX_TEXTURE_IMAGE_UNITS,
+		FRAGMENT_UNIFORM_VECTORS = 224,
+		VERTEX_UNIFORM_VECTORS = 256,
+		MAX_FRAGMENT_UNIFORM_BLOCKS = 12,
+		MAX_VERTEX_UNIFORM_BLOCKS = 12,
+		MAX_UNIFORM_BUFFER_BINDINGS = MAX_FRAGMENT_UNIFORM_BLOCKS + MAX_VERTEX_UNIFORM_BLOCKS,   // Limited to 127 by SourceParameter.bufferIndex in Shader.hpp
+		MAX_UNIFORM_BLOCK_SIZE = 16384,
+		MAX_CLIP_PLANES = 6,
+		MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 64,
+		MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 64,
+		RENDERTARGETS = 8,
+	};
+}
+
+#endif   // sw_Config_hpp
diff --git a/src/Main/FrameBuffer.cpp b/src/Main/FrameBuffer.cpp
index 0c30646..2ac2a49 100644
--- a/src/Main/FrameBuffer.cpp
+++ b/src/Main/FrameBuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "FrameBuffer.hpp"
 
diff --git a/src/Main/FrameBuffer.hpp b/src/Main/FrameBuffer.hpp
index a92dadf..f515b4a 100644
--- a/src/Main/FrameBuffer.hpp
+++ b/src/Main/FrameBuffer.hpp
@@ -1,100 +1,103 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef	sw_FrameBuffer_hpp

-#define	sw_FrameBuffer_hpp

-

-#include "Reactor/Nucleus.hpp"

-#include "Renderer/Surface.hpp"

-#include "Common/Thread.hpp"

-

-namespace sw

-{

-	class Surface;

-

-	struct BlitState

-	{

-		int width;

-		int height;

-		Format destFormat;

-		Format sourceFormat;

-		int stride;

-		int cursorWidth;

-		int cursorHeight;

-	};

-

-	class FrameBuffer

-	{

-	public:

-		FrameBuffer(int width, int height, bool fullscreen, bool topLeftOrigin);

-

-		virtual ~FrameBuffer();

-

-		int getWidth() const;

-		int getHeight() const;

-		int getStride() const;

-

-		virtual void flip(void *source, Format sourceFormat, size_t sourceStride) = 0;

-		virtual void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) = 0;

-

-		virtual void *lock() = 0;

-		virtual void unlock() = 0;

-

-		static void setCursorImage(sw::Surface *cursor);

-		static void setCursorOrigin(int x0, int y0);

-		static void setCursorPosition(int x, int y);

-

-		static Routine *copyRoutine(const BlitState &state);

-

-	protected:

-		void copy(void *source, Format format, size_t stride);

-		int width;

-		int height;

-		Format sourceFormat;

-		Format destFormat;

-		int stride;

-		bool windowed;

-

-		void *locked;   // Video memory back buffer

-

-	private:

-		void copyLocked();

-

-		static void threadFunction(void *parameters);

-

-		void *target;   // Render target buffer

-

-		void (*blitFunction)(void *dst, void *src);

-		Routine *blitRoutine;

-		BlitState blitState;

-

-		static void blend(const BlitState &state, const Pointer<Byte> &d, const Pointer<Byte> &s, const Pointer<Byte> &c);

-

-		static void *cursor;

-		static int cursorWidth;

-		static int cursorHeight;

-		static int cursorHotspotX;

-		static int cursorHotspotY;

-		static int cursorPositionX;

-		static int cursorPositionY;

-		static int cursorX;

-		static int cursorY;

-

-		Thread *blitThread;

-		Event syncEvent;

-		Event blitEvent;

-		volatile bool terminate;

-

-		static bool topLeftOrigin;

-	};

-}

-

-#endif	 //	sw_FrameBuffer_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef	sw_FrameBuffer_hpp
+#define	sw_FrameBuffer_hpp
+
+#include "Reactor/Nucleus.hpp"
+#include "Renderer/Surface.hpp"
+#include "Common/Thread.hpp"
+
+namespace sw
+{
+	class Surface;
+
+	struct BlitState
+	{
+		int width;
+		int height;
+		Format destFormat;
+		Format sourceFormat;
+		int stride;
+		int cursorWidth;
+		int cursorHeight;
+	};
+
+	class FrameBuffer
+	{
+	public:
+		FrameBuffer(int width, int height, bool fullscreen, bool topLeftOrigin);
+
+		virtual ~FrameBuffer();
+
+		int getWidth() const;
+		int getHeight() const;
+		int getStride() const;
+
+		virtual void flip(void *source, Format sourceFormat, size_t sourceStride) = 0;
+		virtual void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) = 0;
+
+		virtual void *lock() = 0;
+		virtual void unlock() = 0;
+
+		static void setCursorImage(sw::Surface *cursor);
+		static void setCursorOrigin(int x0, int y0);
+		static void setCursorPosition(int x, int y);
+
+		static Routine *copyRoutine(const BlitState &state);
+
+	protected:
+		void copy(void *source, Format format, size_t stride);
+		int width;
+		int height;
+		Format sourceFormat;
+		Format destFormat;
+		int stride;
+		bool windowed;
+
+		void *locked;   // Video memory back buffer
+
+	private:
+		void copyLocked();
+
+		static void threadFunction(void *parameters);
+
+		void *target;   // Render target buffer
+
+		void (*blitFunction)(void *dst, void *src);
+		Routine *blitRoutine;
+		BlitState blitState;
+
+		static void blend(const BlitState &state, const Pointer<Byte> &d, const Pointer<Byte> &s, const Pointer<Byte> &c);
+
+		static void *cursor;
+		static int cursorWidth;
+		static int cursorHeight;
+		static int cursorHotspotX;
+		static int cursorHotspotY;
+		static int cursorPositionX;
+		static int cursorPositionY;
+		static int cursorX;
+		static int cursorY;
+
+		Thread *blitThread;
+		Event syncEvent;
+		Event blitEvent;
+		volatile bool terminate;
+
+		static bool topLeftOrigin;
+	};
+}
+
+#endif	 //	sw_FrameBuffer_hpp
diff --git a/src/Main/FrameBufferAndroid.cpp b/src/Main/FrameBufferAndroid.cpp
index 9d20ac6..ed50d13 100644
--- a/src/Main/FrameBufferAndroid.cpp
+++ b/src/Main/FrameBufferAndroid.cpp
@@ -31,67 +31,70 @@
 		#endif
 	}
 
-    FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
-			: FrameBuffer(width, height, false, false),
-			  nativeWindow(window), buffer(0), gralloc(0)
-    {
-        hw_module_t const* pModule;
-        hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
-        gralloc = reinterpret_cast<gralloc_module_t const*>(pModule);
+	FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
+		: FrameBuffer(width, height, false, false),
+		  nativeWindow(window), buffer(nullptr), gralloc(nullptr)
+	{
+		hw_module_t const* pModule;
+		hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
+		gralloc = reinterpret_cast<gralloc_module_t const*>(pModule);
 
-        nativeWindow->common.incRef(&nativeWindow->common);
-        native_window_set_usage(nativeWindow, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
-    }
+		nativeWindow->common.incRef(&nativeWindow->common);
+		native_window_set_usage(nativeWindow, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+	}
 
-    FrameBufferAndroid::~FrameBufferAndroid()
-    {
-        if (buffer)
-        {
-            // Probably doesn't have to cancel assuming a success queueing earlier
-            cancelBuffer(nativeWindow, buffer, -1);
-            buffer = 0;
-        }
-        nativeWindow->common.decRef(&nativeWindow->common);
-    }
+	FrameBufferAndroid::~FrameBufferAndroid()
+	{
+		if(buffer)
+		{
+			// Probably doesn't have to cancel assuming a success queueing earlier
+			cancelBuffer(nativeWindow, buffer, -1);
+			buffer = nullptr;
+		}
 
-    void FrameBufferAndroid::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
-    {
-        copy(source, sourceFormat, sourceStride);
-		if (buffer)
+		nativeWindow->common.decRef(&nativeWindow->common);
+	}
+
+	void FrameBufferAndroid::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+	{
+		copy(source, sourceFormat, sourceStride);
+
+		if(buffer)
 		{
 			queueBuffer(nativeWindow, buffer, -1);
-			if (locked)
+
+			if(locked)
 			{
-				locked = 0;
+				locked = nullptr;
 				unlock();
 			}
+
 			buffer->common.decRef(&buffer->common);
 		}
-    }
+	}
 
-    void* FrameBufferAndroid::lock()
-    {
-        if (dequeueBuffer(nativeWindow, &buffer) != 0)
-        {
-            return NULL;
-        }
+	void *FrameBufferAndroid::lock()
+	{
+		if(dequeueBuffer(nativeWindow, &buffer) != 0)
+		{
+			return nullptr;
+		}
 
-        buffer->common.incRef(&buffer->common);
+		buffer->common.incRef(&buffer->common);
 
-        if (gralloc->lock(
-				gralloc, buffer->handle,
-				GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-				0, 0, buffer->width, buffer->height, &locked) != 0)
-        {
-            ALOGE("%s failed to lock buffer %p", __FUNCTION__, buffer);
-            return NULL;
-        }
+		if(gralloc->lock(gralloc, buffer->handle,
+		                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+		                 0, 0, buffer->width, buffer->height, &locked) != 0)
+		{
+			ALOGE("%s failed to lock buffer %p", __FUNCTION__, buffer);
+			return nullptr;
+		}
 
-		if ((buffer->width < width) || (buffer->height < height))
+		if((buffer->width < width) || (buffer->height < height))
 		{
 			ALOGI("lock failed: buffer of %dx%d too small for window of %dx%d",
 				  buffer->width, buffer->height, width, height);
-			return NULL;
+			return nullptr;
 		}
 
 		switch(buffer->format)
@@ -104,26 +107,28 @@
 		case HAL_PIXEL_FORMAT_BGRA_8888: destFormat = FORMAT_A8R8G8B8; break;
 		}
 
-        stride = buffer->stride * Surface::bytes(destFormat);
-        return locked;
-    }
+		stride = buffer->stride * Surface::bytes(destFormat);
+		return locked;
+	}
 
-    void FrameBufferAndroid::unlock()
-    {
-        if (!buffer)
+	void FrameBufferAndroid::unlock()
+	{
+		if(!buffer)
 		{
 			ALOGE("%s: badness unlock with no active buffer", __FUNCTION__);
 			return;
 		}
-		locked = 0;
-        if (gralloc->unlock(gralloc, buffer->handle) != 0)
+
+		locked = nullptr;
+
+		if(gralloc->unlock(gralloc, buffer->handle) != 0)
 		{
 			ALOGE("%s: badness unlock failed", __FUNCTION__);
 		}
-    }
+	}
 }
 
 sw::FrameBuffer *createFrameBuffer(void *display, ANativeWindow* window, int width, int height)
 {
-    return new sw::FrameBufferAndroid(window, width, height);
+	return new sw::FrameBufferAndroid(window, width, height);
 }
diff --git a/src/Main/FrameBufferAndroid.hpp b/src/Main/FrameBufferAndroid.hpp
index 359cea9..2e567d8 100644
--- a/src/Main/FrameBufferAndroid.hpp
+++ b/src/Main/FrameBufferAndroid.hpp
@@ -9,26 +9,26 @@
 
 namespace sw
 {
-    class FrameBufferAndroid : public FrameBuffer
-    {
-    public:
-        FrameBufferAndroid(ANativeWindow* window, int width, int height);
+	class FrameBufferAndroid : public FrameBuffer
+	{
+	public:
+		FrameBufferAndroid(ANativeWindow* window, int width, int height);
 
-        ~FrameBufferAndroid();
+		~FrameBufferAndroid();
 
-        void flip(void *source, Format sourceFormat, size_t sourceStride) override {blit(source, 0, 0, sourceFormat, sourceStride);};
+		void flip(void *source, Format sourceFormat, size_t sourceStride) override {blit(source, 0, 0, sourceFormat, sourceStride);};
 		void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
 
 		void *lock() override;
 		void unlock() override;
 
-        bool setSwapRectangle(int l, int t, int w, int h);
+		bool setSwapRectangle(int l, int t, int w, int h);
 
-    private:
-        ANativeWindow* nativeWindow;
-        ANativeWindowBuffer* buffer;
-        gralloc_module_t const* gralloc;
-    };
+	private:
+		ANativeWindow* nativeWindow;
+		ANativeWindowBuffer* buffer;
+		gralloc_module_t const* gralloc;
+	};
 }
 
 #endif   // sw_FrameBufferAndroid
diff --git a/src/Main/FrameBufferDD.cpp b/src/Main/FrameBufferDD.cpp
index 81b2ef2..5fd8dbb 100644
--- a/src/Main/FrameBufferDD.cpp
+++ b/src/Main/FrameBufferDD.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "FrameBufferDD.hpp"
 
@@ -92,7 +95,7 @@
 		else
 		{
 			IDirectDrawClipper *clipper;
-			
+
 			DDSURFACEDESC ddsd = {0};
 			ddsd.dwSize = sizeof(ddsd);
 			ddsd.dwFlags = DDSD_CAPS;
@@ -100,7 +103,7 @@
 
 			long result = directDraw->CreateSurface(&ddsd, &frontBuffer, 0);
 			directDraw->GetDisplayMode(&ddsd);
-			
+
 			switch(ddsd.ddpfPixelFormat.dwRGBBitCount)
 			{
 			case 32: destFormat = FORMAT_X8R8G8B8; break;
@@ -372,7 +375,7 @@
 
 		if(frontBuffer)
 		{
-			frontBuffer->QueryInterface(IID_IDirectDrawGammaControl, (void**)&gammaControl); 
+			frontBuffer->QueryInterface(IID_IDirectDrawGammaControl, (void**)&gammaControl);
 
 			if(gammaControl)
 			{
@@ -389,7 +392,7 @@
 
 		if(frontBuffer)
 		{
-			frontBuffer->QueryInterface(IID_IDirectDrawGammaControl, (void**)&gammaControl); 
+			frontBuffer->QueryInterface(IID_IDirectDrawGammaControl, (void**)&gammaControl);
 
 			if(gammaControl)
 			{
@@ -406,7 +409,7 @@
 		{
 			return locked;
 		}
-		
+
 		if(!readySurfaces())
 		{
 			return 0;
diff --git a/src/Main/FrameBufferDD.hpp b/src/Main/FrameBufferDD.hpp
index 1f42552..c2d160a 100644
--- a/src/Main/FrameBufferDD.hpp
+++ b/src/Main/FrameBufferDD.hpp
@@ -1,66 +1,69 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef	sw_FrameBufferDD_hpp

-#define	sw_FrameBufferDD_hpp

-

-#include "FrameBufferWin.hpp"

-

-#include <ddraw.h>

-

-namespace sw

-{

-	class FrameBufferDD : public FrameBufferWin

-	{

-	public:

-		FrameBufferDD(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);

-

-		virtual ~FrameBufferDD();

-

-		void flip(void *source, Format sourceFormat, size_t sourceStride) override;

-		void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;

-

-		void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) override;

-		void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;

-

-		void *lock() override;

-		void unlock() override;

-

-		void setGammaRamp(GammaRamp *gammaRamp, bool calibrate) override;

-		void getGammaRamp(GammaRamp *gammaRamp) override;

-

-		void screenshot(void *destBuffer) override;

-		bool getScanline(bool &inVerticalBlank, unsigned int &scanline) override;

-

-		void drawText(int x, int y, const char *string, ...);

-

-	private:

-		void initFullscreen();

-		void initWindowed();

-		void createSurfaces();

-		bool readySurfaces();

-		void updateClipper(HWND windowOverride);

-		void restoreSurfaces();

-		void releaseAll();

-

-		HMODULE ddraw;

-		typedef HRESULT (WINAPI *DIRECTDRAWCREATE)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );

-		HRESULT (WINAPI *DirectDrawCreate)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );

-		typedef HRESULT (WINAPI *DIRECTDRAWENUMERATEEXA)( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);

-		HRESULT (WINAPI *DirectDrawEnumerateExA)( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);

-

-		IDirectDraw *directDraw;

-		IDirectDrawSurface *frontBuffer;

-		IDirectDrawSurface *backBuffer;

-	};

-}

-

-#endif	 //	sw_FrameBufferDD_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef	sw_FrameBufferDD_hpp
+#define	sw_FrameBufferDD_hpp
+
+#include "FrameBufferWin.hpp"
+
+#include <ddraw.h>
+
+namespace sw
+{
+	class FrameBufferDD : public FrameBufferWin
+	{
+	public:
+		FrameBufferDD(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);
+
+		virtual ~FrameBufferDD();
+
+		void flip(void *source, Format sourceFormat, size_t sourceStride) override;
+		void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+
+		void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) override;
+		void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+
+		void *lock() override;
+		void unlock() override;
+
+		void setGammaRamp(GammaRamp *gammaRamp, bool calibrate) override;
+		void getGammaRamp(GammaRamp *gammaRamp) override;
+
+		void screenshot(void *destBuffer) override;
+		bool getScanline(bool &inVerticalBlank, unsigned int &scanline) override;
+
+		void drawText(int x, int y, const char *string, ...);
+
+	private:
+		void initFullscreen();
+		void initWindowed();
+		void createSurfaces();
+		bool readySurfaces();
+		void updateClipper(HWND windowOverride);
+		void restoreSurfaces();
+		void releaseAll();
+
+		HMODULE ddraw;
+		typedef HRESULT (WINAPI *DIRECTDRAWCREATE)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
+		HRESULT (WINAPI *DirectDrawCreate)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
+		typedef HRESULT (WINAPI *DIRECTDRAWENUMERATEEXA)( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
+		HRESULT (WINAPI *DirectDrawEnumerateExA)( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
+
+		IDirectDraw *directDraw;
+		IDirectDrawSurface *frontBuffer;
+		IDirectDrawSurface *backBuffer;
+	};
+}
+
+#endif	 //	sw_FrameBufferDD_hpp
diff --git a/src/Main/FrameBufferGDI.cpp b/src/Main/FrameBufferGDI.cpp
index 9251edb..e528d26 100644
--- a/src/Main/FrameBufferGDI.cpp
+++ b/src/Main/FrameBufferGDI.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "FrameBufferGDI.hpp"
 
@@ -27,7 +30,7 @@
 			deviceMode.dmSize = sizeof(DEVMODE);
 			deviceMode.dmPelsWidth= width;
 			deviceMode.dmPelsHeight = height;
-			deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;	
+			deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
 
 			ChangeDisplaySettings(&deviceMode, CDS_FULLSCREEN);
 		}
@@ -72,7 +75,7 @@
 	{
 		blit(source, 0, 0, sourceFormat, sourceStride);
 	}
-	
+
 	void FrameBufferGDI::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
 	{
 		copy(source, sourceFormat, sourceStride);
@@ -142,7 +145,7 @@
 		bitmapInfo.bmiHeader.biHeight = -height;
 		bitmapInfo.bmiHeader.biWidth = width;
 		bitmapInfo.bmiHeader.biCompression = BI_RGB;
-		
+
 		bitmap = CreateDIBSection(bitmapContext, &bitmapInfo, DIB_RGB_COLORS, &locked, 0, 0);
 		SelectObject(bitmapContext, bitmap);
 
diff --git a/src/Main/FrameBufferGDI.hpp b/src/Main/FrameBufferGDI.hpp
index b4b4976..f81cb8f 100644
--- a/src/Main/FrameBufferGDI.hpp
+++ b/src/Main/FrameBufferGDI.hpp
@@ -1,53 +1,56 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef	sw_FrameBufferGDI_hpp

-#define	sw_FrameBufferGDI_hpp

-

-#include "FrameBufferWin.hpp"

-

-namespace sw

-{

-	class FrameBufferGDI : public FrameBufferWin

-	{

-	public:

-		FrameBufferGDI(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);

-

-		virtual ~FrameBufferGDI();

-		

-		void flip(void *source, Format sourceFormat, size_t sourceStride) override;

-		void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;

-

-		void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) override;

-		void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;

-

-		void *lock() override;

-		void unlock() override;

-

-		void setGammaRamp(GammaRamp *gammaRamp, bool calibrate) override;

-		void getGammaRamp(GammaRamp *gammaRamp) override;

-

-		void screenshot(void *destBuffer) override;

-		bool getScanline(bool &inVerticalBlank, unsigned int &scanline) override;

-

-	private:

-		void init(HWND bitmapWindow);

-		void release();

-

-		HDC windowContext;

-		HDC bitmapContext;

-		HWND bitmapWindow;

-		

-		HBITMAP bitmap;

-	};

-}

-

-#endif	 //	sw_FrameBufferGDI_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef	sw_FrameBufferGDI_hpp
+#define	sw_FrameBufferGDI_hpp
+
+#include "FrameBufferWin.hpp"
+
+namespace sw
+{
+	class FrameBufferGDI : public FrameBufferWin
+	{
+	public:
+		FrameBufferGDI(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);
+
+		virtual ~FrameBufferGDI();
+		
+		void flip(void *source, Format sourceFormat, size_t sourceStride) override;
+		void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+
+		void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) override;
+		void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+
+		void *lock() override;
+		void unlock() override;
+
+		void setGammaRamp(GammaRamp *gammaRamp, bool calibrate) override;
+		void getGammaRamp(GammaRamp *gammaRamp) override;
+
+		void screenshot(void *destBuffer) override;
+		bool getScanline(bool &inVerticalBlank, unsigned int &scanline) override;
+
+	private:
+		void init(HWND bitmapWindow);
+		void release();
+
+		HDC windowContext;
+		HDC bitmapContext;
+		HWND bitmapWindow;
+		
+		HBITMAP bitmap;
+	};
+}
+
+#endif	 //	sw_FrameBufferGDI_hpp
diff --git a/src/Main/FrameBufferOSX.hpp b/src/Main/FrameBufferOSX.hpp
index 41a6348..41f95fe 100644
--- a/src/Main/FrameBufferOSX.hpp
+++ b/src/Main/FrameBufferOSX.hpp
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #ifndef sw_FrameBufferOSX_hpp
 #define sw_FrameBufferOSX_hpp
 
diff --git a/src/Main/FrameBufferOSX.mm b/src/Main/FrameBufferOSX.mm
index 40827cc..3a0cfc7 100644
--- a/src/Main/FrameBufferOSX.mm
+++ b/src/Main/FrameBufferOSX.mm
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #include "FrameBufferOSX.hpp"
 
 #include "Common/Debug.hpp"
@@ -27,7 +41,7 @@
 		CGImageRelease(currentImage);
 		CGColorSpaceRelease(colorspace);
 		CGDataProviderRelease(provider);
-		
+
 		delete[] buffer;
 	}
 
@@ -61,7 +75,7 @@
 		locked = buffer;
 		return locked;
 	};
-	
+
 	void FrameBufferOSX::unlock()
 	{
 		locked = nullptr;
@@ -84,6 +98,6 @@
 		layer = reinterpret_cast<CALayer*>(window);
 	}
 	else ASSERT(0);
-	
+
 	return new sw::FrameBufferOSX(layer, width, height);
 }
diff --git a/src/Main/FrameBufferWin.cpp b/src/Main/FrameBufferWin.cpp
index 860a424..cad8954 100644
--- a/src/Main/FrameBufferWin.cpp
+++ b/src/Main/FrameBufferWin.cpp
@@ -1,75 +1,78 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 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 "FrameBufferWin.hpp"

-

-namespace sw

-{

-	FrameBufferWin::FrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin) : FrameBuffer(width, height, fullscreen, topLeftOrigin), windowHandle(windowHandle)

-	{

-		if(!windowed)

-		{

-			// Force fullscreen window style (no borders)

-			originalWindowStyle = GetWindowLong(windowHandle, GWL_STYLE);

-			SetWindowLong(windowHandle, GWL_STYLE, WS_POPUP);

-		}

-	}

-

-	FrameBufferWin::~FrameBufferWin()

-	{

-		if(!windowed && GetWindowLong(windowHandle, GWL_STYLE) == WS_POPUP)

-		{

-			SetWindowLong(windowHandle, GWL_STYLE, originalWindowStyle);

-		}

-	}

-

-	void FrameBufferWin::updateBounds(HWND windowOverride)

-	{

-		HWND window = windowOverride ? windowOverride : windowHandle;

-

-		if(windowed)

-		{

-			GetClientRect(window, &bounds);

-			ClientToScreen(window, (POINT*)&bounds);

-			ClientToScreen(window, (POINT*)&bounds + 1);

-		}

-		else

-		{

-			SetRect(&bounds, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));

-		}

-	}

-}

-

-#include "FrameBufferDD.hpp"

-#include "FrameBufferGDI.hpp"

-#include "Common/Configurator.hpp"

-

-sw::FrameBufferWin *createFrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin)

-{

-	sw::Configurator ini("SwiftShader.ini");

-	int api = ini.getInteger("Testing", "FrameBufferAPI", 0);

-

-	if(api == 0 && topLeftOrigin)

-	{

-		return new sw::FrameBufferDD(windowHandle, width, height, fullscreen, topLeftOrigin);

-	}

-	else

-	{

-		return new sw::FrameBufferGDI(windowHandle, width, height, fullscreen, topLeftOrigin);

-	}

-

-	return 0;

-}

-

-sw::FrameBuffer *createFrameBuffer(void *display, HWND window, int width, int height)

-{

-	return createFrameBufferWin(window, width, height, false, false);

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "FrameBufferWin.hpp"
+
+namespace sw
+{
+	FrameBufferWin::FrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin) : FrameBuffer(width, height, fullscreen, topLeftOrigin), windowHandle(windowHandle)
+	{
+		if(!windowed)
+		{
+			// Force fullscreen window style (no borders)
+			originalWindowStyle = GetWindowLong(windowHandle, GWL_STYLE);
+			SetWindowLong(windowHandle, GWL_STYLE, WS_POPUP);
+		}
+	}
+
+	FrameBufferWin::~FrameBufferWin()
+	{
+		if(!windowed && GetWindowLong(windowHandle, GWL_STYLE) == WS_POPUP)
+		{
+			SetWindowLong(windowHandle, GWL_STYLE, originalWindowStyle);
+		}
+	}
+
+	void FrameBufferWin::updateBounds(HWND windowOverride)
+	{
+		HWND window = windowOverride ? windowOverride : windowHandle;
+
+		if(windowed)
+		{
+			GetClientRect(window, &bounds);
+			ClientToScreen(window, (POINT*)&bounds);
+			ClientToScreen(window, (POINT*)&bounds + 1);
+		}
+		else
+		{
+			SetRect(&bounds, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
+		}
+	}
+}
+
+#include "FrameBufferDD.hpp"
+#include "FrameBufferGDI.hpp"
+#include "Common/Configurator.hpp"
+
+sw::FrameBufferWin *createFrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin)
+{
+	sw::Configurator ini("SwiftShader.ini");
+	int api = ini.getInteger("Testing", "FrameBufferAPI", 0);
+
+	if(api == 0 && topLeftOrigin)
+	{
+		return new sw::FrameBufferDD(windowHandle, width, height, fullscreen, topLeftOrigin);
+	}
+	else
+	{
+		return new sw::FrameBufferGDI(windowHandle, width, height, fullscreen, topLeftOrigin);
+	}
+
+	return 0;
+}
+
+sw::FrameBuffer *createFrameBuffer(void *display, HWND window, int width, int height)
+{
+	return createFrameBufferWin(window, width, height, false, false);
+}
diff --git a/src/Main/FrameBufferWin.hpp b/src/Main/FrameBufferWin.hpp
index c0d554d..91b194a 100644
--- a/src/Main/FrameBufferWin.hpp
+++ b/src/Main/FrameBufferWin.hpp
@@ -1,53 +1,56 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef	sw_FrameBufferWin_hpp

-#define	sw_FrameBufferWin_hpp

-

-#include "FrameBuffer.hpp"

-

-namespace sw

-{

-	struct GammaRamp

-	{

-		short red[256];

-		short green[256];

-		short blue[256];

-	};

-

-	class FrameBufferWin : public FrameBuffer

-	{

-	public:

-		FrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);

-

-		virtual ~FrameBufferWin();

-

-		virtual void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) = 0;

-		virtual void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) = 0;

-

-		virtual void setGammaRamp(GammaRamp *gammaRamp, bool calibrate) = 0;

-		virtual void getGammaRamp(GammaRamp *gammaRamp) = 0;

-

-		virtual void screenshot(void *destBuffer) = 0;

-		virtual bool getScanline(bool &inVerticalBlank, unsigned int &scanline) = 0;

-

-	protected:

-		void updateBounds(HWND windowOverride);

-

-		HWND windowHandle;

-		DWORD originalWindowStyle;

-		RECT bounds;

-	};

-}

-

-sw::FrameBufferWin *createFrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);

-

-#endif	 //	sw_FrameBufferWin_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef	sw_FrameBufferWin_hpp
+#define	sw_FrameBufferWin_hpp
+
+#include "FrameBuffer.hpp"
+
+namespace sw
+{
+	struct GammaRamp
+	{
+		short red[256];
+		short green[256];
+		short blue[256];
+	};
+
+	class FrameBufferWin : public FrameBuffer
+	{
+	public:
+		FrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);
+
+		virtual ~FrameBufferWin();
+
+		virtual void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) = 0;
+		virtual void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) = 0;
+
+		virtual void setGammaRamp(GammaRamp *gammaRamp, bool calibrate) = 0;
+		virtual void getGammaRamp(GammaRamp *gammaRamp) = 0;
+
+		virtual void screenshot(void *destBuffer) = 0;
+		virtual bool getScanline(bool &inVerticalBlank, unsigned int &scanline) = 0;
+
+	protected:
+		void updateBounds(HWND windowOverride);
+
+		HWND windowHandle;
+		DWORD originalWindowStyle;
+		RECT bounds;
+	};
+}
+
+sw::FrameBufferWin *createFrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);
+
+#endif	 //	sw_FrameBufferWin_hpp
diff --git a/src/Main/FrameBufferX11.cpp b/src/Main/FrameBufferX11.cpp
index e079e8c..60e0e73 100644
--- a/src/Main/FrameBufferX11.cpp
+++ b/src/Main/FrameBufferX11.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Surface.cpp: Implements the egl::Surface class, representing a drawing surface
 // such as the client area of a window, including any back buffers.
diff --git a/src/Main/FrameBufferX11.hpp b/src/Main/FrameBufferX11.hpp
index 0473553..a9c481b 100644
--- a/src/Main/FrameBufferX11.hpp
+++ b/src/Main/FrameBufferX11.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Surface.cpp: Implements the egl::Surface class, representing a drawing surface
 // such as the client area of a window, including any back buffers.
diff --git a/src/Main/SwiftConfig.cpp b/src/Main/SwiftConfig.cpp
index 9dce441..c3eb19c 100644
--- a/src/Main/SwiftConfig.cpp
+++ b/src/Main/SwiftConfig.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "SwiftConfig.hpp"
 
@@ -32,7 +35,7 @@
 		ss << number;
 		return ss.str();
 	}
-	
+
 	std::string ftoa(double number)
 	{
 		std::stringstream ss;
@@ -139,7 +142,7 @@
 						if(bytesReceived > 0)
 						{
 							receiveBuffer[bytesReceived] = 0;
-							
+
 							respond(clientSocket, receiveBuffer);
 						}
 					}
@@ -194,7 +197,7 @@
 					else   // POST data in next packet
 					{
 						int bytesReceived = clientSocket->receive(receiveBuffer, bufferLength);
-						
+
 						if(bytesReceived > 0)
 						{
 							receiveBuffer[bytesReceived] = 0;
@@ -291,7 +294,7 @@
 		html += "<option value='2048'" + (config.textureMemory == 2048 ? selected : empty) + ">2048 MB</option>\n";
 		html += "</select></td></tr>\n";
 		html += "<tr><td>Device identifier:</td><td><select name='identifier' title='The information used by some applications to determine device capabilities.'>\n";
-		html += "<option value='0'" + (config.identifier == 0 ? selected : empty) + ">TransGaming SwiftShader (default)</option>\n";
+		html += "<option value='0'" + (config.identifier == 0 ? selected : empty) + ">Google SwiftShader (default)</option>\n";
 		html += "<option value='1'" + (config.identifier == 1 ? selected : empty) + ">NVIDIA GeForce 7900 GS</option>\n";
 		html += "<option value='2'" + (config.identifier == 2 ? selected : empty) + ">ATI Mobility Radeon X1600</option>\n";
 		html += "<option value='3'" + (config.identifier == 3 ? selected : empty) + ">Intel GMA X3100</option>\n";
@@ -686,7 +689,7 @@
 			{
 				config.forceClearRegisters = true;
 			}
-		#ifndef NDEBUG		
+		#ifndef NDEBUG
 			else if(sscanf(post, "minPrimitives=%d", &integer))
 			{
 				config.minPrimitives = integer;
@@ -770,7 +773,7 @@
 	void SwiftConfig::writeConfiguration()
 	{
 		Configurator ini("SwiftShader.ini");
-		
+
 		ini.addValue("Capabilities", "PixelShaderVersion", itoa(config.pixelShaderVersion));
 		ini.addValue("Capabilities", "VertexShaderVersion", itoa(config.vertexShaderVersion));
 		ini.addValue("Capabilities", "TextureMemory", itoa(config.textureMemory));
diff --git a/src/Main/SwiftConfig.hpp b/src/Main/SwiftConfig.hpp
index 14142ec..f8fd87e 100644
--- a/src/Main/SwiftConfig.hpp
+++ b/src/Main/SwiftConfig.hpp
@@ -1,112 +1,115 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_SwiftConfig_hpp

-#define sw_SwiftConfig_hpp

-

-#include "Reactor/Nucleus.hpp"

-

-#include "Common/Thread.hpp"

-#include "Common/MutexLock.hpp"

-#include "Common/Socket.hpp"

-

-#include <string>

-

-namespace sw

-{

-	class SwiftConfig

-	{

-	public:

-		struct Configuration

-		{

-			int pixelShaderVersion;

-			int vertexShaderVersion;

-			int textureMemory;

-			int identifier;

-			int vertexRoutineCacheSize;

-			int pixelRoutineCacheSize;

-			int setupRoutineCacheSize;

-			int vertexCacheSize;

-			int textureSampleQuality;

-			int mipmapQuality;

-			bool perspectiveCorrection;

-			int transcendentalPrecision;

-			int threadCount;

-			bool enableSSE;

-			bool enableSSE2;

-			bool enableSSE3;

-			bool enableSSSE3;

-			bool enableSSE4_1;

-			Optimization optimization[10];

-			bool disableServer;

-			bool keepSystemCursor;

-			bool forceWindowed;

-			bool complementaryDepthBuffer;

-			bool postBlendSRGB;

-			bool exactColorRounding;

-			bool disableAlphaMode;

-			bool disable10BitMode;

-			int transparencyAntialiasing;

-			int frameBufferAPI;

-			bool precache;

-			int shadowMapping;

-			bool forceClearRegisters;

-		#ifndef NDEBUG

-			unsigned int minPrimitives;

-			unsigned int maxPrimitives;

-		#endif

-		};

-

-		SwiftConfig(bool disableServerOverride);

-

-		~SwiftConfig();

-

-		bool hasNewConfiguration(bool reset = true);

-		void getConfiguration(Configuration &configuration);

-

-	private:

-		enum Status

-		{

-			OK = 200,

-			NotFound = 404

-		};

-

-		void createServer();

-		void destroyServer();

-

-		static void serverRoutine(void *parameters);

-

-		void serverLoop();

-		void respond(Socket *clientSocket, const char *request);

-		std::string page();

-		std::string profile();

-		void send(Socket *clientSocket, Status code, std::string body = "");

-		void parsePost(const char *post);

-

-		void readConfiguration(bool disableServerOverride = false);

-		void writeConfiguration();

-

-		Configuration config;

-

-		Thread *serverThread;

-		volatile bool terminate;

-		BackoffLock criticalSection;   // Protects reading and writing the configuration settings

-

-		bool newConfig;

-

-		Socket *listenSocket;

-

-		int bufferLength;

-		char *receiveBuffer;

-	};

-}

-

-#endif   // sw_SwiftConfig_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_SwiftConfig_hpp
+#define sw_SwiftConfig_hpp
+
+#include "Reactor/Nucleus.hpp"
+
+#include "Common/Thread.hpp"
+#include "Common/MutexLock.hpp"
+#include "Common/Socket.hpp"
+
+#include <string>
+
+namespace sw
+{
+	class SwiftConfig
+	{
+	public:
+		struct Configuration
+		{
+			int pixelShaderVersion;
+			int vertexShaderVersion;
+			int textureMemory;
+			int identifier;
+			int vertexRoutineCacheSize;
+			int pixelRoutineCacheSize;
+			int setupRoutineCacheSize;
+			int vertexCacheSize;
+			int textureSampleQuality;
+			int mipmapQuality;
+			bool perspectiveCorrection;
+			int transcendentalPrecision;
+			int threadCount;
+			bool enableSSE;
+			bool enableSSE2;
+			bool enableSSE3;
+			bool enableSSSE3;
+			bool enableSSE4_1;
+			Optimization optimization[10];
+			bool disableServer;
+			bool keepSystemCursor;
+			bool forceWindowed;
+			bool complementaryDepthBuffer;
+			bool postBlendSRGB;
+			bool exactColorRounding;
+			bool disableAlphaMode;
+			bool disable10BitMode;
+			int transparencyAntialiasing;
+			int frameBufferAPI;
+			bool precache;
+			int shadowMapping;
+			bool forceClearRegisters;
+		#ifndef NDEBUG
+			unsigned int minPrimitives;
+			unsigned int maxPrimitives;
+		#endif
+		};
+
+		SwiftConfig(bool disableServerOverride);
+
+		~SwiftConfig();
+
+		bool hasNewConfiguration(bool reset = true);
+		void getConfiguration(Configuration &configuration);
+
+	private:
+		enum Status
+		{
+			OK = 200,
+			NotFound = 404
+		};
+
+		void createServer();
+		void destroyServer();
+
+		static void serverRoutine(void *parameters);
+
+		void serverLoop();
+		void respond(Socket *clientSocket, const char *request);
+		std::string page();
+		std::string profile();
+		void send(Socket *clientSocket, Status code, std::string body = "");
+		void parsePost(const char *post);
+
+		void readConfiguration(bool disableServerOverride = false);
+		void writeConfiguration();
+
+		Configuration config;
+
+		Thread *serverThread;
+		volatile bool terminate;
+		BackoffLock criticalSection;   // Protects reading and writing the configuration settings
+
+		bool newConfig;
+
+		Socket *listenSocket;
+
+		int bufferLength;
+		char *receiveBuffer;
+	};
+}
+
+#endif   // sw_SwiftConfig_hpp
diff --git a/src/Main/libX11.cpp b/src/Main/libX11.cpp
index 4b72a7c..7739e4a 100644
--- a/src/Main/libX11.cpp
+++ b/src/Main/libX11.cpp
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #include "libX11.hpp"
 
 #include "Common/SharedLibrary.hpp"
@@ -6,27 +20,27 @@
 
 LibX11exports::LibX11exports(void *libX11, void *libXext)
 {
-    XOpenDisplay = (Display *(*)(char*))getProcAddress(libX11, "XOpenDisplay");
-    XGetWindowAttributes = (Status (*)(Display*, Window, XWindowAttributes*))getProcAddress(libX11, "XGetWindowAttributes");
-    XDefaultScreenOfDisplay = (Screen *(*)(Display*))getProcAddress(libX11, "XDefaultScreenOfDisplay");
-    XWidthOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XWidthOfScreen");
-    XHeightOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XHeightOfScreen");
-    XPlanesOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XPlanesOfScreen");
-    XDefaultGC = (GC (*)(Display*, int))getProcAddress(libX11, "XDefaultGC");
-    XDefaultDepth = (int (*)(Display*, int))getProcAddress(libX11, "XDefaultDepth");
-    XMatchVisualInfo = (Status (*)(Display*, int, int, int, XVisualInfo*))getProcAddress(libX11, "XMatchVisualInfo");
-    XDefaultVisual = (Visual *(*)(Display*, int screen_number))getProcAddress(libX11, "XDefaultVisual");
-    XSetErrorHandler = (int (*(*)(int (*)(Display*, XErrorEvent*)))(Display*, XErrorEvent*))getProcAddress(libX11, "XSetErrorHandler");
-    XSync = (int (*)(Display*, Bool))getProcAddress(libX11, "XSync");
-    XCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int))getProcAddress(libX11, "XCreateImage");
-    XCloseDisplay = (int (*)(Display*))getProcAddress(libX11, "XCloseDisplay");
-    XPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int))getProcAddress(libX11, "XPutImage");
+	XOpenDisplay = (Display *(*)(char*))getProcAddress(libX11, "XOpenDisplay");
+	XGetWindowAttributes = (Status (*)(Display*, Window, XWindowAttributes*))getProcAddress(libX11, "XGetWindowAttributes");
+	XDefaultScreenOfDisplay = (Screen *(*)(Display*))getProcAddress(libX11, "XDefaultScreenOfDisplay");
+	XWidthOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XWidthOfScreen");
+	XHeightOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XHeightOfScreen");
+	XPlanesOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XPlanesOfScreen");
+	XDefaultGC = (GC (*)(Display*, int))getProcAddress(libX11, "XDefaultGC");
+	XDefaultDepth = (int (*)(Display*, int))getProcAddress(libX11, "XDefaultDepth");
+	XMatchVisualInfo = (Status (*)(Display*, int, int, int, XVisualInfo*))getProcAddress(libX11, "XMatchVisualInfo");
+	XDefaultVisual = (Visual *(*)(Display*, int screen_number))getProcAddress(libX11, "XDefaultVisual");
+	XSetErrorHandler = (int (*(*)(int (*)(Display*, XErrorEvent*)))(Display*, XErrorEvent*))getProcAddress(libX11, "XSetErrorHandler");
+	XSync = (int (*)(Display*, Bool))getProcAddress(libX11, "XSync");
+	XCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int))getProcAddress(libX11, "XCreateImage");
+	XCloseDisplay = (int (*)(Display*))getProcAddress(libX11, "XCloseDisplay");
+	XPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int))getProcAddress(libX11, "XPutImage");
 
-    XShmQueryExtension = (Bool (*)(Display*))getProcAddress(libXext, "XShmQueryExtension");
-    XShmCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, char*, XShmSegmentInfo*, unsigned int, unsigned int))getProcAddress(libXext, "XShmCreateImage");
-    XShmAttach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmAttach");
-    XShmDetach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmDetach");
-    XShmPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int, bool))getProcAddress(libXext, "XShmPutImage");
+	XShmQueryExtension = (Bool (*)(Display*))getProcAddress(libXext, "XShmQueryExtension");
+	XShmCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, char*, XShmSegmentInfo*, unsigned int, unsigned int))getProcAddress(libXext, "XShmCreateImage");
+	XShmAttach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmAttach");
+	XShmDetach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmDetach");
+	XShmPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int, bool))getProcAddress(libXext, "XShmPutImage");
 }
 
 LibX11exports *LibX11::operator->()
@@ -36,31 +50,31 @@
 
 LibX11exports *LibX11::loadExports()
 {
-    static void *libX11 = nullptr;
-    static void *libXext = nullptr;
-    static LibX11exports *libX11exports = nullptr;
+	static void *libX11 = nullptr;
+	static void *libXext = nullptr;
+	static LibX11exports *libX11exports = nullptr;
 
-    if(!libX11)
-    {
-        libX11 = loadLibrary("libX11.so");
+	if(!libX11)
+	{
+		libX11 = loadLibrary("libX11.so");
 
-        if(libX11)
-        {
-            libXext = loadLibrary("libXext.so");
-            libX11exports = new LibX11exports(libX11, libXext);
-        }
-        else   // Might have failed to load due to sandboxing. Search the global scope for pre-loaded library.
-        {
-            if(getProcAddress(RTLD_DEFAULT, "XOpenDisplay"))
-            {
-                libX11exports = new LibX11exports(RTLD_DEFAULT, RTLD_DEFAULT);
-            }
+		if(libX11)
+		{
+			libXext = loadLibrary("libXext.so");
+			libX11exports = new LibX11exports(libX11, libXext);
+		}
+		else   // Might have failed to load due to sandboxing. Search the global scope for pre-loaded library.
+		{
+			if(getProcAddress(RTLD_DEFAULT, "XOpenDisplay"))
+			{
+				libX11exports = new LibX11exports(RTLD_DEFAULT, RTLD_DEFAULT);
+			}
 
-            libX11 = (void*)-1;   // Don't attempt loading more than once.
-        }
-    }
+			libX11 = (void*)-1;   // Don't attempt loading more than once.
+		}
+	}
 
-    return libX11exports;
+	return libX11exports;
 }
 
 LibX11 libX11;
diff --git a/src/Main/libX11.hpp b/src/Main/libX11.hpp
index 897a662..f9f88be 100644
--- a/src/Main/libX11.hpp
+++ b/src/Main/libX11.hpp
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #ifndef libX11_hpp
 #define libX11_hpp
 
@@ -8,29 +22,29 @@
 
 struct LibX11exports
 {
-    LibX11exports(void *libX11, void *libXext);
+	LibX11exports(void *libX11, void *libXext);
 
-    Display *(*XOpenDisplay)(char *display_name);
-    Status (*XGetWindowAttributes)(Display *display, Window w, XWindowAttributes *window_attributes_return);
-    Screen *(*XDefaultScreenOfDisplay)(Display *display);
-    int (*XWidthOfScreen)(Screen *screen);
-    int (*XHeightOfScreen)(Screen *screen);
-    int (*XPlanesOfScreen)(Screen *screen);
-    GC (*XDefaultGC)(Display *display, int screen_number);
-    int (*XDefaultDepth)(Display *display, int screen_number);
-    Status (*XMatchVisualInfo)(Display *display, int screen, int depth, int screen_class, XVisualInfo *vinfo_return);
-    Visual *(*XDefaultVisual)(Display *display, int screen_number);
-    int (*(*XSetErrorHandler)(int (*handler)(Display*, XErrorEvent*)))(Display*, XErrorEvent*);
-    int (*XSync)(Display *display, Bool discard);
-    XImage *(*XCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line);
-    int (*XCloseDisplay)(Display *display);
-    int (*XPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height);
+	Display *(*XOpenDisplay)(char *display_name);
+	Status (*XGetWindowAttributes)(Display *display, Window w, XWindowAttributes *window_attributes_return);
+	Screen *(*XDefaultScreenOfDisplay)(Display *display);
+	int (*XWidthOfScreen)(Screen *screen);
+	int (*XHeightOfScreen)(Screen *screen);
+	int (*XPlanesOfScreen)(Screen *screen);
+	GC (*XDefaultGC)(Display *display, int screen_number);
+	int (*XDefaultDepth)(Display *display, int screen_number);
+	Status (*XMatchVisualInfo)(Display *display, int screen, int depth, int screen_class, XVisualInfo *vinfo_return);
+	Visual *(*XDefaultVisual)(Display *display, int screen_number);
+	int (*(*XSetErrorHandler)(int (*handler)(Display*, XErrorEvent*)))(Display*, XErrorEvent*);
+	int (*XSync)(Display *display, Bool discard);
+	XImage *(*XCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line);
+	int (*XCloseDisplay)(Display *display);
+	int (*XPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height);
 
-    Bool (*XShmQueryExtension)(Display *display);
-    XImage *(*XShmCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, char *data, XShmSegmentInfo *shminfo, unsigned int width, unsigned int height);
-    Bool (*XShmAttach)(Display *display, XShmSegmentInfo *shminfo);
-    Bool (*XShmDetach)(Display *display, XShmSegmentInfo *shminfo);
-    int (*XShmPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height, bool send_event);
+	Bool (*XShmQueryExtension)(Display *display);
+	XImage *(*XShmCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, char *data, XShmSegmentInfo *shminfo, unsigned int width, unsigned int height);
+	Bool (*XShmAttach)(Display *display, XShmSegmentInfo *shminfo);
+	Bool (*XShmDetach)(Display *display, XShmSegmentInfo *shminfo);
+	int (*XShmPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height, bool send_event);
 };
 
 #undef Bool
@@ -43,7 +57,7 @@
 		return loadExports();
 	}
 
-    LibX11exports *operator->();
+	LibX11exports *operator->();
 
 private:
 	LibX11exports *loadExports();
diff --git a/src/OpenGL/common/Image.cpp b/src/OpenGL/common/Image.cpp
index 6934787..b7362d8 100644
--- a/src/OpenGL/common/Image.cpp
+++ b/src/OpenGL/common/Image.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Image.hpp"
 
@@ -1114,7 +1117,7 @@
 		{
 		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
 		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-        case GL_ETC1_RGB8_OES:
+		case GL_ETC1_RGB8_OES:
 		case GL_COMPRESSED_R11_EAC:
 		case GL_COMPRESSED_SIGNED_R11_EAC:
 		case GL_COMPRESSED_RGB8_ETC2:
diff --git a/src/OpenGL/common/Image.hpp b/src/OpenGL/common/Image.hpp
index 8fa08c1..af5471c 100644
--- a/src/OpenGL/common/Image.hpp
+++ b/src/OpenGL/common/Image.hpp
@@ -1,319 +1,319 @@
-#ifndef egl_Image_hpp

-#define egl_Image_hpp

-

-#include "libEGL/Texture.hpp"

-#include "Renderer/Surface.hpp"

-

-#include <GLES2/gl2.h>

-#include <GLES2/gl2ext.h>

-

-#if defined(__ANDROID__)

-#include <hardware/gralloc.h>

-#include <system/window.h>

-#include "../../Common/GrallocAndroid.hpp"

-#include "../../Common/DebugAndroid.hpp"

-#define LOGLOCK(fmt, ...) // ALOGI(fmt " tid=%d", ##__VA_ARGS__, gettid())

-#else

-#include <assert.h>

-#define LOGLOCK(...)

-#endif

-

-// Implementation-defined formats

-#define SW_YV12_BT601 0x32315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.601 color space, studio swing

-#define SW_YV12_BT709 0x48315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.709 color space, studio swing

-#define SW_YV12_JFIF  0x4A315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.601 color space, full swing

-

-namespace egl

-{

-

-sw::Format ConvertFormatType(GLenum format, GLenum type);

-sw::Format SelectInternalFormat(GLenum format, GLenum type);

-GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);

-GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);

-size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, GLint skipImages, GLint skipRows, GLint skipPixels);

-

-class Image : public sw::Surface, public gl::Object

-{

-public:

-	// 2D texture image

-	Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)

-		: sw::Surface(parentTexture->getResource(), width, height, 1, SelectInternalFormat(format, type), true, true),

-		  width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),

-		  parentTexture(parentTexture)

-	{

-		shared = false;

-		Object::addRef();

-		parentTexture->addRef();

-	}

-

-	// 3D texture image

-	Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)

-		: sw::Surface(parentTexture->getResource(), width, height, depth, SelectInternalFormat(format, type), true, true),

-		  width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(depth),

-		  parentTexture(parentTexture)

-	{

-		shared = false;

-		Object::addRef();

-		parentTexture->addRef();

-	}

-

-	// Native EGL image

-	Image(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)

-		: sw::Surface(nullptr, width, height, 1, SelectInternalFormat(format, type), true, true, pitchP),

-		  width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),

-		  parentTexture(nullptr)

-	{

-		shared = true;

-		Object::addRef();

-	}

-

-	// Render target

-	Image(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)

-		: sw::Surface(nullptr, width, height, multiSampleDepth, internalFormat, lockable, true),

-		  width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(multiSampleDepth),

-		  parentTexture(nullptr)

-	{

-		shared = false;

-		Object::addRef();

-	}

-

-	GLsizei getWidth() const

-	{

-		return width;

-	}

-

-	GLsizei getHeight() const

-	{

-		return height;

-	}

-

-	int getDepth() const

-	{

-		// FIXME: add member if the depth dimension (for 3D textures or 2D testure arrays)

-		// and multi sample depth are ever simultaneously required.

-		return depth;

-	}

-

-	GLenum getFormat() const

-	{

-		return format;

-	}

-

-	GLenum getType() const

-	{

-		return type;

-	}

-

-	sw::Format getInternalFormat() const

-	{

-		return internalFormat;

-	}

-

-	bool isShared() const

-    {

-        return shared;

-    }

-

-    void markShared()

-    {

-        shared = true;

-    }

-

-	virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)

-	{

-		return lockExternal(left, top, 0, lock, sw::PUBLIC);

-	}

-

-	unsigned int getPitch() const

-	{

-		return getExternalPitchB();

-	}

-

-	virtual void unlock()

-	{

-		unlockExternal();

-	}

-

-	struct UnpackInfo

-	{

-		UnpackInfo() : alignment(4), rowLength(0), imageHeight(0), skipPixels(0), skipRows(0), skipImages(0) {}

-

-		GLint alignment;

-		GLint rowLength;

-		GLint imageHeight;

-		GLint skipPixels;

-		GLint skipRows;

-		GLint skipImages;

-	};

-

-	void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input);

-	void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);

-

-	void release() override;

-	void unbind(const Texture *parent);   // Break parent ownership and release

-	bool isChildOf(const Texture *parent) const;

-

-	virtual void destroyShared()   // Release a shared image

-	{

-		assert(shared);

-		shared = false;

-		release();

-	}

-

-protected:

-	const GLsizei width;

-	const GLsizei height;

-	const GLenum format;

-	const GLenum type;

-	const sw::Format internalFormat;

-	const int depth;

-

-	bool shared;   // Used as an EGLImage

-

-	egl::Texture *parentTexture;

-

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

-

-inline GLenum GLPixelFormatFromAndroid(int halFormat)

-{

-	switch(halFormat)

-	{

-	case HAL_PIXEL_FORMAT_RGBA_8888: return GL_RGBA;

-	case HAL_PIXEL_FORMAT_RGBX_8888: return GL_RGB;

-	case HAL_PIXEL_FORMAT_RGB_888:   return GL_NONE;   // Unsupported

-	case HAL_PIXEL_FORMAT_BGRA_8888: return GL_BGRA_EXT;

-	case HAL_PIXEL_FORMAT_RGB_565:   return GL_RGB565;

-	case HAL_PIXEL_FORMAT_YV12:      return SW_YV12_BT601;

-#ifdef GRALLOC_MODULE_API_VERSION_0_2

-	case HAL_PIXEL_FORMAT_YCbCr_420_888: return SW_YV12_BT601;

-#endif

-	default:                         return GL_NONE;

-	}

-}

-

-inline GLenum GLPixelTypeFromAndroid(int halFormat)

-{

-	switch(halFormat)

-	{

-	case HAL_PIXEL_FORMAT_RGBA_8888: return GL_UNSIGNED_BYTE;

-	case HAL_PIXEL_FORMAT_RGBX_8888: return GL_UNSIGNED_BYTE;

-	case HAL_PIXEL_FORMAT_RGB_888:   return GL_NONE;   // Unsupported

-	case HAL_PIXEL_FORMAT_BGRA_8888: return GL_UNSIGNED_BYTE;

-	case HAL_PIXEL_FORMAT_RGB_565:   return GL_UNSIGNED_SHORT_5_6_5;

-	case HAL_PIXEL_FORMAT_YV12:      return GL_UNSIGNED_BYTE;

-#ifdef GRALLOC_MODULE_API_VERSION_0_2

-	case HAL_PIXEL_FORMAT_YCbCr_420_888: return GL_UNSIGNED_BYTE;

-#endif

-	default:                         return GL_NONE;

-	}

-}

-

-class AndroidNativeImage : public egl::Image

-{

-public:

-	explicit AndroidNativeImage(ANativeWindowBuffer *nativeBuffer)

-		: egl::Image(nativeBuffer->width, nativeBuffer->height,

-		             GLPixelFormatFromAndroid(nativeBuffer->format),

-		             GLPixelTypeFromAndroid(nativeBuffer->format),

-		             nativeBuffer->stride),

-		  nativeBuffer(nativeBuffer)

-	{

-		nativeBuffer->common.incRef(&nativeBuffer->common);

-	}

-

-private:

-	ANativeWindowBuffer *nativeBuffer;

-

-	virtual ~AndroidNativeImage()

-	{

-		// Wait for any draw calls that use this image to finish

-		resource->lock(sw::DESTRUCT);

-		resource->unlock();

-

-		nativeBuffer->common.decRef(&nativeBuffer->common);

-	}

-

-	virtual void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)

-	{

-		LOGLOCK("image=%p op=%s.swsurface lock=%d", this, __FUNCTION__, lock);

-

-		// Always do this for reference counting.

-		void *data = sw::Surface::lockInternal(x, y, z, lock, client);

-

-		if(nativeBuffer)

-		{

-			if(x != 0 || y != 0 || z != 0)

-			{

-				ALOGI("badness: %s called with unsupported parms: image=%p x=%d y=%d z=%d", __FUNCTION__, this, x, y, z);

-			}

-

-			LOGLOCK("image=%p op=%s.ani lock=%d", this, __FUNCTION__, lock);

-

-			// Lock the ANativeWindowBuffer and use its address.

-			data = lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);

-

-			if(lock == sw::LOCK_UNLOCKED)

-			{

-				// We're never going to get a corresponding unlock, so unlock

-				// immediately. This keeps the gralloc reference counts sane.

-				unlockNativeBuffer();

-			}

-		}

-

-		return data;

-	}

-

-	virtual void unlockInternal()

-	{

-		if(nativeBuffer)   // Unlock the buffer from ANativeWindowBuffer

-		{

-			LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);

-			unlockNativeBuffer();

-		}

-

-		LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);

-		sw::Surface::unlockInternal();

-	}

-

-	virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)

-	{

-		LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);

-		(void)sw::Surface::lockExternal(left, top, 0, lock, sw::PUBLIC);

-

-		return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);

-	}

-

-	virtual void unlock()

-	{

-		LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);

-		unlockNativeBuffer();

-

-		LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);

-		sw::Surface::unlockExternal();

-	}

-

-	void* lockNativeBuffer(int usage)

-	{

-		void *buffer = nullptr;

-		GrallocModule::getInstance()->lock(nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);

-

-		return buffer;

-	}

-

-	void unlockNativeBuffer()

-	{

-		GrallocModule::getInstance()->unlock(nativeBuffer->handle);

-	}

-};

-

-#endif  // __ANDROID__

-

-}

-

-#endif   // egl_Image_hpp

+#ifndef egl_Image_hpp
+#define egl_Image_hpp
+
+#include "libEGL/Texture.hpp"
+#include "Renderer/Surface.hpp"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#if defined(__ANDROID__)
+#include <hardware/gralloc.h>
+#include <system/window.h>
+#include "../../Common/GrallocAndroid.hpp"
+#include "../../Common/DebugAndroid.hpp"
+#define LOGLOCK(fmt, ...) // ALOGI(fmt " tid=%d", ##__VA_ARGS__, gettid())
+#else
+#include <assert.h>
+#define LOGLOCK(...)
+#endif
+
+// Implementation-defined formats
+#define SW_YV12_BT601 0x32315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.601 color space, studio swing
+#define SW_YV12_BT709 0x48315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.709 color space, studio swing
+#define SW_YV12_JFIF  0x4A315659   // YCrCb 4:2:0 Planar, 16-byte aligned, BT.601 color space, full swing
+
+namespace egl
+{
+
+sw::Format ConvertFormatType(GLenum format, GLenum type);
+sw::Format SelectInternalFormat(GLenum format, GLenum type);
+GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
+GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
+size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, GLint skipImages, GLint skipRows, GLint skipPixels);
+
+class Image : public sw::Surface, public gl::Object
+{
+public:
+	// 2D texture image
+	Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
+		: sw::Surface(parentTexture->getResource(), width, height, 1, SelectInternalFormat(format, type), true, true),
+		  width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
+		  parentTexture(parentTexture)
+	{
+		shared = false;
+		Object::addRef();
+		parentTexture->addRef();
+	}
+
+	// 3D texture image
+	Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
+		: sw::Surface(parentTexture->getResource(), width, height, depth, SelectInternalFormat(format, type), true, true),
+		  width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(depth),
+		  parentTexture(parentTexture)
+	{
+		shared = false;
+		Object::addRef();
+		parentTexture->addRef();
+	}
+
+	// Native EGL image
+	Image(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
+		: sw::Surface(nullptr, width, height, 1, SelectInternalFormat(format, type), true, true, pitchP),
+		  width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
+		  parentTexture(nullptr)
+	{
+		shared = true;
+		Object::addRef();
+	}
+
+	// Render target
+	Image(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
+		: sw::Surface(nullptr, width, height, multiSampleDepth, internalFormat, lockable, true),
+		  width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(multiSampleDepth),
+		  parentTexture(nullptr)
+	{
+		shared = false;
+		Object::addRef();
+	}
+
+	GLsizei getWidth() const
+	{
+		return width;
+	}
+
+	GLsizei getHeight() const
+	{
+		return height;
+	}
+
+	int getDepth() const
+	{
+		// FIXME: add member if the depth dimension (for 3D textures or 2D testure arrays)
+		// and multi sample depth are ever simultaneously required.
+		return depth;
+	}
+
+	GLenum getFormat() const
+	{
+		return format;
+	}
+
+	GLenum getType() const
+	{
+		return type;
+	}
+
+	sw::Format getInternalFormat() const
+	{
+		return internalFormat;
+	}
+
+	bool isShared() const
+	{
+		return shared;
+	}
+
+	void markShared()
+	{
+		shared = true;
+	}
+
+	virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)
+	{
+		return lockExternal(left, top, 0, lock, sw::PUBLIC);
+	}
+
+	unsigned int getPitch() const
+	{
+		return getExternalPitchB();
+	}
+
+	virtual void unlock()
+	{
+		unlockExternal();
+	}
+
+	struct UnpackInfo
+	{
+		UnpackInfo() : alignment(4), rowLength(0), imageHeight(0), skipPixels(0), skipRows(0), skipImages(0) {}
+
+		GLint alignment;
+		GLint rowLength;
+		GLint imageHeight;
+		GLint skipPixels;
+		GLint skipRows;
+		GLint skipImages;
+	};
+
+	void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input);
+	void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+
+	void release() override;
+	void unbind(const Texture *parent);   // Break parent ownership and release
+	bool isChildOf(const Texture *parent) const;
+
+	virtual void destroyShared()   // Release a shared image
+	{
+		assert(shared);
+		shared = false;
+		release();
+	}
+
+protected:
+	const GLsizei width;
+	const GLsizei height;
+	const GLenum format;
+	const GLenum type;
+	const sw::Format internalFormat;
+	const int depth;
+
+	bool shared;   // Used as an EGLImage
+
+	egl::Texture *parentTexture;
+
+	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__
+
+inline GLenum GLPixelFormatFromAndroid(int halFormat)
+{
+	switch(halFormat)
+	{
+	case HAL_PIXEL_FORMAT_RGBA_8888: return GL_RGBA;
+	case HAL_PIXEL_FORMAT_RGBX_8888: return GL_RGB;
+	case HAL_PIXEL_FORMAT_RGB_888:   return GL_NONE;   // Unsupported
+	case HAL_PIXEL_FORMAT_BGRA_8888: return GL_BGRA_EXT;
+	case HAL_PIXEL_FORMAT_RGB_565:   return GL_RGB565;
+	case HAL_PIXEL_FORMAT_YV12:      return SW_YV12_BT601;
+#ifdef GRALLOC_MODULE_API_VERSION_0_2
+	case HAL_PIXEL_FORMAT_YCbCr_420_888: return SW_YV12_BT601;
+#endif
+	default:                         return GL_NONE;
+	}
+}
+
+inline GLenum GLPixelTypeFromAndroid(int halFormat)
+{
+	switch(halFormat)
+	{
+	case HAL_PIXEL_FORMAT_RGBA_8888: return GL_UNSIGNED_BYTE;
+	case HAL_PIXEL_FORMAT_RGBX_8888: return GL_UNSIGNED_BYTE;
+	case HAL_PIXEL_FORMAT_RGB_888:   return GL_NONE;   // Unsupported
+	case HAL_PIXEL_FORMAT_BGRA_8888: return GL_UNSIGNED_BYTE;
+	case HAL_PIXEL_FORMAT_RGB_565:   return GL_UNSIGNED_SHORT_5_6_5;
+	case HAL_PIXEL_FORMAT_YV12:      return GL_UNSIGNED_BYTE;
+#ifdef GRALLOC_MODULE_API_VERSION_0_2
+	case HAL_PIXEL_FORMAT_YCbCr_420_888: return GL_UNSIGNED_BYTE;
+#endif
+	default:                         return GL_NONE;
+	}
+}
+
+class AndroidNativeImage : public egl::Image
+{
+public:
+	explicit AndroidNativeImage(ANativeWindowBuffer *nativeBuffer)
+		: egl::Image(nativeBuffer->width, nativeBuffer->height,
+		             GLPixelFormatFromAndroid(nativeBuffer->format),
+		             GLPixelTypeFromAndroid(nativeBuffer->format),
+		             nativeBuffer->stride),
+		  nativeBuffer(nativeBuffer)
+	{
+		nativeBuffer->common.incRef(&nativeBuffer->common);
+	}
+
+private:
+	ANativeWindowBuffer *nativeBuffer;
+
+	virtual ~AndroidNativeImage()
+	{
+		// Wait for any draw calls that use this image to finish
+		resource->lock(sw::DESTRUCT);
+		resource->unlock();
+
+		nativeBuffer->common.decRef(&nativeBuffer->common);
+	}
+
+	virtual void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
+	{
+		LOGLOCK("image=%p op=%s.swsurface lock=%d", this, __FUNCTION__, lock);
+
+		// Always do this for reference counting.
+		void *data = sw::Surface::lockInternal(x, y, z, lock, client);
+
+		if(nativeBuffer)
+		{
+			if(x != 0 || y != 0 || z != 0)
+			{
+				ALOGI("badness: %s called with unsupported parms: image=%p x=%d y=%d z=%d", __FUNCTION__, this, x, y, z);
+			}
+
+			LOGLOCK("image=%p op=%s.ani lock=%d", this, __FUNCTION__, lock);
+
+			// Lock the ANativeWindowBuffer and use its address.
+			data = lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+
+			if(lock == sw::LOCK_UNLOCKED)
+			{
+				// We're never going to get a corresponding unlock, so unlock
+				// immediately. This keeps the gralloc reference counts sane.
+				unlockNativeBuffer();
+			}
+		}
+
+		return data;
+	}
+
+	virtual void unlockInternal()
+	{
+		if(nativeBuffer)   // Unlock the buffer from ANativeWindowBuffer
+		{
+			LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
+			unlockNativeBuffer();
+		}
+
+		LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
+		sw::Surface::unlockInternal();
+	}
+
+	virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)
+	{
+		LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);
+		(void)sw::Surface::lockExternal(left, top, 0, lock, sw::PUBLIC);
+
+		return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+	}
+
+	virtual void unlock()
+	{
+		LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
+		unlockNativeBuffer();
+
+		LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
+		sw::Surface::unlockExternal();
+	}
+
+	void* lockNativeBuffer(int usage)
+	{
+		void *buffer = nullptr;
+		GrallocModule::getInstance()->lock(nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
+
+		return buffer;
+	}
+
+	void unlockNativeBuffer()
+	{
+		GrallocModule::getInstance()->unlock(nativeBuffer->handle);
+	}
+};
+
+#endif  // __ANDROID__
+
+}
+
+#endif   // egl_Image_hpp
diff --git a/src/OpenGL/common/MatrixStack.cpp b/src/OpenGL/common/MatrixStack.cpp
index 0cfcf74..5a248be 100644
--- a/src/OpenGL/common/MatrixStack.cpp
+++ b/src/OpenGL/common/MatrixStack.cpp
@@ -1,203 +1,203 @@
-#include "MatrixStack.hpp"

-

-#include "Common/Math.hpp"

-

-namespace sw

-{

-	MatrixStack::MatrixStack(int size)

-	{

-		stack = new Matrix[size];

-		stack[0] = 1;

-

-		top = 0;

-		this->size = size;

-	}

-

-	MatrixStack::~MatrixStack()

-	{

-		delete[] stack;

-		stack = 0;

-	}

-

-	void MatrixStack::identity()

-	{

-		stack[top] = 1;

-	}

-

-	void MatrixStack::load(const Matrix &M)

-	{

-		stack[top] = M;

-	}

-

-	void MatrixStack::load(const float *M)

-	{

-		stack[top] = Matrix(M[0], M[4], M[8],  M[12],

-		                    M[1], M[5], M[9],  M[13],

-		                    M[2], M[6], M[10], M[14],

-		                    M[3], M[7], M[11], M[15]);

-	}

-

-	void MatrixStack::load(const double *M)

-	{

-		stack[top] = Matrix((float)M[0], (float)M[4], (float)M[8],  (float)M[12],

-		                    (float)M[1], (float)M[5], (float)M[9],  (float)M[13],

-		                    (float)M[2], (float)M[6], (float)M[10], (float)M[14],

-		                    (float)M[3], (float)M[7], (float)M[11], (float)M[15]);

-	}

-

-	void MatrixStack::translate(float x, float y, float z)

-	{

-		stack[top] *= Matrix::translate(x, y, z);

-	}

-

-	void MatrixStack::translate(double x, double y, double z)

-	{

-		translate((float)x, (float)y, (float)z);

-	}

-

-	void MatrixStack::rotate(float angle, float x, float y, float z)

-	{

-		float n = 1.0f / sqrt(x*x + y*y + z*z);

-

-		x *= n;

-		y *= n;

-		z *= n;

-

-		float theta = angle * 0.0174532925f;   // In radians

-		float c = cos(theta);

-		float _c = 1 - c;

-		float s = sin(theta);

-

-		// Rodrigues' rotation formula

-		sw::Matrix rotate(c+x*x*_c,   x*y*_c-z*s, x*z*_c+y*s,

-		                  x*y*_c+z*s, c+y*y*_c,   y*z*_c-x*s,

-		                  x*z*_c-y*s, y*z*_c+x*s, c+z*z*_c);

-

-		stack[top] *= rotate;

-	}

-

-	void MatrixStack::rotate(double angle, double x, double y, double z)

-	{

-		rotate((float)angle, (float)x, (float)y, (float)z);

-	}

-

-	void MatrixStack::scale(float x, float y, float z)

-	{

-		stack[top] *= Matrix::scale(x, y, z);

-	}

-

-	void MatrixStack::scale(double x, double y, double z)

-	{

-		scale((float)x, (float)y, (float)z);

-	}

-

-	void MatrixStack::multiply(const float *M)

-	{

-		stack[top] *= Matrix(M[0], M[4], M[8],  M[12],

-		                     M[1], M[5], M[9],  M[13],

-		                     M[2], M[6], M[10], M[14],

-		                     M[3], M[7], M[11], M[15]);

-	}

-

-	void MatrixStack::multiply(const double *M)

-	{

-		stack[top] *= Matrix((float)M[0], (float)M[4], (float)M[8],  (float)M[12],

-		                     (float)M[1], (float)M[5], (float)M[9],  (float)M[13],

-		                     (float)M[2], (float)M[6], (float)M[10], (float)M[14],

-		                     (float)M[3], (float)M[7], (float)M[11], (float)M[15]);

-	}

-

-	void MatrixStack::frustum(float left, float right, float bottom, float top, float zNear, float zFar)

-	{

-		float l = (float)left;

-		float r = (float)right;

-		float b = (float)bottom;

-		float t = (float)top;

-		float n = (float)zNear;

-		float f = (float)zFar;

-

-		float A = (r + l) / (r - l);

-		float B = (t + b) / (t - b);

-		float C = -(f + n) / (f - n);

-		float D = -2 * f * n / (f - n);

-

-		Matrix frustum(2 * n / (r - l), 0,               A,  0,

-		               0,               2 * n / (t - b), B,  0,

-	                   0,               0,               C,  D,

-	                   0,               0,               -1, 0);

-

-		stack[this->top] *= frustum;

-	}

-

-	void MatrixStack::ortho(double left, double right, double bottom, double top, double zNear, double zFar)

-	{

-		float l = (float)left;

-		float r = (float)right;

-		float b = (float)bottom;

-		float t = (float)top;

-		float n = (float)zNear;

-		float f = (float)zFar;

-

-		float tx = -(r + l) / (r - l);

-		float ty = -(t + b) / (t - b);

-		float tz = -(f + n) / (f - n);

-

-		Matrix ortho(2 / (r - l), 0,           0,            tx,

-		             0,           2 / (t - b), 0,            ty,

-		             0,           0,           -2 / (f - n), tz,

-		             0,           0,           0,            1);

-

-		stack[this->top] *= ortho;

-	}

-

-	bool MatrixStack::push()

-	{

-		if(top >= size - 1) return false;

-

-		stack[top + 1] = stack[top];

-		top++;

-

-		return true;

-	}

-

-	bool MatrixStack::pop()

-	{

-		if(top <= 0) return false;

-

-		top--;

-

-		return true;

-	}

-

-	const Matrix &MatrixStack::current()

-	{

-		return stack[top];

-	}

-

-	bool MatrixStack::isIdentity() const

-	{

-		const Matrix &m = stack[top];

-

-		if(m.m[0][0] != 1.0f) return false;

-		if(m.m[0][1] != 0.0f) return false;

-		if(m.m[0][2] != 0.0f) return false;

-		if(m.m[0][3] != 0.0f) return false;

-

-		if(m.m[1][0] != 0.0f) return false;

-		if(m.m[1][1] != 1.0f) return false;

-		if(m.m[1][2] != 0.0f) return false;

-		if(m.m[1][3] != 0.0f) return false;

-

-		if(m.m[2][0] != 0.0f) return false;

-		if(m.m[2][1] != 0.0f) return false;

-		if(m.m[2][2] != 1.0f) return false;

-		if(m.m[2][3] != 0.0f) return false;

-

-		if(m.m[3][0] != 0.0f) return false;

-		if(m.m[3][1] != 0.0f) return false;

-		if(m.m[3][2] != 0.0f) return false;

-		if(m.m[3][3] != 1.0f) return false;

-

-		return true;

-	}

-}

+#include "MatrixStack.hpp"
+
+#include "Common/Math.hpp"
+
+namespace sw
+{
+	MatrixStack::MatrixStack(int size)
+	{
+		stack = new Matrix[size];
+		stack[0] = 1;
+
+		top = 0;
+		this->size = size;
+	}
+
+	MatrixStack::~MatrixStack()
+	{
+		delete[] stack;
+		stack = 0;
+	}
+
+	void MatrixStack::identity()
+	{
+		stack[top] = 1;
+	}
+
+	void MatrixStack::load(const Matrix &M)
+	{
+		stack[top] = M;
+	}
+
+	void MatrixStack::load(const float *M)
+	{
+		stack[top] = Matrix(M[0], M[4], M[8],  M[12],
+		                    M[1], M[5], M[9],  M[13],
+		                    M[2], M[6], M[10], M[14],
+		                    M[3], M[7], M[11], M[15]);
+	}
+
+	void MatrixStack::load(const double *M)
+	{
+		stack[top] = Matrix((float)M[0], (float)M[4], (float)M[8],  (float)M[12],
+		                    (float)M[1], (float)M[5], (float)M[9],  (float)M[13],
+		                    (float)M[2], (float)M[6], (float)M[10], (float)M[14],
+		                    (float)M[3], (float)M[7], (float)M[11], (float)M[15]);
+	}
+
+	void MatrixStack::translate(float x, float y, float z)
+	{
+		stack[top] *= Matrix::translate(x, y, z);
+	}
+
+	void MatrixStack::translate(double x, double y, double z)
+	{
+		translate((float)x, (float)y, (float)z);
+	}
+
+	void MatrixStack::rotate(float angle, float x, float y, float z)
+	{
+		float n = 1.0f / sqrt(x*x + y*y + z*z);
+
+		x *= n;
+		y *= n;
+		z *= n;
+
+		float theta = angle * 0.0174532925f;   // In radians
+		float c = cos(theta);
+		float _c = 1 - c;
+		float s = sin(theta);
+
+		// Rodrigues' rotation formula
+		sw::Matrix rotate(c+x*x*_c,   x*y*_c-z*s, x*z*_c+y*s,
+		                  x*y*_c+z*s, c+y*y*_c,   y*z*_c-x*s,
+		                  x*z*_c-y*s, y*z*_c+x*s, c+z*z*_c);
+
+		stack[top] *= rotate;
+	}
+
+	void MatrixStack::rotate(double angle, double x, double y, double z)
+	{
+		rotate((float)angle, (float)x, (float)y, (float)z);
+	}
+
+	void MatrixStack::scale(float x, float y, float z)
+	{
+		stack[top] *= Matrix::scale(x, y, z);
+	}
+
+	void MatrixStack::scale(double x, double y, double z)
+	{
+		scale((float)x, (float)y, (float)z);
+	}
+
+	void MatrixStack::multiply(const float *M)
+	{
+		stack[top] *= Matrix(M[0], M[4], M[8],  M[12],
+		                     M[1], M[5], M[9],  M[13],
+		                     M[2], M[6], M[10], M[14],
+		                     M[3], M[7], M[11], M[15]);
+	}
+
+	void MatrixStack::multiply(const double *M)
+	{
+		stack[top] *= Matrix((float)M[0], (float)M[4], (float)M[8],  (float)M[12],
+		                     (float)M[1], (float)M[5], (float)M[9],  (float)M[13],
+		                     (float)M[2], (float)M[6], (float)M[10], (float)M[14],
+		                     (float)M[3], (float)M[7], (float)M[11], (float)M[15]);
+	}
+
+	void MatrixStack::frustum(float left, float right, float bottom, float top, float zNear, float zFar)
+	{
+		float l = (float)left;
+		float r = (float)right;
+		float b = (float)bottom;
+		float t = (float)top;
+		float n = (float)zNear;
+		float f = (float)zFar;
+
+		float A = (r + l) / (r - l);
+		float B = (t + b) / (t - b);
+		float C = -(f + n) / (f - n);
+		float D = -2 * f * n / (f - n);
+
+		Matrix frustum(2 * n / (r - l), 0,               A,  0,
+		               0,               2 * n / (t - b), B,  0,
+	                   0,               0,               C,  D,
+	                   0,               0,               -1, 0);
+
+		stack[this->top] *= frustum;
+	}
+
+	void MatrixStack::ortho(double left, double right, double bottom, double top, double zNear, double zFar)
+	{
+		float l = (float)left;
+		float r = (float)right;
+		float b = (float)bottom;
+		float t = (float)top;
+		float n = (float)zNear;
+		float f = (float)zFar;
+
+		float tx = -(r + l) / (r - l);
+		float ty = -(t + b) / (t - b);
+		float tz = -(f + n) / (f - n);
+
+		Matrix ortho(2 / (r - l), 0,           0,            tx,
+		             0,           2 / (t - b), 0,            ty,
+		             0,           0,           -2 / (f - n), tz,
+		             0,           0,           0,            1);
+
+		stack[this->top] *= ortho;
+	}
+
+	bool MatrixStack::push()
+	{
+		if(top >= size - 1) return false;
+
+		stack[top + 1] = stack[top];
+		top++;
+
+		return true;
+	}
+
+	bool MatrixStack::pop()
+	{
+		if(top <= 0) return false;
+
+		top--;
+
+		return true;
+	}
+
+	const Matrix &MatrixStack::current()
+	{
+		return stack[top];
+	}
+
+	bool MatrixStack::isIdentity() const
+	{
+		const Matrix &m = stack[top];
+
+		if(m.m[0][0] != 1.0f) return false;
+		if(m.m[0][1] != 0.0f) return false;
+		if(m.m[0][2] != 0.0f) return false;
+		if(m.m[0][3] != 0.0f) return false;
+
+		if(m.m[1][0] != 0.0f) return false;
+		if(m.m[1][1] != 1.0f) return false;
+		if(m.m[1][2] != 0.0f) return false;
+		if(m.m[1][3] != 0.0f) return false;
+
+		if(m.m[2][0] != 0.0f) return false;
+		if(m.m[2][1] != 0.0f) return false;
+		if(m.m[2][2] != 1.0f) return false;
+		if(m.m[2][3] != 0.0f) return false;
+
+		if(m.m[3][0] != 0.0f) return false;
+		if(m.m[3][1] != 0.0f) return false;
+		if(m.m[3][2] != 0.0f) return false;
+		if(m.m[3][3] != 1.0f) return false;
+
+		return true;
+	}
+}
diff --git a/src/OpenGL/common/MatrixStack.hpp b/src/OpenGL/common/MatrixStack.hpp
index eb2c1a1..e489b11 100644
--- a/src/OpenGL/common/MatrixStack.hpp
+++ b/src/OpenGL/common/MatrixStack.hpp
@@ -1,45 +1,45 @@
-#ifndef sw_MatrixStack_hpp

-#define sw_MatrixStack_hpp

-

-#include "Renderer/Matrix.hpp"

-

-namespace sw

-{

-	class MatrixStack

-	{

-	public:

-		MatrixStack(int size = 2);

-

-		~MatrixStack();

-

-		void identity();

-		void load(const Matrix &M);

-		void load(const float *M);

-		void load(const double *M);

-

-		void translate(float x, float y, float z);

-		void translate(double x, double y, double z);

-		void rotate(float angle, float x, float y, float z);

-		void rotate(double angle, double x, double y, double z);

-		void scale(float x, float y, float z);

-		void scale(double x, double y, double z);

-		void multiply(const float *M);

-		void multiply(const double *M);

-

-		void frustum(float left, float right, float bottom, float top, float zNear, float zFar);

-		void ortho(double left, double right, double bottom, double top, double zNear, double zFar);

-

-		bool push();   // False on overflow

-		bool pop();    // False on underflow

-

-		const Matrix &current();

-		bool isIdentity() const;

-

-	private:

-		int top;

-		int size;

-		Matrix *stack;

-	};

-}

-

-#endif   // sw_MatrixStack_hpp

+#ifndef sw_MatrixStack_hpp
+#define sw_MatrixStack_hpp
+
+#include "Renderer/Matrix.hpp"
+
+namespace sw
+{
+	class MatrixStack
+	{
+	public:
+		MatrixStack(int size = 2);
+
+		~MatrixStack();
+
+		void identity();
+		void load(const Matrix &M);
+		void load(const float *M);
+		void load(const double *M);
+
+		void translate(float x, float y, float z);
+		void translate(double x, double y, double z);
+		void rotate(float angle, float x, float y, float z);
+		void rotate(double angle, double x, double y, double z);
+		void scale(float x, float y, float z);
+		void scale(double x, double y, double z);
+		void multiply(const float *M);
+		void multiply(const double *M);
+
+		void frustum(float left, float right, float bottom, float top, float zNear, float zFar);
+		void ortho(double left, double right, double bottom, double top, double zNear, double zFar);
+
+		bool push();   // False on overflow
+		bool pop();    // False on underflow
+
+		const Matrix &current();
+		bool isIdentity() const;
+
+	private:
+		int top;
+		int size;
+		Matrix *stack;
+	};
+}
+
+#endif   // sw_MatrixStack_hpp
diff --git a/src/OpenGL/common/NameSpace.hpp b/src/OpenGL/common/NameSpace.hpp
index 3b5417c..d701219 100644
--- a/src/OpenGL/common/NameSpace.hpp
+++ b/src/OpenGL/common/NameSpace.hpp
@@ -1,120 +1,123 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// NameSpace.h: Defines the NameSpace class, which is used to

-// allocate GL object names.

-

-#ifndef gl_NameSpace_hpp

-#define gl_NameSpace_hpp

-

-#include "Object.hpp"

-#include "debug.h"

-

-#include <map>

-

-namespace gl

-{

-

-template<class ObjectType, GLuint baseName = 1>

-class NameSpace

-{

-public:

-    NameSpace() : freeName(baseName)

-	{

-	}

-

-	~NameSpace()

-	{

-		ASSERT(empty());

-	}

-

-	bool empty()

-	{

-		return map.empty();

-	}

-

-	GLuint firstName()

-	{

-		return map.begin()->first;

-	}

-

-    GLuint allocate(ObjectType *object = nullptr)

-	{

-		GLuint name = freeName;

-

-		while(isReserved(name))

-		{

-			name++;

-		}

-

-		map.insert({name, object});

-		freeName = name + 1;

-

-		return name;

-	}

-

-	bool isReserved(GLuint name) const

-	{

-		return map.find(name) != map.end();

-	}

-

-	void insert(GLuint name, ObjectType *object)

-	{

-		map[name] = object;

-

-		if(name == freeName)

-		{

-			freeName++;

-		}

-	}

-

-    ObjectType *remove(GLuint name)

-	{

-		auto element = map.find(name);

-

-		if(element != map.end())

-		{

-			ObjectType *object = element->second;

-			map.erase(element);

-

-			if(name < freeName)

-			{

-				freeName = name;

-			}

-

-			return object;

-		}

-

-		return nullptr;

-	}

-

-	ObjectType *find(GLuint name) const

-	{

-		auto element = map.find(name);

-

-		if(element == map.end())

-		{

-			return nullptr;

-		}

-

-		return element->second;

-	}

-

-private:

-	typedef std::map<GLuint, ObjectType*> Map;

-	Map map;

-

-	GLuint freeName;   // Lowest known potentially free name

-};

-

-}

-

-#endif   // gl_NameSpace_hpp

+// 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.
+
+// NameSpace.h: Defines the NameSpace class, which is used to
+// allocate GL object names.
+
+#ifndef gl_NameSpace_hpp
+#define gl_NameSpace_hpp
+
+#include "Object.hpp"
+#include "debug.h"
+
+#include <map>
+
+namespace gl
+{
+
+template<class ObjectType, GLuint baseName = 1>
+class NameSpace
+{
+public:
+	NameSpace() : freeName(baseName)
+	{
+	}
+
+	~NameSpace()
+	{
+		ASSERT(empty());
+	}
+
+	bool empty()
+	{
+		return map.empty();
+	}
+
+	GLuint firstName()
+	{
+		return map.begin()->first;
+	}
+
+	GLuint allocate(ObjectType *object = nullptr)
+	{
+		GLuint name = freeName;
+
+		while(isReserved(name))
+		{
+			name++;
+		}
+
+		map.insert({name, object});
+		freeName = name + 1;
+
+		return name;
+	}
+
+	bool isReserved(GLuint name) const
+	{
+		return map.find(name) != map.end();
+	}
+
+	void insert(GLuint name, ObjectType *object)
+	{
+		map[name] = object;
+
+		if(name == freeName)
+		{
+			freeName++;
+		}
+	}
+
+	ObjectType *remove(GLuint name)
+	{
+		auto element = map.find(name);
+
+		if(element != map.end())
+		{
+			ObjectType *object = element->second;
+			map.erase(element);
+
+			if(name < freeName)
+			{
+				freeName = name;
+			}
+
+			return object;
+		}
+
+		return nullptr;
+	}
+
+	ObjectType *find(GLuint name) const
+	{
+		auto element = map.find(name);
+
+		if(element == map.end())
+		{
+			return nullptr;
+		}
+
+		return element->second;
+	}
+
+private:
+	typedef std::map<GLuint, ObjectType*> Map;
+	Map map;
+
+	GLuint freeName;   // Lowest known potentially free name
+};
+
+}
+
+#endif   // gl_NameSpace_hpp
diff --git a/src/OpenGL/common/Object.cpp b/src/OpenGL/common/Object.cpp
index 3808dff..1a4a7c8 100644
--- a/src/OpenGL/common/Object.cpp
+++ b/src/OpenGL/common/Object.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    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.
 
 // Object.cpp: Defines the Object base class that provides
 // lifecycle support for GL objects using the traditional BindObject scheme, but
@@ -34,7 +37,7 @@
 
 Object::~Object()
 {
-    ASSERT(referenceCount == 0);
+	ASSERT(referenceCount == 0);
 
 	#ifndef NDEBUG
 		ASSERT(instances.find(this) != instances.end());   // Check for double deletion
@@ -57,9 +60,9 @@
 
 int Object::dereference()
 {
-    ASSERT(referenceCount > 0);
+	ASSERT(referenceCount > 0);
 
-    if(referenceCount > 0)
+	if(referenceCount > 0)
 	{
 		return sw::atomicDecrement(&referenceCount);
 	}
diff --git a/src/OpenGL/common/Object.hpp b/src/OpenGL/common/Object.hpp
index b54d589..c9584e1 100644
--- a/src/OpenGL/common/Object.hpp
+++ b/src/OpenGL/common/Object.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    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.
 
 // Object.hpp: Defines the Object base class that provides
 // lifecycle support for GL objects using the traditional BindObject scheme, but
@@ -28,9 +31,9 @@
 class Object
 {
 public:
-    Object();
+	Object();
 
-    virtual void addRef();
+	virtual void addRef();
 	virtual void release();
 
 	inline bool hasSingleReference() const
@@ -39,12 +42,12 @@
 	}
 
 protected:
-    virtual ~Object();
+	virtual ~Object();
 
 	int dereference();
 	void destroy();
 
-    volatile int referenceCount;
+	volatile int referenceCount;
 
 #ifndef NDEBUG
 public:
@@ -55,10 +58,10 @@
 class NamedObject : public Object
 {
 public:
-    explicit NamedObject(GLuint name);
-    virtual ~NamedObject();
+	explicit NamedObject(GLuint name);
+	virtual ~NamedObject();
 
-    const GLuint name;
+	const GLuint name;
 };
 
 template<class ObjectType>
@@ -68,16 +71,16 @@
 	BindingPointer() : object(nullptr) { }
 
 	BindingPointer(const BindingPointer<ObjectType> &other) : object(nullptr)
-    {
-        operator=(other.object);
-    }
+	{
+		operator=(other.object);
+	}
 
 	~BindingPointer()
 	{
 		ASSERT(!object);   // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up. Assign null to all binding pointers to make the reference count go to zero.
 	}
 
-    ObjectType *operator=(ObjectType *newObject)
+	ObjectType *operator=(ObjectType *newObject)
 	{
 		if(newObject) newObject->addRef();
 		if(object) object->release();
@@ -92,13 +95,13 @@
 		return operator=(other.object);
 	}
 
-    operator ObjectType*() const { return object; }
-    ObjectType *operator->() const { return object; }
+	operator ObjectType*() const { return object; }
+	ObjectType *operator->() const { return object; }
 	GLuint name() const { return object ? object->name : 0; }
-    bool operator!() const { return !object; }
+	bool operator!() const { return !object; }
 
 private:
-    ObjectType *object;
+	ObjectType *object;
 };
 
 }
diff --git a/src/OpenGL/common/debug.cpp b/src/OpenGL/common/debug.cpp
index 7789f12..a7ced89 100644
--- a/src/OpenGL/common/debug.cpp
+++ b/src/OpenGL/common/debug.cpp
@@ -1,57 +1,60 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// debug.cpp: Debugging utilities.

-

-#include "common/debug.h"

-

-#ifdef  __ANDROID__

-#include <utils/String8.h>

-#include <cutils/log.h>

-#endif

-

-#include <stdio.h>

-#include <stdarg.h>

-

-namespace es

-{

-#ifdef __ANDROID__

-	void output(const char *format, va_list vararg)

-	{

-		ALOGI("%s", android::String8::formatV(format, vararg).string());

-	}

-#else

-	static void output(const char *format, va_list vararg)

-	{

-		if(false)

-		{

-			static FILE* file = nullptr;

-			if(!file)

-			{

-				file = fopen(TRACE_OUTPUT_FILE, "w");

-			}

-

-			if(file)

-			{

-				vfprintf(file, format, vararg);

-			}

-		}

-	}

-#endif

-

-	void trace(const char *format, ...)

-	{

-		va_list vararg;

-		va_start(vararg, format);

-		output(format, vararg);

-		va_end(vararg);

-	}

-}

+// 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.
+
+// debug.cpp: Debugging utilities.
+
+#include "common/debug.h"
+
+#ifdef  __ANDROID__
+#include <utils/String8.h>
+#include <cutils/log.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+namespace es
+{
+#ifdef __ANDROID__
+	void output(const char *format, va_list vararg)
+	{
+		ALOGI("%s", android::String8::formatV(format, vararg).string());
+	}
+#else
+	static void output(const char *format, va_list vararg)
+	{
+		if(false)
+		{
+			static FILE* file = nullptr;
+			if(!file)
+			{
+				file = fopen(TRACE_OUTPUT_FILE, "w");
+			}
+
+			if(file)
+			{
+				vfprintf(file, format, vararg);
+			}
+		}
+	}
+#endif
+
+	void trace(const char *format, ...)
+	{
+		va_list vararg;
+		va_start(vararg, format);
+		output(format, vararg);
+		va_end(vararg);
+	}
+}
diff --git a/src/OpenGL/common/debug.h b/src/OpenGL/common/debug.h
index e6ee160..dc8ea98 100644
--- a/src/OpenGL/common/debug.h
+++ b/src/OpenGL/common/debug.h
@@ -1,93 +1,96 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// debug.h: Debugging utilities.

-

-#ifndef COMMON_DEBUG_H_

-#define COMMON_DEBUG_H_

-

-#ifdef __ANDROID__

-#include "../../Common/DebugAndroid.hpp"

-#else

-#include <stdio.h>

-#include <assert.h>

-

-#if !defined(TRACE_OUTPUT_FILE)

-#define TRACE_OUTPUT_FILE "debug.txt"

-#endif

-

-namespace es

-{

-    // Outputs text to the debugging log

-    void trace(const char *format, ...);

-}

-

-// A macro to output a trace of a function call and its arguments to the debugging log

-#if defined(ANGLE_DISABLE_TRACE)

-#define TRACE(message, ...) (void(0))

-#else

-#define TRACE(message, ...) es::trace("trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)

-#endif

-

-// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.

-#if defined(ANGLE_DISABLE_TRACE)

-#define FIXME(message, ...) (void(0))

-#else

-#define FIXME(message, ...) do {es::trace("fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); assert(false);} while(false)

-#endif

-

-// A macro to output a function call and its arguments to the debugging log, in case of error.

-#if defined(ANGLE_DISABLE_TRACE)

-#define ERR(message, ...) (void(0))

-#else

-#define ERR(message, ...) do {es::trace("err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); assert(false);} while(false)

-#endif

-

-// A macro asserting a condition and outputting failures to the debug log

-#undef ASSERT

-#if !defined(NDEBUG)

-#define ASSERT(expression) do { \

-    if(!(expression)) \

-        ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \

-        assert(expression); \

-    } while(0)

-#else

-#define ASSERT(expression) (void(0))

-#endif

-

-// A macro to indicate unimplemented functionality

-#undef UNIMPLEMENTED

-#if !defined(NDEBUG)

-#define UNIMPLEMENTED() do { \

-    FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \

-    assert(false); \

-    } while(0)

-#else

-    #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)

-#endif

-

-// A macro for code which is not expected to be reached under valid assumptions

-#undef UNREACHABLE

-#if !defined(NDEBUG)

-#define UNREACHABLE(value) do { \

-    ERR("\t! Unreachable case reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value); \

-    assert(false); \

-    } while(0)

-#else

-    #define UNREACHABLE(value) ERR("\t! Unreachable reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value)

-#endif

-

-#endif   // __ANDROID__

-

-// A macro functioning as a compile-time assert to validate constant conditions

-#define META_ASSERT(condition) typedef int COMPILE_TIME_ASSERT_##__LINE__[static_cast<bool>(condition) ? 1 : -1]

-

-#endif   // COMMON_DEBUG_H_

+// 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.
+
+// debug.h: Debugging utilities.
+
+#ifndef COMMON_DEBUG_H_
+#define COMMON_DEBUG_H_
+
+#ifdef __ANDROID__
+#include "../../Common/DebugAndroid.hpp"
+#else
+#include <stdio.h>
+#include <assert.h>
+
+#if !defined(TRACE_OUTPUT_FILE)
+#define TRACE_OUTPUT_FILE "debug.txt"
+#endif
+
+namespace es
+{
+	// Outputs text to the debugging log
+	void trace(const char *format, ...);
+}
+
+// A macro to output a trace of a function call and its arguments to the debugging log
+#if defined(ANGLE_DISABLE_TRACE)
+#define TRACE(message, ...) (void(0))
+#else
+#define TRACE(message, ...) es::trace("trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#endif
+
+// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
+#if defined(ANGLE_DISABLE_TRACE)
+#define FIXME(message, ...) (void(0))
+#else
+#define FIXME(message, ...) do {es::trace("fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); assert(false);} while(false)
+#endif
+
+// A macro to output a function call and its arguments to the debugging log, in case of error.
+#if defined(ANGLE_DISABLE_TRACE)
+#define ERR(message, ...) (void(0))
+#else
+#define ERR(message, ...) do {es::trace("err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); assert(false);} while(false)
+#endif
+
+// A macro asserting a condition and outputting failures to the debug log
+#undef ASSERT
+#if !defined(NDEBUG)
+#define ASSERT(expression) do { \
+	if(!(expression)) \
+		ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
+		assert(expression); \
+	} while(0)
+#else
+#define ASSERT(expression) (void(0))
+#endif
+
+// A macro to indicate unimplemented functionality
+#undef UNIMPLEMENTED
+#if !defined(NDEBUG)
+#define UNIMPLEMENTED() do { \
+	FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
+	assert(false); \
+	} while(0)
+#else
+	#define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)
+#endif
+
+// A macro for code which is not expected to be reached under valid assumptions
+#undef UNREACHABLE
+#if !defined(NDEBUG)
+#define UNREACHABLE(value) do { \
+	ERR("\t! Unreachable case reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value); \
+	assert(false); \
+	} while(0)
+#else
+	#define UNREACHABLE(value) ERR("\t! Unreachable reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value)
+#endif
+
+#endif   // __ANDROID__
+
+// A macro functioning as a compile-time assert to validate constant conditions
+#define META_ASSERT(condition) typedef int COMPILE_TIME_ASSERT_##__LINE__[static_cast<bool>(condition) ? 1 : -1]
+
+#endif   // COMMON_DEBUG_H_
diff --git a/src/OpenGL/compiler/AnalyzeCallDepth.cpp b/src/OpenGL/compiler/AnalyzeCallDepth.cpp
index d4f30fa..60991af 100644
--- a/src/OpenGL/compiler/AnalyzeCallDepth.cpp
+++ b/src/OpenGL/compiler/AnalyzeCallDepth.cpp
@@ -1,196 +1,204 @@
-//

-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "AnalyzeCallDepth.h"

-

-AnalyzeCallDepth::FunctionNode::FunctionNode(TIntermAggregate *node) : node(node)

-{

-	visit = PreVisit;

-	callDepth = 0;

-}

-

-const TString &AnalyzeCallDepth::FunctionNode::getName() const

-{

-	return node->getName();

-}

-

-void AnalyzeCallDepth::FunctionNode::addCallee(AnalyzeCallDepth::FunctionNode *callee)

-{

-    for(size_t i = 0; i < callees.size(); i++)

-	{

-        if(callees[i] == callee)

-		{

-            return;

-		}

-    }

-

-    callees.push_back(callee);

-}

-

-unsigned int AnalyzeCallDepth::FunctionNode::analyzeCallDepth(AnalyzeCallDepth *analyzeCallDepth)

-{

-    ASSERT(visit == PreVisit);

-    ASSERT(analyzeCallDepth);

-

-    callDepth = 0;

-    visit = InVisit;

-

-    for(size_t i = 0; i < callees.size(); i++)

-	{

-		unsigned int calleeDepth = 0;

-        switch(callees[i]->visit)

-		{

-        case InVisit:

-            // Cycle detected (recursion)

-            return UINT_MAX;

-        case PostVisit:

-			calleeDepth = callees[i]->getLastDepth();

-            break;

-        case PreVisit:

-			calleeDepth = callees[i]->analyzeCallDepth(analyzeCallDepth);

-			break;

-        default:

-            UNREACHABLE(callees[i]->visit);

-            break;

-        }

-		if(calleeDepth != UINT_MAX) ++calleeDepth;

-		callDepth = std::max(callDepth, calleeDepth);

-    }

-

-    visit = PostVisit;

-    return callDepth;

-}

-

-unsigned int AnalyzeCallDepth::FunctionNode::getLastDepth() const

-{

-	return callDepth;

-}

-

-void AnalyzeCallDepth::FunctionNode::removeIfUnreachable()

-{

-	if(visit == PreVisit)

-	{

-		node->setOp(EOpPrototype);

-		node->getSequence().resize(1);   // Remove function body

-	}

-}

-

-AnalyzeCallDepth::AnalyzeCallDepth(TIntermNode *root)

-    : TIntermTraverser(true, false, true, false),

-      currentFunction(0)

-{

-	root->traverse(this);

-}

-

-AnalyzeCallDepth::~AnalyzeCallDepth()

-{

-    for(size_t i = 0; i < functions.size(); i++)

-	{

-        delete functions[i];

-	}

-}

-

-bool AnalyzeCallDepth::visitAggregate(Visit visit, TIntermAggregate *node)

-{

-    switch(node->getOp())

-    {

-    case EOpFunction:   // Function definition

-		{

-			if(visit == PreVisit)

-			{

-				currentFunction = findFunctionByName(node->getName());

-

-				if(!currentFunction)

-				{

-					currentFunction = new FunctionNode(node);

-					functions.push_back(currentFunction);

-				}

-			}

-			else if(visit == PostVisit)

-			{

-				currentFunction = 0;

-			}

-		}

-        break;

-    case EOpFunctionCall:

-		{

-			if(!node->isUserDefined())

-			{

-				return true;   // Check the arguments for function calls

-			}

-

-			if(visit == PreVisit)

-			{

-				FunctionNode *function = findFunctionByName(node->getName());

-

-				if(!function)

-				{

-					function = new FunctionNode(node);

-					functions.push_back(function);

-				}

-				

-				if(currentFunction)

-				{

-					currentFunction->addCallee(function);

-				}

-				else

-				{

-					globalFunctionCalls.insert(function);

-				}

-			}

-		}

-        break;

-    default:

-        break;

-    }

-

-    return true;

-}

-

-unsigned int AnalyzeCallDepth::analyzeCallDepth()

-{

-    FunctionNode *main = findFunctionByName("main(");

-    

-	if(!main)

-	{

-		return 0;

-	}

-

-    unsigned int depth = main->analyzeCallDepth(this);

-	if(depth != UINT_MAX) ++depth;

-

-	for(FunctionSet::iterator globalCall = globalFunctionCalls.begin(); globalCall != globalFunctionCalls.end(); globalCall++)

-	{

-		unsigned int globalDepth = (*globalCall)->analyzeCallDepth(this);

-		if(globalDepth != UINT_MAX) ++globalDepth;

-

-		if(globalDepth > depth)

-		{

-			depth = globalDepth;

-		}

-	}

-

-	for(size_t i = 0; i < functions.size(); i++)

-	{

-		functions[i]->removeIfUnreachable();

-    }

-

-    return depth;

-}

-

-AnalyzeCallDepth::FunctionNode *AnalyzeCallDepth::findFunctionByName(const TString &name)

-{

-    for(size_t i = 0; i < functions.size(); i++)

-	{

-        if(functions[i]->getName() == name)

-		{

-            return functions[i];

-		}

-    }

-

-    return 0;

-}

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "AnalyzeCallDepth.h"
+
+AnalyzeCallDepth::FunctionNode::FunctionNode(TIntermAggregate *node) : node(node)
+{
+	visit = PreVisit;
+	callDepth = 0;
+}
+
+const TString &AnalyzeCallDepth::FunctionNode::getName() const
+{
+	return node->getName();
+}
+
+void AnalyzeCallDepth::FunctionNode::addCallee(AnalyzeCallDepth::FunctionNode *callee)
+{
+	for(size_t i = 0; i < callees.size(); i++)
+	{
+		if(callees[i] == callee)
+		{
+			return;
+		}
+	}
+
+	callees.push_back(callee);
+}
+
+unsigned int AnalyzeCallDepth::FunctionNode::analyzeCallDepth(AnalyzeCallDepth *analyzeCallDepth)
+{
+	ASSERT(visit == PreVisit);
+	ASSERT(analyzeCallDepth);
+
+	callDepth = 0;
+	visit = InVisit;
+
+	for(size_t i = 0; i < callees.size(); i++)
+	{
+		unsigned int calleeDepth = 0;
+		switch(callees[i]->visit)
+		{
+		case InVisit:
+			// Cycle detected (recursion)
+			return UINT_MAX;
+		case PostVisit:
+			calleeDepth = callees[i]->getLastDepth();
+			break;
+		case PreVisit:
+			calleeDepth = callees[i]->analyzeCallDepth(analyzeCallDepth);
+			break;
+		default:
+			UNREACHABLE(callees[i]->visit);
+			break;
+		}
+		if(calleeDepth != UINT_MAX) ++calleeDepth;
+		callDepth = std::max(callDepth, calleeDepth);
+	}
+
+	visit = PostVisit;
+	return callDepth;
+}
+
+unsigned int AnalyzeCallDepth::FunctionNode::getLastDepth() const
+{
+	return callDepth;
+}
+
+void AnalyzeCallDepth::FunctionNode::removeIfUnreachable()
+{
+	if(visit == PreVisit)
+	{
+		node->setOp(EOpPrototype);
+		node->getSequence().resize(1);   // Remove function body
+	}
+}
+
+AnalyzeCallDepth::AnalyzeCallDepth(TIntermNode *root)
+	: TIntermTraverser(true, false, true, false),
+	  currentFunction(0)
+{
+	root->traverse(this);
+}
+
+AnalyzeCallDepth::~AnalyzeCallDepth()
+{
+	for(size_t i = 0; i < functions.size(); i++)
+	{
+		delete functions[i];
+	}
+}
+
+bool AnalyzeCallDepth::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+	switch(node->getOp())
+	{
+	case EOpFunction:   // Function definition
+		{
+			if(visit == PreVisit)
+			{
+				currentFunction = findFunctionByName(node->getName());
+
+				if(!currentFunction)
+				{
+					currentFunction = new FunctionNode(node);
+					functions.push_back(currentFunction);
+				}
+			}
+			else if(visit == PostVisit)
+			{
+				currentFunction = 0;
+			}
+		}
+		break;
+	case EOpFunctionCall:
+		{
+			if(!node->isUserDefined())
+			{
+				return true;   // Check the arguments for function calls
+			}
+
+			if(visit == PreVisit)
+			{
+				FunctionNode *function = findFunctionByName(node->getName());
+
+				if(!function)
+				{
+					function = new FunctionNode(node);
+					functions.push_back(function);
+				}
+
+				if(currentFunction)
+				{
+					currentFunction->addCallee(function);
+				}
+				else
+				{
+					globalFunctionCalls.insert(function);
+				}
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+unsigned int AnalyzeCallDepth::analyzeCallDepth()
+{
+	FunctionNode *main = findFunctionByName("main(");
+
+	if(!main)
+	{
+		return 0;
+	}
+
+	unsigned int depth = main->analyzeCallDepth(this);
+	if(depth != UINT_MAX) ++depth;
+
+	for(FunctionSet::iterator globalCall = globalFunctionCalls.begin(); globalCall != globalFunctionCalls.end(); globalCall++)
+	{
+		unsigned int globalDepth = (*globalCall)->analyzeCallDepth(this);
+		if(globalDepth != UINT_MAX) ++globalDepth;
+
+		if(globalDepth > depth)
+		{
+			depth = globalDepth;
+		}
+	}
+
+	for(size_t i = 0; i < functions.size(); i++)
+	{
+		functions[i]->removeIfUnreachable();
+	}
+
+	return depth;
+}
+
+AnalyzeCallDepth::FunctionNode *AnalyzeCallDepth::findFunctionByName(const TString &name)
+{
+	for(size_t i = 0; i < functions.size(); i++)
+	{
+		if(functions[i]->getName() == name)
+		{
+			return functions[i];
+		}
+	}
+
+	return 0;
+}
+
diff --git a/src/OpenGL/compiler/AnalyzeCallDepth.h b/src/OpenGL/compiler/AnalyzeCallDepth.h
index f0621e9..b2ca07a 100644
--- a/src/OpenGL/compiler/AnalyzeCallDepth.h
+++ b/src/OpenGL/compiler/AnalyzeCallDepth.h
@@ -1,55 +1,63 @@
-//

-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_ANALYZE_CALL_DEPTH_H_

-#define COMPILER_ANALYZE_CALL_DEPTH_H_

-

-#include "intermediate.h"

-

-#include <set>

-#include <limits.h>

-

-// Traverses intermediate tree to analyze call depth or detect function recursion

-class AnalyzeCallDepth : public TIntermTraverser

-{

-public:

-    AnalyzeCallDepth(TIntermNode *root);

-    ~AnalyzeCallDepth();

-

-    virtual bool visitAggregate(Visit, TIntermAggregate*);

-

-    unsigned int analyzeCallDepth();

-

-private:

-    class FunctionNode

-	{

-    public:

-        FunctionNode(TIntermAggregate *node);

-

-        const TString &getName() const;

-        void addCallee(FunctionNode *callee);

-		unsigned int analyzeCallDepth(AnalyzeCallDepth *analyzeCallDepth);

-		unsigned int getLastDepth() const;

-

-		void removeIfUnreachable();

-

-    private:

-        TIntermAggregate *const node;

-        TVector<FunctionNode*> callees;

-

-        Visit visit;

-		unsigned int callDepth;

-    };

-

-    FunctionNode *findFunctionByName(const TString &name);

-	

-    std::vector<FunctionNode*> functions;

-	typedef std::set<FunctionNode*> FunctionSet;

-	FunctionSet globalFunctionCalls;

-    FunctionNode *currentFunction;

-};

-

-#endif  // COMPILER_ANALYZE_CALL_DEPTH_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_ANALYZE_CALL_DEPTH_H_
+#define COMPILER_ANALYZE_CALL_DEPTH_H_
+
+#include "intermediate.h"
+
+#include <set>
+#include <limits.h>
+
+// Traverses intermediate tree to analyze call depth or detect function recursion
+class AnalyzeCallDepth : public TIntermTraverser
+{
+public:
+	AnalyzeCallDepth(TIntermNode *root);
+	~AnalyzeCallDepth();
+
+	virtual bool visitAggregate(Visit, TIntermAggregate*);
+
+	unsigned int analyzeCallDepth();
+
+private:
+	class FunctionNode
+	{
+	public:
+		FunctionNode(TIntermAggregate *node);
+
+		const TString &getName() const;
+		void addCallee(FunctionNode *callee);
+		unsigned int analyzeCallDepth(AnalyzeCallDepth *analyzeCallDepth);
+		unsigned int getLastDepth() const;
+
+		void removeIfUnreachable();
+
+	private:
+		TIntermAggregate *const node;
+		TVector<FunctionNode*> callees;
+
+		Visit visit;
+		unsigned int callDepth;
+	};
+
+	FunctionNode *findFunctionByName(const TString &name);
+
+	std::vector<FunctionNode*> functions;
+	typedef std::set<FunctionNode*> FunctionSet;
+	FunctionSet globalFunctionCalls;
+	FunctionNode *currentFunction;
+};
+
+#endif  // COMPILER_ANALYZE_CALL_DEPTH_H_
diff --git a/src/OpenGL/compiler/BaseTypes.h b/src/OpenGL/compiler/BaseTypes.h
index 1a58d54..58c0856 100644
--- a/src/OpenGL/compiler/BaseTypes.h
+++ b/src/OpenGL/compiler/BaseTypes.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _BASICTYPES_INCLUDED_
 #define _BASICTYPES_INCLUDED_
@@ -14,22 +22,22 @@
 //
 enum TPrecision : unsigned char
 {
-    // These need to be kept sorted
-    EbpUndefined,
-    EbpLow,
-    EbpMedium,
-    EbpHigh
+	// These need to be kept sorted
+	EbpUndefined,
+	EbpLow,
+	EbpMedium,
+	EbpHigh
 };
 
 inline const char *getPrecisionString(TPrecision precision)
 {
-    switch(precision)
-    {
-    case EbpHigh:		return "highp";		break;
-    case EbpMedium:		return "mediump";	break;
-    case EbpLow:		return "lowp";		break;
-    default:			return "mediump";   break;   // Safest fallback
-    }
+	switch(precision)
+	{
+	case EbpHigh:		return "highp";		break;
+	case EbpMedium:		return "mediump";	break;
+	case EbpLow:		return "lowp";		break;
+	default:			return "mediump";   break;   // Safest fallback
+	}
 }
 
 //
@@ -37,46 +45,46 @@
 //
 enum TBasicType : unsigned char
 {
-    EbtVoid,
-    EbtFloat,
-    EbtInt,
-    EbtUInt,
-    EbtBool,
-    EbtGVec4,              // non type: represents vec4, ivec4, and uvec4
-    EbtGenType,            // non type: represents float, vec2, vec3, and vec4
-    EbtGenIType,           // non type: represents int, ivec2, ivec3, and ivec4
-    EbtGenUType,           // non type: represents uint, uvec2, uvec3, and uvec4
-    EbtGenBType,           // non type: represents bool, bvec2, bvec3, and bvec4
-    EbtVec,                // non type: represents vec2, vec3, and vec4
-    EbtIVec,               // non type: represents ivec2, ivec3, and ivec4
-    EbtUVec,               // non type: represents uvec2, uvec3, and uvec4
-    EbtBVec,               // non type: represents bvec2, bvec3, and bvec4
-    EbtGuardSamplerBegin,  // non type: see implementation of IsSampler()
-    EbtSampler2D,
-    EbtSampler3D,
-    EbtSamplerCube,
-    EbtSampler2DArray,
-    EbtSamplerExternalOES,  // Only valid if OES_EGL_image_external exists.
-    EbtISampler2D,
-    EbtISampler3D,
-    EbtISamplerCube,
-    EbtISampler2DArray,
-    EbtUSampler2D,
-    EbtUSampler3D,
-    EbtUSamplerCube,
-    EbtUSampler2DArray,
-    EbtSampler2DShadow,
-    EbtSamplerCubeShadow,
-    EbtSampler2DArrayShadow,
-    EbtGuardSamplerEnd,    // non type: see implementation of IsSampler()
-    EbtGSampler2D,         // non type: represents sampler2D, isampler2D, and usampler2D
-    EbtGSampler3D,         // non type: represents sampler3D, isampler3D, and usampler3D
-    EbtGSamplerCube,       // non type: represents samplerCube, isamplerCube, and usamplerCube
-    EbtGSampler2DArray,    // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
-    EbtStruct,
-    EbtInterfaceBlock,
-    EbtAddress,            // should be deprecated??
-    EbtInvariant           // used as a type when qualifying a previously declared variable as being invariant
+	EbtVoid,
+	EbtFloat,
+	EbtInt,
+	EbtUInt,
+	EbtBool,
+	EbtGVec4,              // non type: represents vec4, ivec4, and uvec4
+	EbtGenType,            // non type: represents float, vec2, vec3, and vec4
+	EbtGenIType,           // non type: represents int, ivec2, ivec3, and ivec4
+	EbtGenUType,           // non type: represents uint, uvec2, uvec3, and uvec4
+	EbtGenBType,           // non type: represents bool, bvec2, bvec3, and bvec4
+	EbtVec,                // non type: represents vec2, vec3, and vec4
+	EbtIVec,               // non type: represents ivec2, ivec3, and ivec4
+	EbtUVec,               // non type: represents uvec2, uvec3, and uvec4
+	EbtBVec,               // non type: represents bvec2, bvec3, and bvec4
+	EbtGuardSamplerBegin,  // non type: see implementation of IsSampler()
+	EbtSampler2D,
+	EbtSampler3D,
+	EbtSamplerCube,
+	EbtSampler2DArray,
+	EbtSamplerExternalOES,  // Only valid if OES_EGL_image_external exists.
+	EbtISampler2D,
+	EbtISampler3D,
+	EbtISamplerCube,
+	EbtISampler2DArray,
+	EbtUSampler2D,
+	EbtUSampler3D,
+	EbtUSamplerCube,
+	EbtUSampler2DArray,
+	EbtSampler2DShadow,
+	EbtSamplerCubeShadow,
+	EbtSampler2DArrayShadow,
+	EbtGuardSamplerEnd,    // non type: see implementation of IsSampler()
+	EbtGSampler2D,         // non type: represents sampler2D, isampler2D, and usampler2D
+	EbtGSampler3D,         // non type: represents sampler3D, isampler3D, and usampler3D
+	EbtGSamplerCube,       // non type: represents samplerCube, isamplerCube, and usamplerCube
+	EbtGSampler2DArray,    // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
+	EbtStruct,
+	EbtInterfaceBlock,
+	EbtAddress,            // should be deprecated??
+	EbtInvariant           // used as a type when qualifying a previously declared variable as being invariant
 };
 
 enum TLayoutMatrixPacking
@@ -96,20 +104,20 @@
 
 inline const char *getBasicString(TBasicType type)
 {
-    switch(type)
-    {
-    case EbtVoid:               return "void";
-    case EbtFloat:              return "float";
-    case EbtInt:                return "int";
-    case EbtUInt:               return "uint";
-    case EbtBool:               return "bool";
-    case EbtSampler2D:          return "sampler2D";
-    case EbtSamplerCube:        return "samplerCube";
-    case EbtSamplerExternalOES: return "samplerExternalOES";
+	switch(type)
+	{
+	case EbtVoid:               return "void";
+	case EbtFloat:              return "float";
+	case EbtInt:                return "int";
+	case EbtUInt:               return "uint";
+	case EbtBool:               return "bool";
+	case EbtSampler2D:          return "sampler2D";
+	case EbtSamplerCube:        return "samplerCube";
+	case EbtSamplerExternalOES: return "samplerExternalOES";
 	case EbtSampler3D:			return "sampler3D";
-    case EbtStruct:             return "structure";
-    default: UNREACHABLE(type); return "unknown type";
-    }
+	case EbtStruct:             return "structure";
+	default: UNREACHABLE(type); return "unknown type";
+	}
 }
 
 inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)
@@ -137,7 +145,7 @@
 
 inline bool IsSampler(TBasicType type)
 {
-    return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
+	return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
 }
 
 inline bool IsIntegerSampler(TBasicType type)
@@ -332,81 +340,81 @@
 //
 enum TQualifier : unsigned char
 {
-    EvqTemporary,     // For temporaries (within a function), read/write
-    EvqGlobal,        // For globals read/write
-    EvqConstExpr,     // User defined constants
-    EvqAttribute,     // Readonly
-    EvqVaryingIn,     // readonly, fragment shaders only
-    EvqVaryingOut,    // vertex shaders only  read/write
-    EvqInvariantVaryingIn,     // readonly, fragment shaders only
-    EvqInvariantVaryingOut,    // vertex shaders only  read/write
-    EvqUniform,       // Readonly, vertex and fragment
+	EvqTemporary,     // For temporaries (within a function), read/write
+	EvqGlobal,        // For globals read/write
+	EvqConstExpr,     // User defined constants
+	EvqAttribute,     // Readonly
+	EvqVaryingIn,     // readonly, fragment shaders only
+	EvqVaryingOut,    // vertex shaders only  read/write
+	EvqInvariantVaryingIn,     // readonly, fragment shaders only
+	EvqInvariantVaryingOut,    // vertex shaders only  read/write
+	EvqUniform,       // Readonly, vertex and fragment
 
-    EvqVertexIn,      // Vertex shader input
-    EvqFragmentOut,   // Fragment shader output
-    EvqVertexOut,     // Vertex shader output
-    EvqFragmentIn,    // Fragment shader input
+	EvqVertexIn,      // Vertex shader input
+	EvqFragmentOut,   // Fragment shader output
+	EvqVertexOut,     // Vertex shader output
+	EvqFragmentIn,    // Fragment shader input
 
-    // pack/unpack input and output
-    EvqInput,
-    EvqOutput,
+	// pack/unpack input and output
+	EvqInput,
+	EvqOutput,
 
-    // parameters
-    EvqIn,
-    EvqOut,
-    EvqInOut,
-    EvqConstReadOnly,
+	// parameters
+	EvqIn,
+	EvqOut,
+	EvqInOut,
+	EvqConstReadOnly,
 
-    // built-ins written by vertex shader
-    EvqPosition,
-    EvqPointSize,
-    EvqInstanceID,
+	// built-ins written by vertex shader
+	EvqPosition,
+	EvqPointSize,
+	EvqInstanceID,
 
-    // built-ins read by fragment shader
-    EvqFragCoord,
-    EvqFrontFacing,
-    EvqPointCoord,
+	// built-ins read by fragment shader
+	EvqFragCoord,
+	EvqFrontFacing,
+	EvqPointCoord,
 
-    // built-ins written by fragment shader
-    EvqFragColor,
-    EvqFragData,
-    EvqFragDepth,
+	// built-ins written by fragment shader
+	EvqFragColor,
+	EvqFragData,
+	EvqFragDepth,
 
-    // GLSL ES 3.0 vertex output and fragment input
-    EvqSmooth,        // Incomplete qualifier, smooth is the default
-    EvqFlat,          // Incomplete qualifier
-    EvqSmoothOut = EvqSmooth,
-    EvqFlatOut = EvqFlat,
-    EvqCentroidOut,   // Implies smooth
-    EvqSmoothIn,
-    EvqFlatIn,
-    EvqCentroidIn,    // Implies smooth
+	// GLSL ES 3.0 vertex output and fragment input
+	EvqSmooth,        // Incomplete qualifier, smooth is the default
+	EvqFlat,          // Incomplete qualifier
+	EvqSmoothOut = EvqSmooth,
+	EvqFlatOut = EvqFlat,
+	EvqCentroidOut,   // Implies smooth
+	EvqSmoothIn,
+	EvqFlatIn,
+	EvqCentroidIn,    // Implies smooth
 
-    // end of list
-    EvqLast
+	// end of list
+	EvqLast
 };
 
 struct TLayoutQualifier
 {
-    static TLayoutQualifier create()
-    {
-        TLayoutQualifier layoutQualifier;
+	static TLayoutQualifier create()
+	{
+		TLayoutQualifier layoutQualifier;
 
-        layoutQualifier.location = -1;
-        layoutQualifier.matrixPacking = EmpUnspecified;
-        layoutQualifier.blockStorage = EbsUnspecified;
+		layoutQualifier.location = -1;
+		layoutQualifier.matrixPacking = EmpUnspecified;
+		layoutQualifier.blockStorage = EbsUnspecified;
 
-        return layoutQualifier;
-    }
+		return layoutQualifier;
+	}
 
-    bool isEmpty() const
-    {
-        return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified;
-    }
+	bool isEmpty() const
+	{
+		return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified;
+	}
 
-    int location;
-    TLayoutMatrixPacking matrixPacking;
-    TLayoutBlockStorage blockStorage;
+	int location;
+	TLayoutMatrixPacking matrixPacking;
+	TLayoutBlockStorage blockStorage;
 };
 
 //
@@ -414,43 +422,43 @@
 //
 inline const char *getQualifierString(TQualifier qualifier)
 {
-    switch(qualifier)
-    {
-    case EvqTemporary:      return "Temporary";      break;
-    case EvqGlobal:         return "Global";         break;
-    case EvqConstExpr:      return "const";          break;
-    case EvqConstReadOnly:  return "const";          break;
-    case EvqAttribute:      return "attribute";      break;
-    case EvqVaryingIn:      return "varying";        break;
-    case EvqVaryingOut:     return "varying";        break;
-    case EvqInvariantVaryingIn: return "invariant varying";	break;
-    case EvqInvariantVaryingOut:return "invariant varying";	break;
-    case EvqUniform:        return "uniform";        break;
-    case EvqVertexIn:       return "in";             break;
-    case EvqFragmentOut:    return "out";            break;
-    case EvqVertexOut:      return "out";            break;
-    case EvqFragmentIn:     return "in";             break;
-    case EvqIn:             return "in";             break;
-    case EvqOut:            return "out";            break;
-    case EvqInOut:          return "inout";          break;
-    case EvqInput:          return "input";          break;
-    case EvqOutput:         return "output";         break;
-    case EvqPosition:       return "Position";       break;
-    case EvqPointSize:      return "PointSize";      break;
-    case EvqInstanceID:     return "InstanceID";     break;
-    case EvqFragCoord:      return "FragCoord";      break;
-    case EvqFrontFacing:    return "FrontFacing";    break;
-    case EvqFragColor:      return "FragColor";      break;
-    case EvqFragData:       return "FragData";       break;
-    case EvqFragDepth:      return "FragDepth";      break;
-    case EvqSmooth:         return "Smooth";         break;
-    case EvqFlat:           return "Flat";           break;
-    case EvqCentroidOut:    return "CentroidOut";    break;
-    case EvqSmoothIn:       return "SmoothIn";       break;
-    case EvqFlatIn:         return "FlatIn";         break;
-    case EvqCentroidIn:     return "CentroidIn";     break;
-    default: UNREACHABLE(qualifier); return "unknown qualifier";
-    }
+	switch(qualifier)
+	{
+	case EvqTemporary:      return "Temporary";      break;
+	case EvqGlobal:         return "Global";         break;
+	case EvqConstExpr:      return "const";          break;
+	case EvqConstReadOnly:  return "const";          break;
+	case EvqAttribute:      return "attribute";      break;
+	case EvqVaryingIn:      return "varying";        break;
+	case EvqVaryingOut:     return "varying";        break;
+	case EvqInvariantVaryingIn: return "invariant varying";	break;
+	case EvqInvariantVaryingOut:return "invariant varying";	break;
+	case EvqUniform:        return "uniform";        break;
+	case EvqVertexIn:       return "in";             break;
+	case EvqFragmentOut:    return "out";            break;
+	case EvqVertexOut:      return "out";            break;
+	case EvqFragmentIn:     return "in";             break;
+	case EvqIn:             return "in";             break;
+	case EvqOut:            return "out";            break;
+	case EvqInOut:          return "inout";          break;
+	case EvqInput:          return "input";          break;
+	case EvqOutput:         return "output";         break;
+	case EvqPosition:       return "Position";       break;
+	case EvqPointSize:      return "PointSize";      break;
+	case EvqInstanceID:     return "InstanceID";     break;
+	case EvqFragCoord:      return "FragCoord";      break;
+	case EvqFrontFacing:    return "FrontFacing";    break;
+	case EvqFragColor:      return "FragColor";      break;
+	case EvqFragData:       return "FragData";       break;
+	case EvqFragDepth:      return "FragDepth";      break;
+	case EvqSmooth:         return "Smooth";         break;
+	case EvqFlat:           return "Flat";           break;
+	case EvqCentroidOut:    return "CentroidOut";    break;
+	case EvqSmoothIn:       return "SmoothIn";       break;
+	case EvqFlatIn:         return "FlatIn";         break;
+	case EvqCentroidIn:     return "CentroidIn";     break;
+	default: UNREACHABLE(qualifier); return "unknown qualifier";
+	}
 }
 
 #endif // _BASICTYPES_INCLUDED_
diff --git a/src/OpenGL/compiler/Common.h b/src/OpenGL/compiler/Common.h
index f3bf435..b6fe5d6 100644
--- a/src/OpenGL/compiler/Common.h
+++ b/src/OpenGL/compiler/Common.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _COMMON_INCLUDED_
 #define _COMMON_INCLUDED_
@@ -25,14 +33,14 @@
 // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
 //
 #define POOL_ALLOCATOR_NEW_DELETE()                                                  \
-    void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); }   \
-    void* operator new(size_t, void *_Where) { return (_Where); }                    \
-    void operator delete(void*) { }                                                  \
-    void operator delete(void *, void *) { }                                         \
-    void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
-    void* operator new[](size_t, void *_Where) { return (_Where); }                  \
-    void operator delete[](void*) { }                                                \
-    void operator delete[](void *, void *) { }
+	void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); }   \
+	void* operator new(size_t, void *_Where) { return (_Where); }                    \
+	void operator delete(void*) { }                                                  \
+	void operator delete(void *, void *) { }                                         \
+	void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+	void* operator new[](size_t, void *_Where) { return (_Where); }                  \
+	void operator delete[](void*) { }                                                \
+	void operator delete[](void *, void *) { }
 
 //
 // Pool version of string.
@@ -58,20 +66,20 @@
 //
 template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
 public:
-    typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
-    TVector() : std::vector<T, pool_allocator<T> >() {}
-    TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
-    TVector(size_type i): std::vector<T, pool_allocator<T> >(i) {}
+	typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
+	TVector() : std::vector<T, pool_allocator<T> >() {}
+	TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
+	TVector(size_type i): std::vector<T, pool_allocator<T> >(i) {}
 };
 
-template <class K, class D, class CMP = std::less<K> > 
+template <class K, class D, class CMP = std::less<K> >
 class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D> > > {
 public:
-    typedef pool_allocator<std::pair<const K, D> > tAllocator;
+	typedef pool_allocator<std::pair<const K, D> > tAllocator;
 
-    TMap() : std::map<K, D, CMP, tAllocator>() {}
-    // use correct two-stage name lookup supported in gcc 3.4 and above
-    TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {}
+	TMap() : std::map<K, D, CMP, tAllocator>() {}
+	// use correct two-stage name lookup supported in gcc 3.4 and above
+	TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {}
 };
 
 #endif // _COMMON_INCLUDED_
diff --git a/src/OpenGL/compiler/Compiler.cpp b/src/OpenGL/compiler/Compiler.cpp
index cbb04f5..7861acf 100644
--- a/src/OpenGL/compiler/Compiler.cpp
+++ b/src/OpenGL/compiler/Compiler.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Compiler.h"
 
@@ -13,23 +21,25 @@
 #include "ParseHelper.h"
 #include "ValidateLimitations.h"
 
-namespace 
+namespace
 {
 class TScopedPoolAllocator {
 public:
-    TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
-        : mAllocator(allocator), mPushPopAllocator(pushPop) {
-        if (mPushPopAllocator) mAllocator->push();
-        SetGlobalPoolAllocator(mAllocator);
-    }
-    ~TScopedPoolAllocator() {
-        SetGlobalPoolAllocator(NULL);
-        if (mPushPopAllocator) mAllocator->pop();
-    }
+	TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
+		: mAllocator(allocator), mPushPopAllocator(pushPop)
+	{
+		if (mPushPopAllocator) mAllocator->push();
+		SetGlobalPoolAllocator(mAllocator);
+	}
+	~TScopedPoolAllocator()
+	{
+		SetGlobalPoolAllocator(nullptr);
+		if (mPushPopAllocator) mAllocator->pop();
+	}
 
 private:
-    TPoolAllocator* mAllocator;
-    bool mPushPopAllocator;
+	TPoolAllocator* mAllocator;
+	bool mPushPopAllocator;
 };
 }  // namespace
 
@@ -38,125 +48,125 @@
 //
 ShBuiltInResources::ShBuiltInResources()
 {
-    // Constants.
-    MaxVertexAttribs = 8;
-    MaxVertexUniformVectors = 128;
-    MaxVaryingVectors = 8;
-    MaxVertexTextureImageUnits = 0;
-    MaxCombinedTextureImageUnits = 8;
-    MaxTextureImageUnits = 8;
-    MaxFragmentUniformVectors = 16;
-    MaxDrawBuffers = 1;
-    MaxVertexOutputVectors = 16;

-    MaxFragmentInputVectors = 15;

-    MinProgramTexelOffset = -8;

-    MaxProgramTexelOffset = 7;
+	// Constants.
+	MaxVertexAttribs = 8;
+	MaxVertexUniformVectors = 128;
+	MaxVaryingVectors = 8;
+	MaxVertexTextureImageUnits = 0;
+	MaxCombinedTextureImageUnits = 8;
+	MaxTextureImageUnits = 8;
+	MaxFragmentUniformVectors = 16;
+	MaxDrawBuffers = 1;
+	MaxVertexOutputVectors = 16;
+	MaxFragmentInputVectors = 15;
+	MinProgramTexelOffset = -8;
+	MaxProgramTexelOffset = 7;
 
-    // Extensions.
-    OES_standard_derivatives = 0;
+	// Extensions.
+	OES_standard_derivatives = 0;
 	OES_fragment_precision_high = 0;
-    OES_EGL_image_external = 0;
+	OES_EGL_image_external = 0;
 
 	MaxCallStackDepth = UINT_MAX;
 }
 
 TCompiler::TCompiler(GLenum type)
-    : shaderType(type),
-      maxCallStackDepth(UINT_MAX)
+	: shaderType(type),
+	  maxCallStackDepth(UINT_MAX)
 {
 	allocator.push();
-    SetGlobalPoolAllocator(&allocator);
+	SetGlobalPoolAllocator(&allocator);
 }
 
 TCompiler::~TCompiler()
 {
-	SetGlobalPoolAllocator(NULL);
-    allocator.popAll();
+	SetGlobalPoolAllocator(nullptr);
+	allocator.popAll();
 }
 
 bool TCompiler::Init(const ShBuiltInResources& resources)
 {
-    shaderVersion = 100;
-    maxCallStackDepth = resources.MaxCallStackDepth;
-    TScopedPoolAllocator scopedAlloc(&allocator, false);
+	shaderVersion = 100;
+	maxCallStackDepth = resources.MaxCallStackDepth;
+	TScopedPoolAllocator scopedAlloc(&allocator, false);
 
-    // Generate built-in symbol table.
-    if (!InitBuiltInSymbolTable(resources))
-        return false;
-    InitExtensionBehavior(resources, extensionBehavior);
+	// Generate built-in symbol table.
+	if (!InitBuiltInSymbolTable(resources))
+		return false;
+	InitExtensionBehavior(resources, extensionBehavior);
 
-    return true;
+	return true;
 }
 
 bool TCompiler::compile(const char* const shaderStrings[],
                         const int numStrings,
                         int compileOptions)
 {
-    TScopedPoolAllocator scopedAlloc(&allocator, true);
-    clearResults();
+	TScopedPoolAllocator scopedAlloc(&allocator, true);
+	clearResults();
 
-    if (numStrings == 0)
-        return true;
+	if (numStrings == 0)
+		return true;
 
-    // First string is path of source file if flag is set. The actual source follows.
-    const char* sourcePath = NULL;
-    int firstSource = 0;
-    if (compileOptions & SH_SOURCE_PATH)
-    {
-        sourcePath = shaderStrings[0];
-        ++firstSource;
-    }
+	// First string is path of source file if flag is set. The actual source follows.
+	const char* sourcePath = nullptr;
+	int firstSource = 0;
+	if (compileOptions & SH_SOURCE_PATH)
+	{
+		sourcePath = shaderStrings[0];
+		++firstSource;
+	}
 
-    TIntermediate intermediate(infoSink);
-    TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
-                               shaderType, compileOptions, true,
-                               sourcePath, infoSink);
-    SetGlobalParseContext(&parseContext);
+	TIntermediate intermediate(infoSink);
+	TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
+	                           shaderType, compileOptions, true,
+	                           sourcePath, infoSink);
+	SetGlobalParseContext(&parseContext);
 
-    // We preserve symbols at the built-in level from compile-to-compile.
-    // Start pushing the user-defined symbols at global level.
-    symbolTable.push();
-    if (!symbolTable.atGlobalLevel())
-        infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
+	// We preserve symbols at the built-in level from compile-to-compile.
+	// Start pushing the user-defined symbols at global level.
+	symbolTable.push();
+	if (!symbolTable.atGlobalLevel())
+		infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
 
-    // Parse shader.
-    bool success =
-        (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
-        (parseContext.getTreeRoot() != NULL);
+	// Parse shader.
+	bool success =
+		(PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr, &parseContext) == 0) &&
+		(parseContext.getTreeRoot() != nullptr);
 
-    shaderVersion = parseContext.getShaderVersion();
+	shaderVersion = parseContext.getShaderVersion();
 
-    if (success) {
-        TIntermNode* root = parseContext.getTreeRoot();
-        success = intermediate.postProcess(root);
+	if (success) {
+		TIntermNode* root = parseContext.getTreeRoot();
+		success = intermediate.postProcess(root);
 
-        if (success)
-            success = validateCallDepth(root, infoSink);
+		if (success)
+			success = validateCallDepth(root, infoSink);
 
-        if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
-            success = validateLimitations(root);
+		if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
+			success = validateLimitations(root);
 
-        if (success && (compileOptions & SH_INTERMEDIATE_TREE))
-            intermediate.outputTree(root);
+		if (success && (compileOptions & SH_INTERMEDIATE_TREE))
+			intermediate.outputTree(root);
 
-        if (success && (compileOptions & SH_OBJECT_CODE))
-            success = translate(root);
-    }
+		if (success && (compileOptions & SH_OBJECT_CODE))
+			success = translate(root);
+	}
 
-    // Ensure symbol table is returned to the built-in level,
-    // throwing away all but the built-ins.
-    while (!symbolTable.atBuiltInLevel())
-        symbolTable.pop();
+	// Ensure symbol table is returned to the built-in level,
+	// throwing away all but the built-ins.
+	while (!symbolTable.atBuiltInLevel())
+		symbolTable.pop();
 
-    return success;
+	return success;
 }
 
 bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
 {
-    assert(symbolTable.isEmpty());
-    symbolTable.push();   // COMMON_BUILTINS
-    symbolTable.push();   // ESSL1_BUILTINS
-    symbolTable.push();   // ESSL3_BUILTINS
+	assert(symbolTable.isEmpty());
+	symbolTable.push();   // COMMON_BUILTINS
+	symbolTable.push();   // ESSL1_BUILTINS
+	symbolTable.push();   // ESSL3_BUILTINS
 
 	TPublicType integer;
 	integer.type = EbtInt;
@@ -172,88 +182,88 @@
 
 	switch(shaderType)
 	{
-    case GL_FRAGMENT_SHADER:
+	case GL_FRAGMENT_SHADER:
 		symbolTable.setDefaultPrecision(integer, EbpMedium);
-        break;
-    case GL_VERTEX_SHADER:
+		break;
+	case GL_VERTEX_SHADER:
 		symbolTable.setDefaultPrecision(integer, EbpHigh);
 		symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
-        break;
-    default: assert(false && "Language not supported");
-    }
+		break;
+	default: assert(false && "Language not supported");
+	}
 
 	InsertBuiltInFunctions(shaderType, resources, symbolTable);
 
-    IdentifyBuiltIns(shaderType, resources, symbolTable);
+	IdentifyBuiltIns(shaderType, resources, symbolTable);
 
-    return true;
+	return true;
 }
 
 void TCompiler::clearResults()
 {
-    infoSink.info.erase();
-    infoSink.obj.erase();
-    infoSink.debug.erase();
+	infoSink.info.erase();
+	infoSink.obj.erase();
+	infoSink.debug.erase();
 }
 
 bool TCompiler::validateCallDepth(TIntermNode *root, TInfoSink &infoSink)
 {
-    AnalyzeCallDepth validator(root);
-    
+	AnalyzeCallDepth validator(root);
+
 	unsigned int depth = validator.analyzeCallDepth();
-	
+
 	if(depth == 0)
 	{
-        infoSink.info.prefix(EPrefixError);
-        infoSink.info << "Missing main()";
-        return false;
+		infoSink.info.prefix(EPrefixError);
+		infoSink.info << "Missing main()";
+		return false;
 	}
-    else if(depth == UINT_MAX)
+	else if(depth == UINT_MAX)
 	{
-        infoSink.info.prefix(EPrefixError);
-        infoSink.info << "Function recursion detected";
-        return false;
+		infoSink.info.prefix(EPrefixError);
+		infoSink.info << "Function recursion detected";
+		return false;
 	}
 	else if(depth > maxCallStackDepth)
 	{
-        infoSink.info.prefix(EPrefixError);
-        infoSink.info << "Function call stack too deep";
-        return false;
+		infoSink.info.prefix(EPrefixError);
+		infoSink.info << "Function call stack too deep";
+		return false;
 	}
 
-    return true;
+	return true;
 }
 
 bool TCompiler::validateLimitations(TIntermNode* root) {
-    ValidateLimitations validate(shaderType, infoSink.info);
-    root->traverse(&validate);
-    return validate.numErrors() == 0;
+	ValidateLimitations validate(shaderType, infoSink.info);
+	root->traverse(&validate);
+	return validate.numErrors() == 0;
 }
 
 const TExtensionBehavior& TCompiler::getExtensionBehavior() const
 {
-    return extensionBehavior;
+	return extensionBehavior;
 }
 
 bool InitCompilerGlobals()
 {
-    if(!InitializePoolIndex())
+	if(!InitializePoolIndex())
 	{
-        assert(0 && "InitCompilerGlobals(): Failed to initalize global pool");
-        return false;
-    }
+		assert(0 && "InitCompilerGlobals(): Failed to initalize global pool");
+		return false;
+	}
 
-    if(!InitializeParseContextIndex())
+	if(!InitializeParseContextIndex())
 	{
-        assert(0 && "InitCompilerGlobals(): Failed to initalize parse context");
-        return false;
-    }
+		assert(0 && "InitCompilerGlobals(): Failed to initalize parse context");
+		return false;
+	}
 
-    return true;
+	return true;
 }
 
 void FreeCompilerGlobals()
 {
-    FreeParseContextIndex();
-    FreePoolIndex();
+	FreeParseContextIndex();
+	FreePoolIndex();
 }
diff --git a/src/OpenGL/compiler/Compiler.h b/src/OpenGL/compiler/Compiler.h
index c90dbd2..8cdc755 100644
--- a/src/OpenGL/compiler/Compiler.h
+++ b/src/OpenGL/compiler/Compiler.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _COMPILER_INCLUDED_
 #define _COMPILER_INCLUDED_
@@ -30,28 +38,28 @@
 {
 	ShBuiltInResources();
 
-    // Constants.
-    int MaxVertexAttribs;
-    int MaxVertexUniformVectors;
-    int MaxVaryingVectors;
-    int MaxVertexTextureImageUnits;
-    int MaxCombinedTextureImageUnits;
-    int MaxTextureImageUnits;
-    int MaxFragmentUniformVectors;
-    int MaxDrawBuffers;
-    int MaxVertexOutputVectors;
-    int MaxFragmentInputVectors;
-    int MinProgramTexelOffset;
-    int MaxProgramTexelOffset;
+	// Constants.
+	int MaxVertexAttribs;
+	int MaxVertexUniformVectors;
+	int MaxVaryingVectors;
+	int MaxVertexTextureImageUnits;
+	int MaxCombinedTextureImageUnits;
+	int MaxTextureImageUnits;
+	int MaxFragmentUniformVectors;
+	int MaxDrawBuffers;
+	int MaxVertexOutputVectors;
+	int MaxFragmentInputVectors;
+	int MinProgramTexelOffset;
+	int MaxProgramTexelOffset;
 
-    // Extensions.
-    // Set to 1 to enable the extension, else 0.
-    int OES_standard_derivatives;
+	// Extensions.
+	// Set to 1 to enable the extension, else 0.
+	int OES_standard_derivatives;
 	int OES_fragment_precision_high;
-    int OES_EGL_image_external;
+	int OES_EGL_image_external;
 	int EXT_draw_buffers;
 
-    unsigned int MaxCallStackDepth;
+	unsigned int MaxCallStackDepth;
 };
 
 typedef unsigned int GLenum;
@@ -65,53 +73,53 @@
 class TCompiler
 {
 public:
-    TCompiler(GLenum shaderType);
-    virtual ~TCompiler();
-    virtual TCompiler* getAsCompiler() { return this; }
+	TCompiler(GLenum shaderType);
+	virtual ~TCompiler();
+	virtual TCompiler* getAsCompiler() { return this; }
 
-    bool Init(const ShBuiltInResources& resources);
-    bool compile(const char* const shaderStrings[],
-                 const int numStrings,
-                 int compileOptions);
+	bool Init(const ShBuiltInResources& resources);
+	bool compile(const char* const shaderStrings[],
+	             const int numStrings,
+	             int compileOptions);
 
-    // Get results of the last compilation.
-    int getShaderVersion() const { return shaderVersion; }
-    TInfoSink& getInfoSink() { return infoSink; }
+	// Get results of the last compilation.
+	int getShaderVersion() const { return shaderVersion; }
+	TInfoSink& getInfoSink() { return infoSink; }
 
 protected:
-    GLenum getShaderType() const { return shaderType; }
-    // Initialize symbol-table with built-in symbols.
-    bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
-    // Clears the results from the previous compilation.
-    void clearResults();
-    // Return true if function recursion is detected or call depth exceeded.
-    bool validateCallDepth(TIntermNode *root, TInfoSink &infoSink);
-    // Returns true if the given shader does not exceed the minimum
-    // functionality mandated in GLSL 1.0 spec Appendix A.
-    bool validateLimitations(TIntermNode *root);
-    // Translate to object code.
-    virtual bool translate(TIntermNode *root) = 0;
-    // Get built-in extensions with default behavior.
-    const TExtensionBehavior& getExtensionBehavior() const;
+	GLenum getShaderType() const { return shaderType; }
+	// Initialize symbol-table with built-in symbols.
+	bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
+	// Clears the results from the previous compilation.
+	void clearResults();
+	// Return true if function recursion is detected or call depth exceeded.
+	bool validateCallDepth(TIntermNode *root, TInfoSink &infoSink);
+	// Returns true if the given shader does not exceed the minimum
+	// functionality mandated in GLSL 1.0 spec Appendix A.
+	bool validateLimitations(TIntermNode *root);
+	// Translate to object code.
+	virtual bool translate(TIntermNode *root) = 0;
+	// Get built-in extensions with default behavior.
+	const TExtensionBehavior& getExtensionBehavior() const;
 
 private:
-    GLenum shaderType;
+	GLenum shaderType;
 
-    unsigned int maxCallStackDepth;
+	unsigned int maxCallStackDepth;
 
-    // Built-in symbol table for the given language, spec, and resources.
-    // It is preserved from compile-to-compile.
-    TSymbolTable symbolTable;
-    // Built-in extensions with default behavior.
-    TExtensionBehavior extensionBehavior;
+	// Built-in symbol table for the given language, spec, and resources.
+	// It is preserved from compile-to-compile.
+	TSymbolTable symbolTable;
+	// Built-in extensions with default behavior.
+	TExtensionBehavior extensionBehavior;
 
-    // Results of compilation.
-    int shaderVersion;
-    TInfoSink infoSink;  // Output sink.
+	// Results of compilation.
+	int shaderVersion;
+	TInfoSink infoSink;  // Output sink.
 
-    // Memory allocator. Allocates and tracks memory required by the compiler.
-    // Deallocates all memory when compiler is destructed.
-    TPoolAllocator allocator;
+	// Memory allocator. Allocates and tracks memory required by the compiler.
+	// Deallocates all memory when compiler is destructed.
+	TPoolAllocator allocator;
 };
 
 bool InitCompilerGlobals();
diff --git a/src/OpenGL/compiler/ConstantUnion.h b/src/OpenGL/compiler/ConstantUnion.h
index b001ec4..27f816c 100644
--- a/src/OpenGL/compiler/ConstantUnion.h
+++ b/src/OpenGL/compiler/ConstantUnion.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _CONSTANT_UNION_INCLUDED_
 #define _CONSTANT_UNION_INCLUDED_
@@ -16,82 +24,82 @@
 class ConstantUnion {
 public:
 	POOL_ALLOCATOR_NEW_DELETE();
-    ConstantUnion()
-    {
-        iConst = 0;
-        type = EbtVoid;
-    }
+	ConstantUnion()
+	{
+		iConst = 0;
+		type = EbtVoid;
+	}
 
-    bool cast(TBasicType newType, const ConstantUnion &constant)
-    {
-        switch (newType)
-        {
-          case EbtFloat:
-            switch (constant.type)
-            {
-              case EbtInt:   setFConst(static_cast<float>(constant.getIConst())); break;
-              case EbtUInt:  setFConst(static_cast<float>(constant.getUConst())); break;
-              case EbtBool:  setFConst(static_cast<float>(constant.getBConst())); break;
-              case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
-              default:       return false;
-            }
-            break;
-          case EbtInt:
-            switch (constant.type)
-            {
-              case EbtInt:   setIConst(static_cast<int>(constant.getIConst())); break;
-              case EbtUInt:  setIConst(static_cast<int>(constant.getUConst())); break;
-              case EbtBool:  setIConst(static_cast<int>(constant.getBConst())); break;
-              case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
-              default:       return false;
-            }
-            break;
-          case EbtUInt:
-            switch (constant.type)
-            {
-              case EbtInt:   setUConst(static_cast<unsigned int>(constant.getIConst())); break;
-              case EbtUInt:  setUConst(static_cast<unsigned int>(constant.getUConst())); break;
-              case EbtBool:  setUConst(static_cast<unsigned int>(constant.getBConst())); break;
-              case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
-              default:       return false;
-            }
-            break;
-          case EbtBool:
-            switch (constant.type)
-            {
-              case EbtInt:   setBConst(constant.getIConst() != 0);    break;
-              case EbtUInt:  setBConst(constant.getUConst() != 0);    break;
-              case EbtBool:  setBConst(constant.getBConst());         break;
-              case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
-              default:       return false;
-            }
-            break;
-          case EbtStruct:    // Struct fields don't get cast
-            switch (constant.type)
-            {
-              case EbtInt:   setIConst(constant.getIConst()); break;
-              case EbtUInt:  setUConst(constant.getUConst()); break;
-              case EbtBool:  setBConst(constant.getBConst()); break;
-              case EbtFloat: setFConst(constant.getFConst()); break;
-              default:       return false;
-            }
-            break;
-          default:
-            return false;
-        }
+	bool cast(TBasicType newType, const ConstantUnion &constant)
+	{
+		switch (newType)
+		{
+		case EbtFloat:
+			switch (constant.type)
+			{
+			case EbtInt:   setFConst(static_cast<float>(constant.getIConst())); break;
+			case EbtUInt:  setFConst(static_cast<float>(constant.getUConst())); break;
+			case EbtBool:  setFConst(static_cast<float>(constant.getBConst())); break;
+			case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
+			default:       return false;
+			}
+			break;
+		case EbtInt:
+			switch (constant.type)
+			{
+			case EbtInt:   setIConst(static_cast<int>(constant.getIConst())); break;
+			case EbtUInt:  setIConst(static_cast<int>(constant.getUConst())); break;
+			case EbtBool:  setIConst(static_cast<int>(constant.getBConst())); break;
+			case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
+			default:       return false;
+			}
+			break;
+		case EbtUInt:
+			switch (constant.type)
+			{
+			case EbtInt:   setUConst(static_cast<unsigned int>(constant.getIConst())); break;
+			case EbtUInt:  setUConst(static_cast<unsigned int>(constant.getUConst())); break;
+			case EbtBool:  setUConst(static_cast<unsigned int>(constant.getBConst())); break;
+			case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
+			default:       return false;
+			}
+			break;
+		case EbtBool:
+			switch (constant.type)
+			{
+			case EbtInt:   setBConst(constant.getIConst() != 0);    break;
+			case EbtUInt:  setBConst(constant.getUConst() != 0);    break;
+			case EbtBool:  setBConst(constant.getBConst());         break;
+			case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
+			default:       return false;
+			}
+			break;
+		case EbtStruct:    // Struct fields don't get cast
+			switch (constant.type)
+			{
+			case EbtInt:   setIConst(constant.getIConst()); break;
+			case EbtUInt:  setUConst(constant.getUConst()); break;
+			case EbtBool:  setBConst(constant.getBConst()); break;
+			case EbtFloat: setFConst(constant.getFConst()); break;
+			default:       return false;
+			}
+			break;
+		default:
+			return false;
+		}
 
-        return true;
-    }
+		return true;
+	}
 
-    void setIConst(int i) {iConst = i; type = EbtInt; }
-    void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
-    void setFConst(float f) {fConst = f; type = EbtFloat; }
-    void setBConst(bool b) {bConst = b; type = EbtBool; }
+	void setIConst(int i) {iConst = i; type = EbtInt; }
+	void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
+	void setFConst(float f) {fConst = f; type = EbtFloat; }
+	void setBConst(bool b) {bConst = b; type = EbtBool; }
 
-    int getIConst() const { return iConst; }
-    unsigned int getUConst() const { return uConst; }
-    float getFConst() const { return fConst; }
-    bool getBConst() const { return bConst; }
+	int getIConst() const { return iConst; }
+	unsigned int getUConst() const { return uConst; }
+	float getFConst() const { return fConst; }
+	bool getBConst() const { return bConst; }
 
 	float getAsFloat() const
 	{
@@ -99,306 +107,306 @@
 
 		switch(type)
 		{
-        case EbtInt:   return reinterpret_cast<const float&>(iConst);
+		case EbtInt:   return reinterpret_cast<const float&>(iConst);
 		case EbtUInt:  return reinterpret_cast<const float&>(uConst);
-        case EbtFloat: return fConst;
+		case EbtFloat: return fConst;
 		case EbtBool:  return (bConst == true) ? reinterpret_cast<const float&>(FFFFFFFFh) : 0;
-        default:       return 0;
-        }
+		default:       return 0;
+		}
 	}
 
-    bool operator==(const int i) const
-    {
-        return i == iConst;
-    }
+	bool operator==(const int i) const
+	{
+		return i == iConst;
+	}
 
-    bool operator==(const unsigned int u) const
-    {
-        return u == uConst;
-    }
+	bool operator==(const unsigned int u) const
+	{
+		return u == uConst;
+	}
 
-    bool operator==(const float f) const
-    {
-        return f == fConst;
-    }
+	bool operator==(const float f) const
+	{
+		return f == fConst;
+	}
 
-    bool operator==(const bool b) const
-    {
-        return b == bConst;
-    }
+	bool operator==(const bool b) const
+	{
+		return b == bConst;
+	}
 
-    bool operator==(const ConstantUnion& constant) const
-    {
-        if (constant.type != type)
-            return false;
+	bool operator==(const ConstantUnion& constant) const
+	{
+		if (constant.type != type)
+			return false;
 
-        switch (type) {
-        case EbtInt:
-            return constant.iConst == iConst;
-        case EbtUInt:
-            return constant.uConst == uConst;
-        case EbtFloat:
-            return constant.fConst == fConst;
-        case EbtBool:
-            return constant.bConst == bConst;
-        default:
-            return false;
-        }
+		switch (type) {
+		case EbtInt:
+			return constant.iConst == iConst;
+		case EbtUInt:
+			return constant.uConst == uConst;
+		case EbtFloat:
+			return constant.fConst == fConst;
+		case EbtBool:
+			return constant.bConst == bConst;
+		default:
+			return false;
+		}
 
-        return false;
-    }
+		return false;
+	}
 
-    bool operator!=(const int i) const
-    {
-        return !operator==(i);
-    }
+	bool operator!=(const int i) const
+	{
+		return !operator==(i);
+	}
 
-    bool operator!=(const unsigned int u) const
-    {
-        return !operator==(u);
-    }
+	bool operator!=(const unsigned int u) const
+	{
+		return !operator==(u);
+	}
 
-    bool operator!=(const float f) const
-    {
-        return !operator==(f);
-    }
+	bool operator!=(const float f) const
+	{
+		return !operator==(f);
+	}
 
-    bool operator!=(const bool b) const
-    {
-        return !operator==(b);
-    }
+	bool operator!=(const bool b) const
+	{
+		return !operator==(b);
+	}
 
-    bool operator!=(const ConstantUnion& constant) const
-    {
-        return !operator==(constant);
-    }
+	bool operator!=(const ConstantUnion& constant) const
+	{
+		return !operator==(constant);
+	}
 
-    bool operator>(const ConstantUnion& constant) const
-    {
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt:
-            return iConst > constant.iConst;
-        case EbtUInt:
-            return uConst > constant.uConst;
-        case EbtFloat:
-            return fConst > constant.fConst;
-        default:
-            return false;   // Invalid operation, handled at semantic analysis
-        }
+	bool operator>(const ConstantUnion& constant) const
+	{
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt:
+			return iConst > constant.iConst;
+		case EbtUInt:
+			return uConst > constant.uConst;
+		case EbtFloat:
+			return fConst > constant.fConst;
+		default:
+			return false;   // Invalid operation, handled at semantic analysis
+		}
 
-        return false;
-    }
+		return false;
+	}
 
-    bool operator<(const ConstantUnion& constant) const
-    {
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt:
-            return iConst < constant.iConst;
-        case EbtUInt:
-            return uConst < constant.uConst;
-        case EbtFloat:
-            return fConst < constant.fConst;
-        default:
-            return false;   // Invalid operation, handled at semantic analysis
-        }
+	bool operator<(const ConstantUnion& constant) const
+	{
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt:
+			return iConst < constant.iConst;
+		case EbtUInt:
+			return uConst < constant.uConst;
+		case EbtFloat:
+			return fConst < constant.fConst;
+		default:
+			return false;   // Invalid operation, handled at semantic analysis
+		}
 
-        return false;
-    }
+		return false;
+	}
 
 	bool operator<=(const ConstantUnion& constant) const
-    {
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt:
-            return iConst <= constant.iConst;
-        case EbtUInt:
-            return uConst <= constant.uConst;
-        case EbtFloat:
-            return fConst <= constant.fConst;
-        default:
-            return false;   // Invalid operation, handled at semantic analysis
-        }
+	{
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt:
+			return iConst <= constant.iConst;
+		case EbtUInt:
+			return uConst <= constant.uConst;
+		case EbtFloat:
+			return fConst <= constant.fConst;
+		default:
+			return false;   // Invalid operation, handled at semantic analysis
+		}
 
-        return false;
-    }
+		return false;
+	}
 
 	bool operator>=(const ConstantUnion& constant) const
-    {
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt:
-            return iConst >= constant.iConst;
-        case EbtUInt:
-            return uConst >= constant.uConst;
-        case EbtFloat:
-            return fConst >= constant.fConst;
-        default:
-            return false;   // Invalid operation, handled at semantic analysis
-        }
+	{
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt:
+			return iConst >= constant.iConst;
+		case EbtUInt:
+			return uConst >= constant.uConst;
+		case EbtFloat:
+			return fConst >= constant.fConst;
+		default:
+			return false;   // Invalid operation, handled at semantic analysis
+		}
 
-        return false;
-    }
+		return false;
+	}
 
-    ConstantUnion operator+(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
-        case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
-        case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
-        default: assert(false && "Default missing");
-        }
+	ConstantUnion operator+(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
+		case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
+		case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
+		default: assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator-(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
-        case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
-        case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
-        default: assert(false && "Default missing");
-        }
+	ConstantUnion operator-(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
+		case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
+		case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
+		default: assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator*(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
-        case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
-        case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
-        default: assert(false && "Default missing");
-        }
+	ConstantUnion operator*(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
+		case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
+		case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
+		default: assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator%(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
-        case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator%(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
+		case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator>>(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
-        case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator>>(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
+		case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator<<(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        // The signedness of the second parameter might be different, but we
-        // don't care, since the result is undefined if the second parameter is
-        // negative, and aliasing should not be a problem with unions.
-        assert(constant.type == EbtInt || constant.type == EbtUInt);
-        switch (type) {
-        case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
-        case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator<<(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		// The signedness of the second parameter might be different, but we
+		// don't care, since the result is undefined if the second parameter is
+		// negative, and aliasing should not be a problem with unions.
+		assert(constant.type == EbtInt || constant.type == EbtUInt);
+		switch (type) {
+		case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
+		case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator&(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(constant.type == EbtInt || constant.type == EbtUInt);
-        switch (type) {
-        case EbtInt:  returnValue.setIConst(iConst & constant.iConst); break;
-        case EbtUInt:  returnValue.setUConst(uConst & constant.uConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator&(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(constant.type == EbtInt || constant.type == EbtUInt);
+		switch (type) {
+		case EbtInt:  returnValue.setIConst(iConst & constant.iConst); break;
+		case EbtUInt:  returnValue.setUConst(uConst & constant.uConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator|(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
-        case EbtUInt:  returnValue.setUConst(uConst | constant.uConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator|(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
+		case EbtUInt:  returnValue.setUConst(uConst | constant.uConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator^(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
-        case EbtUInt:  returnValue.setUConst(uConst ^ constant.uConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator^(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
+		case EbtUInt:  returnValue.setUConst(uConst ^ constant.uConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator&&(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator&&(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    ConstantUnion operator||(const ConstantUnion& constant) const
-    {
-        ConstantUnion returnValue;
-        assert(type == constant.type);
-        switch (type) {
-        case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
-        default:     assert(false && "Default missing");
-        }
+	ConstantUnion operator||(const ConstantUnion& constant) const
+	{
+		ConstantUnion returnValue;
+		assert(type == constant.type);
+		switch (type) {
+		case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
+		default:     assert(false && "Default missing");
+		}
 
-        return returnValue;
-    }
+		return returnValue;
+	}
 
-    TBasicType getType() const { return type; }
+	TBasicType getType() const { return type; }
 private:
 
-    union  {
-        int iConst;  // used for ivec, scalar ints
-        unsigned int uConst; // used for uvec, scalar uints
-        bool bConst; // used for bvec, scalar bools
-        float fConst;   // used for vec, mat, scalar floats
-    } ;
+	union  {
+		int iConst;  // used for ivec, scalar ints
+		unsigned int uConst; // used for uvec, scalar uints
+		bool bConst; // used for bvec, scalar bools
+		float fConst;   // used for vec, mat, scalar floats
+	} ;
 
-    TBasicType type;
+	TBasicType type;
 };
 
 #endif // _CONSTANT_UNION_INCLUDED_
diff --git a/src/OpenGL/compiler/Diagnostics.cpp b/src/OpenGL/compiler/Diagnostics.cpp
index 65aa6ed..490ecfe 100644
--- a/src/OpenGL/compiler/Diagnostics.cpp
+++ b/src/OpenGL/compiler/Diagnostics.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Diagnostics.h"
 
@@ -11,10 +19,10 @@
 #include "preprocessor/SourceLocation.h"
 
 TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
-    mShaderVersion(100),
-    mInfoSink(infoSink),
-    mNumErrors(0),
-    mNumWarnings(0)
+	mShaderVersion(100),
+	mInfoSink(infoSink),
+	mNumErrors(0),
+	mNumWarnings(0)
 {
 }
 
@@ -24,7 +32,7 @@
 
 void TDiagnostics::setShaderVersion(int version)
 {
-    mShaderVersion = version;
+	mShaderVersion = version;
 }
 
 void TDiagnostics::writeInfo(Severity severity,
@@ -33,40 +41,40 @@
                              const std::string& token,
                              const std::string& extra)
 {
-    TPrefixType prefix = EPrefixNone;
-    switch (severity)
-    {
-      case PP_ERROR:
-        ++mNumErrors;
-        prefix = EPrefixError;
-        break;
-      case PP_WARNING:
-        ++mNumWarnings;
-        prefix = EPrefixWarning;
-        break;
-      default:
-        UNREACHABLE(severity);
-        break;
-    }
+	TPrefixType prefix = EPrefixNone;
+	switch(severity)
+	{
+	case PP_ERROR:
+		++mNumErrors;
+		prefix = EPrefixError;
+		break;
+	case PP_WARNING:
+		++mNumWarnings;
+		prefix = EPrefixWarning;
+		break;
+	default:
+		UNREACHABLE(severity);
+		break;
+	}
 
-    TInfoSinkBase& sink = mInfoSink.info;
-    /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
-    sink.prefix(prefix);
-    TSourceLoc sourceLoc;
-    sourceLoc.first_file = sourceLoc.last_file = loc.file;
-    sourceLoc.first_line = sourceLoc.last_line = loc.line;
-    sink.location(sourceLoc);
-    sink << "'" << token <<  "' : " << reason << " " << extra << "\n";
+	TInfoSinkBase& sink = mInfoSink.info;
+	/* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+	sink.prefix(prefix);
+	TSourceLoc sourceLoc;
+	sourceLoc.first_file = sourceLoc.last_file = loc.file;
+	sourceLoc.first_line = sourceLoc.last_line = loc.line;
+	sink.location(sourceLoc);
+	sink << "'" << token <<  "' : " << reason << " " << extra << "\n";
 }
 
 void TDiagnostics::writeDebug(const std::string& str)
 {
-    mInfoSink.debug << str;
+	mInfoSink.debug << str;
 }
 
 void TDiagnostics::print(ID id,
                          const pp::SourceLocation& loc,
                          const std::string& text)
 {
-    writeInfo(severity(id), loc, message(id), text, "");
+	writeInfo(severity(id), loc, message(id), text, "");
 }
diff --git a/src/OpenGL/compiler/Diagnostics.h b/src/OpenGL/compiler/Diagnostics.h
index 1726924..35983ac 100644
--- a/src/OpenGL/compiler/Diagnostics.h
+++ b/src/OpenGL/compiler/Diagnostics.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef COMPILER_DIAGNOSTICS_H_
 #define COMPILER_DIAGNOSTICS_H_
@@ -13,37 +21,37 @@
 
 class TDiagnostics : public pp::Diagnostics
 {
-  public:
-    TDiagnostics(TInfoSink& infoSink);
-    virtual ~TDiagnostics();
+public:
+	TDiagnostics(TInfoSink& infoSink);
+	virtual ~TDiagnostics();
 
-    int shaderVersion() const { return mShaderVersion; }
-    TInfoSink& infoSink() { return mInfoSink; }
+	int shaderVersion() const { return mShaderVersion; }
+	TInfoSink& infoSink() { return mInfoSink; }
 
-    int numErrors() const { return mNumErrors; }
-    int numWarnings() const { return mNumWarnings; }
+	int numErrors() const { return mNumErrors; }
+	int numWarnings() const { return mNumWarnings; }
 
-    void setShaderVersion(int version);
+	void setShaderVersion(int version);
 
-    void writeInfo(Severity severity,
-                   const pp::SourceLocation& loc,
-                   const std::string& reason,
-                   const std::string& token,
-                   const std::string& extra);
+	void writeInfo(Severity severity,
+				   const pp::SourceLocation& loc,
+				   const std::string& reason,
+				   const std::string& token,
+				   const std::string& extra);
 
-    void writeDebug(const std::string& str);
+	void writeDebug(const std::string& str);
 
-  protected:
-    virtual void print(ID id,
-                       const pp::SourceLocation& loc,
-                       const std::string& text);
+protected:
+	virtual void print(ID id,
+					   const pp::SourceLocation& loc,
+					   const std::string& text);
 
-  private:
-    int mShaderVersion;
+private:
+	int mShaderVersion;
 
-    TInfoSink& mInfoSink;
-    int mNumErrors;
-    int mNumWarnings;
+	TInfoSink& mInfoSink;
+	int mNumErrors;
+	int mNumWarnings;
 };
 
 #endif  // COMPILER_DIAGNOSTICS_H_
diff --git a/src/OpenGL/compiler/DirectiveHandler.cpp b/src/OpenGL/compiler/DirectiveHandler.cpp
index c9368b1..2391d35 100644
--- a/src/OpenGL/compiler/DirectiveHandler.cpp
+++ b/src/OpenGL/compiler/DirectiveHandler.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "DirectiveHandler.h"
 
@@ -13,24 +21,24 @@
 
 static TBehavior getBehavior(const std::string& str)
 {
-    static const std::string kRequire("require");
-    static const std::string kEnable("enable");
-    static const std::string kDisable("disable");
-    static const std::string kWarn("warn");
+	static const std::string kRequire("require");
+	static const std::string kEnable("enable");
+	static const std::string kDisable("disable");
+	static const std::string kWarn("warn");
 
-    if (str == kRequire) return EBhRequire;
-    else if (str == kEnable) return EBhEnable;
-    else if (str == kDisable) return EBhDisable;
-    else if (str == kWarn) return EBhWarn;
-    return EBhUndefined;
+	if (str == kRequire) return EBhRequire;
+	else if (str == kEnable) return EBhEnable;
+	else if (str == kDisable) return EBhDisable;
+	else if (str == kWarn) return EBhWarn;
+	return EBhUndefined;
 }
 
 TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
                                      TDiagnostics& diagnostics,
                                      int& shaderVersion)
-    : mExtensionBehavior(extBehavior),
-      mDiagnostics(diagnostics),
-      mShaderVersion(shaderVersion)
+	: mExtensionBehavior(extBehavior),
+	  mDiagnostics(diagnostics),
+	  mShaderVersion(shaderVersion)
 {
 }
 
@@ -41,126 +49,126 @@
 void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
                                     const std::string& msg)
 {
-    mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
+	mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
 }
 
 void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
                                      const std::string& name,
                                      const std::string& value)
 {
-    static const std::string kSTDGL("STDGL");
-    static const std::string kOptimize("optimize");
-    static const std::string kDebug("debug");
-    static const std::string kOn("on");
-    static const std::string kOff("off");
+	static const std::string kSTDGL("STDGL");
+	static const std::string kOptimize("optimize");
+	static const std::string kDebug("debug");
+	static const std::string kOn("on");
+	static const std::string kOff("off");
 
-    bool invalidValue = false;
-    if (name == kSTDGL)
-    {
-        // The STDGL pragma is used to reserve pragmas for use by future
-        // revisions of GLSL. Ignore it.
-        return;
-    }
-    else if (name == kOptimize)
-    {
-        if (value == kOn) mPragma.optimize = true;
-        else if (value == kOff) mPragma.optimize = false;
-        else invalidValue = true;
-    }
-    else if (name == kDebug)
-    {
-        if (value == kOn) mPragma.debug = true;
-        else if (value == kOff) mPragma.debug = false;
-        else invalidValue = true;
-    }
-    else
-    {
-        mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name);
-        return;
-    }
+	bool invalidValue = false;
+	if (name == kSTDGL)
+	{
+		// The STDGL pragma is used to reserve pragmas for use by future
+		// revisions of GLSL. Ignore it.
+		return;
+	}
+	else if (name == kOptimize)
+	{
+		if (value == kOn) mPragma.optimize = true;
+		else if (value == kOff) mPragma.optimize = false;
+		else invalidValue = true;
+	}
+	else if (name == kDebug)
+	{
+		if (value == kOn) mPragma.debug = true;
+		else if (value == kOff) mPragma.debug = false;
+		else invalidValue = true;
+	}
+	else
+	{
+		mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name);
+		return;
+	}
 
-    if (invalidValue)
-      mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
-                             "invalid pragma value", value,
-                             "'on' or 'off' expected");
+	if (invalidValue)
+		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+		                       "invalid pragma value", value,
+		                       "'on' or 'off' expected");
 }
 
 void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
                                         const std::string& name,
                                         const std::string& behavior)
 {
-    static const std::string kExtAll("all");
+	static const std::string kExtAll("all");
 
-    TBehavior behaviorVal = getBehavior(behavior);
-    if (behaviorVal == EBhUndefined)
-    {
-        mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
-                               "behavior", name, "invalid");
-        return;
-    }
+	TBehavior behaviorVal = getBehavior(behavior);
+	if (behaviorVal == EBhUndefined)
+	{
+		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+		                       "behavior", name, "invalid");
+		return;
+	}
 
-    if (name == kExtAll)
-    {
-        if (behaviorVal == EBhRequire)
-        {
-            mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
-                                   "extension", name,
-                                   "cannot have 'require' behavior");
-        }
-        else if (behaviorVal == EBhEnable)
-        {
-            mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
-                                   "extension", name,
-                                   "cannot have 'enable' behavior");
-        }
-        else
-        {
-            for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
-                 iter != mExtensionBehavior.end(); ++iter)
-                iter->second = behaviorVal;
-        }
-        return;
-    }
+	if (name == kExtAll)
+	{
+		if (behaviorVal == EBhRequire)
+		{
+			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+			                       "extension", name,
+			                       "cannot have 'require' behavior");
+		}
+		else if (behaviorVal == EBhEnable)
+		{
+			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+			                       "extension", name,
+			                       "cannot have 'enable' behavior");
+		}
+		else
+		{
+			for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
+				 iter != mExtensionBehavior.end(); ++iter)
+				iter->second = behaviorVal;
+		}
+		return;
+	}
 
-    TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
-    if (iter != mExtensionBehavior.end())
-    {
-        iter->second = behaviorVal;
-        return;
-    }
+	TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
+	if (iter != mExtensionBehavior.end())
+	{
+		iter->second = behaviorVal;
+		return;
+	}
 
-    pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
-    switch (behaviorVal) {
-      case EBhRequire:
-        severity = pp::Diagnostics::PP_ERROR;
-        break;
-      case EBhEnable:
-      case EBhWarn:
-      case EBhDisable:
-        severity = pp::Diagnostics::PP_WARNING;
-        break;
-      default:
-        UNREACHABLE(behaviorVal);
-        break;
-    }
-    mDiagnostics.writeInfo(severity, loc,
-                           "extension", name, "is not supported");
+	pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
+	switch (behaviorVal) {
+	case EBhRequire:
+		severity = pp::Diagnostics::PP_ERROR;
+		break;
+	case EBhEnable:
+	case EBhWarn:
+	case EBhDisable:
+		severity = pp::Diagnostics::PP_WARNING;
+		break;
+	default:
+		UNREACHABLE(behaviorVal);
+		break;
+	}
+	mDiagnostics.writeInfo(severity, loc,
+	                       "extension", name, "is not supported");
 }
 
 void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
                                       int version)
 {
-    if (version == 100 ||
-        version == 300)
-    {
-        mShaderVersion = version;
-    }
-    else
-    {
-        std::stringstream stream;
-        stream << version;
-        std::string str = stream.str();
-        mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
-                               "version number", str, "not supported");
-    }
+	if (version == 100 ||
+	    version == 300)
+	{
+		mShaderVersion = version;
+	}
+	else
+	{
+		std::stringstream stream;
+		stream << version;
+		std::string str = stream.str();
+		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+		                       "version number", str, "not supported");
+	}
 }
diff --git a/src/OpenGL/compiler/DirectiveHandler.h b/src/OpenGL/compiler/DirectiveHandler.h
index 48b3c04..f77d1f9 100644
--- a/src/OpenGL/compiler/DirectiveHandler.h
+++ b/src/OpenGL/compiler/DirectiveHandler.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef COMPILER_DIRECTIVE_HANDLER_H_
 #define COMPILER_DIRECTIVE_HANDLER_H_
@@ -16,33 +24,33 @@
 class TDirectiveHandler : public pp::DirectiveHandler
 {
 public:
-    TDirectiveHandler(TExtensionBehavior& extBehavior,
-                      TDiagnostics& diagnostics,
-                      int& shaderVersion);
-    virtual ~TDirectiveHandler();
+	TDirectiveHandler(TExtensionBehavior& extBehavior,
+	                  TDiagnostics& diagnostics,
+	                  int& shaderVersion);
+	virtual ~TDirectiveHandler();
 
-    const TPragma& pragma() const { return mPragma; }
-    const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; }
+	const TPragma& pragma() const { return mPragma; }
+	const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; }
 
-    virtual void handleError(const pp::SourceLocation& loc,
-                             const std::string& msg);
+	virtual void handleError(const pp::SourceLocation& loc,
+	                         const std::string& msg);
 
-    virtual void handlePragma(const pp::SourceLocation& loc,
-                              const std::string& name,
-                              const std::string& value);
+	virtual void handlePragma(const pp::SourceLocation& loc,
+	                          const std::string& name,
+	                          const std::string& value);
 
-    virtual void handleExtension(const pp::SourceLocation& loc,
-                                 const std::string& name,
-                                 const std::string& behavior);
+	virtual void handleExtension(const pp::SourceLocation& loc,
+	                             const std::string& name,
+	                             const std::string& behavior);
 
-    virtual void handleVersion(const pp::SourceLocation& loc,
-                               int version);
+	virtual void handleVersion(const pp::SourceLocation& loc,
+	                           int version);
 
 private:
-    TPragma mPragma;
-    TExtensionBehavior& mExtensionBehavior;
-    TDiagnostics& mDiagnostics;
-    int& mShaderVersion;
+	TPragma mPragma;
+	TExtensionBehavior& mExtensionBehavior;
+	TDiagnostics& mDiagnostics;
+	int& mShaderVersion;
 };
 
 #endif  // COMPILER_DIRECTIVE_HANDLER_H_
diff --git a/src/OpenGL/compiler/ExtensionBehavior.h b/src/OpenGL/compiler/ExtensionBehavior.h
index 1318dd3..eb035e5 100644
--- a/src/OpenGL/compiler/ExtensionBehavior.h
+++ b/src/OpenGL/compiler/ExtensionBehavior.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _EXTENSION_BEHAVIOR_INCLUDED_
 #define _EXTENSION_BEHAVIOR_INCLUDED_
@@ -12,23 +20,23 @@
 
 typedef enum
 {
-    EBhRequire,
-    EBhEnable,
-    EBhWarn,
-    EBhDisable,
-    EBhUndefined
+	EBhRequire,
+	EBhEnable,
+	EBhWarn,
+	EBhDisable,
+	EBhUndefined
 } TBehavior;
 
 inline const char *getBehaviorString(TBehavior b)
 {
-    switch(b)
-    {
-      case EBhRequire: return "require";
-      case EBhEnable:  return "enable";
-      case EBhWarn:    return "warn";
-      case EBhDisable: return "disable";
-      default: return NULL;
-    }
+	switch(b)
+	{
+	case EBhRequire: return "require";
+	case EBhEnable:  return "enable";
+	case EBhWarn:    return "warn";
+	case EBhDisable: return "disable";
+	default:         return nullptr;
+	}
 }
 
 // Mapping between extension name and behavior.
diff --git a/src/OpenGL/compiler/InfoSink.cpp b/src/OpenGL/compiler/InfoSink.cpp
index 53efd17..d059d05 100644
--- a/src/OpenGL/compiler/InfoSink.cpp
+++ b/src/OpenGL/compiler/InfoSink.cpp
@@ -1,58 +1,66 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "InfoSink.h"
 
 void TInfoSinkBase::prefix(TPrefixType message) {
-    switch(message) {
-        case EPrefixNone:
-            break;
-        case EPrefixWarning:
-            sink.append("WARNING: ");
-            break;
-        case EPrefixError:
-            sink.append("ERROR: ");
-            break;
-        case EPrefixInternalError:
-            sink.append("INTERNAL ERROR: ");
-            break;
-        case EPrefixUnimplemented:
-            sink.append("UNIMPLEMENTED: ");
-            break;
-        case EPrefixNote:
-            sink.append("NOTE: ");
-            break;
-        default:
-            sink.append("UNKOWN ERROR: ");
-            break;
-    }
+	switch(message) {
+		case EPrefixNone:
+			break;
+		case EPrefixWarning:
+			sink.append("WARNING: ");
+			break;
+		case EPrefixError:
+			sink.append("ERROR: ");
+			break;
+		case EPrefixInternalError:
+			sink.append("INTERNAL ERROR: ");
+			break;
+		case EPrefixUnimplemented:
+			sink.append("UNIMPLEMENTED: ");
+			break;
+		case EPrefixNote:
+			sink.append("NOTE: ");
+			break;
+		default:
+			sink.append("UNKOWN ERROR: ");
+			break;
+	}
 }
 
 void TInfoSinkBase::location(const TSourceLoc& loc) {
-    int string = loc.first_file, line = loc.first_line;
+	int string = loc.first_file, line = loc.first_line;
 
-    TPersistStringStream stream;
-    if (line)
-        stream << string << ":" << line;
-    else
-        stream << string << ":? ";
-    stream << ": ";
+	TPersistStringStream stream;
+	if (line)
+		stream << string << ":" << line;
+	else
+		stream << string << ":? ";
+	stream << ": ";
 
-    sink.append(stream.str());
+	sink.append(stream.str());
 }
 
 void TInfoSinkBase::message(TPrefixType message, const char* s) {
-    prefix(message);
-    sink.append(s);
-    sink.append("\n");
+	prefix(message);
+	sink.append(s);
+	sink.append("\n");
 }
 
 void TInfoSinkBase::message(TPrefixType message, const char* s, TSourceLoc loc) {
-    prefix(message);
-    location(loc);
-    sink.append(s);
-    sink.append("\n");
+	prefix(message);
+	location(loc);
+	sink.append(s);
+	sink.append("\n");
 }
diff --git a/src/OpenGL/compiler/InfoSink.h b/src/OpenGL/compiler/InfoSink.h
index 160ba2e..711e4e4 100644
--- a/src/OpenGL/compiler/InfoSink.h
+++ b/src/OpenGL/compiler/InfoSink.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _INFOSINK_INCLUDED_
 #define _INFOSINK_INCLUDED_
@@ -21,12 +29,12 @@
 // See below.
 //
 enum TPrefixType {
-    EPrefixNone,
-    EPrefixWarning,
-    EPrefixError,
-    EPrefixInternalError,
-    EPrefixUnimplemented,
-    EPrefixNote
+	EPrefixNone,
+	EPrefixWarning,
+	EPrefixError,
+	EPrefixInternalError,
+	EPrefixUnimplemented,
+	EPrefixNote
 };
 
 //
@@ -37,79 +45,79 @@
 //
 class TInfoSinkBase {
 public:
-    TInfoSinkBase() {}
+	TInfoSinkBase() {}
 
-    template <typename T>
-    TInfoSinkBase& operator<<(const T& t) {
-        TPersistStringStream stream;
-        stream << t;
-        sink.append(stream.str());
-        return *this;
-    }
-    // Override << operator for specific types. It is faster to append strings
-    // and characters directly to the sink.
-    TInfoSinkBase& operator<<(char c) {
-        sink.append(1, c);
-        return *this;
-    }
-    TInfoSinkBase& operator<<(const char* str) {
-        sink.append(str);
-        return *this;
-    }
-    TInfoSinkBase& operator<<(const TPersistString& str) {
-        sink.append(str);
-        return *this;
-    }
-    TInfoSinkBase& operator<<(const TString& str) {
-        sink.append(str.c_str());
-        return *this;
-    }
-    // Make sure floats are written with correct precision.
-    TInfoSinkBase& operator<<(float f) {
-        // Make sure that at least one decimal point is written. If a number
-        // does not have a fractional part, the default precision format does
-        // not write the decimal portion which gets interpreted as integer by
-        // the compiler.
-        TPersistStringStream stream;
-        if (fractionalPart(f) == 0.0f) {
-            stream.precision(1);
-            stream << std::showpoint << std::fixed << f;
-        } else {
-            stream.unsetf(std::ios::fixed);
-            stream.unsetf(std::ios::scientific);
-            stream.precision(8);
-            stream << f;
-        }
-        sink.append(stream.str());
-        return *this;
-    }
-    // Write boolean values as their names instead of integral value.
-    TInfoSinkBase& operator<<(bool b) {
-        const char* str = b ? "true" : "false";
-        sink.append(str);
-        return *this;
-    }
+	template <typename T>
+	TInfoSinkBase& operator<<(const T& t) {
+		TPersistStringStream stream;
+		stream << t;
+		sink.append(stream.str());
+		return *this;
+	}
+	// Override << operator for specific types. It is faster to append strings
+	// and characters directly to the sink.
+	TInfoSinkBase& operator<<(char c) {
+		sink.append(1, c);
+		return *this;
+	}
+	TInfoSinkBase& operator<<(const char* str) {
+		sink.append(str);
+		return *this;
+	}
+	TInfoSinkBase& operator<<(const TPersistString& str) {
+		sink.append(str);
+		return *this;
+	}
+	TInfoSinkBase& operator<<(const TString& str) {
+		sink.append(str.c_str());
+		return *this;
+	}
+	// Make sure floats are written with correct precision.
+	TInfoSinkBase& operator<<(float f) {
+		// Make sure that at least one decimal point is written. If a number
+		// does not have a fractional part, the default precision format does
+		// not write the decimal portion which gets interpreted as integer by
+		// the compiler.
+		TPersistStringStream stream;
+		if (fractionalPart(f) == 0.0f) {
+			stream.precision(1);
+			stream << std::showpoint << std::fixed << f;
+		} else {
+			stream.unsetf(std::ios::fixed);
+			stream.unsetf(std::ios::scientific);
+			stream.precision(8);
+			stream << f;
+		}
+		sink.append(stream.str());
+		return *this;
+	}
+	// Write boolean values as their names instead of integral value.
+	TInfoSinkBase& operator<<(bool b) {
+		const char* str = b ? "true" : "false";
+		sink.append(str);
+		return *this;
+	}
 
-    void erase() { sink.clear(); }
-    int size() { return static_cast<int>(sink.size()); }
+	void erase() { sink.clear(); }
+	int size() { return static_cast<int>(sink.size()); }
 
-    const TPersistString& str() const { return sink; }
-    const char* c_str() const { return sink.c_str(); }
+	const TPersistString& str() const { return sink; }
+	const char* c_str() const { return sink.c_str(); }
 
-    void prefix(TPrefixType message);
-    void location(const TSourceLoc& loc);
-    void message(TPrefixType message, const char* s);
-    void message(TPrefixType message, const char* s, TSourceLoc loc);
+	void prefix(TPrefixType message);
+	void location(const TSourceLoc& loc);
+	void message(TPrefixType message, const char* s);
+	void message(TPrefixType message, const char* s, TSourceLoc loc);
 
 private:
-    TPersistString sink;
+	TPersistString sink;
 };
 
 class TInfoSink {
 public:
-    TInfoSinkBase info;
-    TInfoSinkBase debug;
-    TInfoSinkBase obj;
+	TInfoSinkBase info;
+	TInfoSinkBase debug;
+	TInfoSinkBase obj;
 };
 
 #endif // _INFOSINK_INCLUDED_
diff --git a/src/OpenGL/compiler/Initialize.cpp b/src/OpenGL/compiler/Initialize.cpp
index 2fc517f..1948a57 100644
--- a/src/OpenGL/compiler/Initialize.cpp
+++ b/src/OpenGL/compiler/Initialize.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 //
 // Create strings that declare built-in definitions, add built-ins that
@@ -22,83 +30,83 @@
 	TType *float4 = new TType(EbtFloat, 4);
 	TType *genType = new TType(EbtGenType);
 
-    TType *int1 = new TType(EbtInt);
+	TType *int1 = new TType(EbtInt);
 	TType *int2 = new TType(EbtInt, 2);
 	TType *int3 = new TType(EbtInt, 3);
-    TType *uint1 = new TType(EbtUInt);
-    TType *genIType = new TType(EbtGenIType);
-    TType *genUType = new TType(EbtGenUType);
-    TType *genBType = new TType(EbtGenBType);
+	TType *uint1 = new TType(EbtUInt);
+	TType *genIType = new TType(EbtGenIType);
+	TType *genUType = new TType(EbtGenUType);
+	TType *genBType = new TType(EbtGenBType);
 
-    //
-    // Angle and Trigonometric Functions.
-    //
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRadians, genType, "radians", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDegrees, genType, "degrees", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSin, genType, "sin", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCos, genType, "cos", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpTan, genType, "tan", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAsin, genType, "asin", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAcos, genType, "acos", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSinh, genType, "sinh", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpCosh, genType, "cosh", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTanh, genType, "tanh", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAsinh, genType, "asinh", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAcosh, genType, "acosh", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAtanh, genType, "atanh", genType);
+	//
+	// Angle and Trigonometric Functions.
+	//
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRadians, genType, "radians", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDegrees, genType, "degrees", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSin, genType, "sin", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCos, genType, "cos", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpTan, genType, "tan", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAsin, genType, "asin", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAcos, genType, "acos", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSinh, genType, "sinh", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpCosh, genType, "cosh", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTanh, genType, "tanh", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAsinh, genType, "asinh", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAcosh, genType, "acosh", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAtanh, genType, "atanh", genType);
 
-    //
-    // Exponential Functions.
-    //
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpPow, genType, "pow", genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp, genType, "exp", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog, genType, "log", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp2, genType, "exp2", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog2, genType, "log2", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSqrt, genType, "sqrt", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpInverseSqrt, genType, "inversesqrt", genType);
+	//
+	// Exponential Functions.
+	//
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpPow, genType, "pow", genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp, genType, "exp", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog, genType, "log", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp2, genType, "exp2", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog2, genType, "log2", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSqrt, genType, "sqrt", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpInverseSqrt, genType, "inversesqrt", genType);
 
-    //
-    // Common Functions.
-    //
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAbs, genType, "abs", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAbs, genIType, "abs", genIType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSign, genType, "sign", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSign, genIType, "sign", genIType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFloor, genType, "floor", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTrunc, genType, "trunc", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRound, genType, "round", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRoundEven, genType, "roundEven", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCeil, genType, "ceil", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFract, genType, "fract", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, float1);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, float1);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, genIType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, genUType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, uint1);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, float1);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, genIType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, genUType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, uint1);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, float1, float1);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, genType, genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, int1, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, genIType, genIType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, uint1, uint1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, genUType, genUType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, float1);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", float1, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", float1, float1, genType);
+	//
+	// Common Functions.
+	//
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAbs, genType, "abs", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAbs, genIType, "abs", genIType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSign, genType, "sign", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSign, genIType, "sign", genIType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFloor, genType, "floor", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTrunc, genType, "trunc", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRound, genType, "round", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRoundEven, genType, "roundEven", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCeil, genType, "ceil", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFract, genType, "fract", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, float1);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, float1);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, genIType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, int1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, genUType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, uint1);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, float1);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, genIType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, int1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, genUType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, uint1);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, float1, float1);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, genType, genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, int1, int1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, genIType, genIType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, uint1, uint1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, genUType, genUType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, float1);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", float1, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", float1, float1, genType);
 
 	TType *outFloat1 = new TType(EbtFloat, EbpUndefined, EvqOut);
 	TType *outFloat2 = new TType(EbtFloat, EbpUndefined, EvqOut, 2);
@@ -110,31 +118,31 @@
 	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float3, "modf", float3, outFloat3);
 	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float4, "modf", float4, outFloat4);
 
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsNan, genBType, "isnan", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsInf, genBType, "isinf", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, "floatBitsToInt", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, "floatBitsToUint", genType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, "intBitsToFloat", genIType);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, "uintBitsToFloat", genUType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsNan, genBType, "isnan", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsInf, genBType, "isinf", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, "floatBitsToInt", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, "floatBitsToUint", genType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, "intBitsToFloat", genIType);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, "uintBitsToFloat", genUType);
 
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, "packSnorm2x16", float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, "packUnorm2x16", float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, "packHalf2x16", float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, "unpackSnorm2x16", uint1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, "unpackUnorm2x16", uint1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, "unpackHalf2x16", uint1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, "packSnorm2x16", float2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, "packUnorm2x16", float2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, "packHalf2x16", float2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, "unpackSnorm2x16", uint1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, "unpackUnorm2x16", uint1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, "unpackHalf2x16", uint1);
 
-    //
-    // Geometric Functions.
-    //
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLength, float1, "length", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDistance, float1, "distance", genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDot, float1, "dot", genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCross, float3, "cross", float3, float3);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpNormalize, genType, "normalize", genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFaceForward, genType, "faceforward", genType, genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpReflect, genType, "reflect", genType, genType);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRefract, genType, "refract", genType, genType, float1);
+	//
+	// Geometric Functions.
+	//
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLength, float1, "length", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDistance, float1, "distance", genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDot, float1, "dot", genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCross, float3, "cross", float3, float3);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpNormalize, genType, "normalize", genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFaceForward, genType, "faceforward", genType, genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpReflect, genType, "reflect", genType, genType);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRefract, genType, "refract", genType, genType, float1);
 
 	TType *mat2 = new TType(EbtFloat, 2, 2);
 	TType *mat2x3 = new TType(EbtFloat, 2, 3);
@@ -146,46 +154,46 @@
 	TType *mat4x3 = new TType(EbtFloat, 4, 3);
 	TType *mat4 = new TType(EbtFloat, 4, 4);
 
-    //
-    // Matrix Functions.
-    //
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat2, "matrixCompMult", mat2, mat2);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat3, "matrixCompMult", mat3, mat3);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat4, "matrixCompMult", mat4, mat4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x3, "matrixCompMult", mat2x3, mat2x3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x2, "matrixCompMult", mat3x2, mat3x2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x4, "matrixCompMult", mat2x4, mat2x4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x2, "matrixCompMult", mat4x2, mat4x2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x4, "matrixCompMult", mat3x4, mat3x4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x3, "matrixCompMult", mat4x3, mat4x3);
+	//
+	// Matrix Functions.
+	//
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat2, "matrixCompMult", mat2, mat2);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat3, "matrixCompMult", mat3, mat3);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat4, "matrixCompMult", mat4, mat4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x3, "matrixCompMult", mat2x3, mat2x3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x2, "matrixCompMult", mat3x2, mat3x2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x4, "matrixCompMult", mat2x4, mat2x4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x2, "matrixCompMult", mat4x2, mat4x2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x4, "matrixCompMult", mat3x4, mat3x4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x3, "matrixCompMult", mat4x3, mat4x3);
 
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2, "outerProduct", float2, float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3, "outerProduct", float3, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4, "outerProduct", float4, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, "outerProduct", float3, float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, "outerProduct", float2, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, "outerProduct", float4, float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, "outerProduct", float2, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, "outerProduct", float4, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, "outerProduct", float3, float4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2, "outerProduct", float2, float2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3, "outerProduct", float3, float3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4, "outerProduct", float4, float4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, "outerProduct", float3, float2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, "outerProduct", float2, float3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, "outerProduct", float4, float2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, "outerProduct", float2, float4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, "outerProduct", float4, float3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, "outerProduct", float3, float4);
 
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2, "transpose", mat2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3, "transpose", mat3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4, "transpose", mat4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x3, "transpose", mat3x2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x2, "transpose", mat2x3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x4, "transpose", mat4x2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x2, "transpose", mat2x4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x4, "transpose", mat4x3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x3, "transpose", mat3x4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2, "transpose", mat2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3, "transpose", mat3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4, "transpose", mat4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x3, "transpose", mat3x2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x2, "transpose", mat2x3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x4, "transpose", mat4x2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x2, "transpose", mat2x4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x4, "transpose", mat4x3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x3, "transpose", mat3x4);
 
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat4);
 
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat2, "inverse", mat2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat3, "inverse", mat3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat4, "inverse", mat4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat2, "inverse", mat2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat3, "inverse", mat3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat4, "inverse", mat4);
 
 
 	TType *bool1 = new TType(EbtBool);
@@ -194,62 +202,62 @@
 	TType *uvec = new TType(EbtUVec);
 	TType *bvec = new TType(EbtBVec);
 
-    //
-    // Vector relational functions.
-    //
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", vec, vec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", ivec, ivec);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThan, bvec, "lessThan", uvec, uvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", vec, vec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", ivec, ivec);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", uvec, uvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", vec, vec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", ivec, ivec);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThan, bvec, "greaterThan", uvec, uvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", vec, vec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", ivec, ivec);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", uvec, uvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", vec, vec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", ivec, ivec);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorEqual, bvec, "equal", uvec, uvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", bvec, bvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", vec, vec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", ivec, ivec);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", uvec, uvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", bvec, bvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAny, bool1, "any", bvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAll, bool1, "all", bvec);
-    symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorLogicalNot, bvec, "not", bvec);
+	//
+	// Vector relational functions.
+	//
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", vec, vec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", ivec, ivec);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThan, bvec, "lessThan", uvec, uvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", vec, vec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", ivec, ivec);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", uvec, uvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", vec, vec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", ivec, ivec);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThan, bvec, "greaterThan", uvec, uvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", vec, vec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", ivec, ivec);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", uvec, uvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", vec, vec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", ivec, ivec);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorEqual, bvec, "equal", uvec, uvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", bvec, bvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", vec, vec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", ivec, ivec);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", uvec, uvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", bvec, bvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAny, bool1, "any", bvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAll, bool1, "all", bvec);
+	symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorLogicalNot, bvec, "not", bvec);
 
 	TType *sampler2D = new TType(EbtSampler2D);
 	TType *samplerCube = new TType(EbtSamplerCube);
 	TType *sampler3D = new TType(EbtSampler3D);
 
-    //
-    // Texture Functions for GLSL ES 1.0
-    //
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
+	//
+	// Texture Functions for GLSL ES 1.0
+	//
+	symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
+	symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
+	symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
+	symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
 	symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture3D", sampler3D, float3);
 
 	if(resources.OES_EGL_image_external)
-    {
-        TType *samplerExternalOES = new TType(EbtSamplerExternalOES);
+	{
+		TType *samplerExternalOES = new TType(EbtSamplerExternalOES);
 
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4);
+		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
+		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3);
+		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4);
 		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture3D", samplerExternalOES, float3);
-    }
+	}
 
 	if(type == GL_FRAGMENT_SHADER)
 	{
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, float1);
+		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1);
+		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1);
+		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, float1);
+		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, float1);
 
 		if(resources.OES_standard_derivatives)
 		{
@@ -268,38 +276,38 @@
 		symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture3DLod", sampler3D, float3, float1);
 	}
 
-    TType *gvec4 = new TType(EbtGVec4);
+	TType *gvec4 = new TType(EbtGVec4);
 
-    TType *gsampler2D = new TType(EbtGSampler2D);
-    TType *gsamplerCube = new TType(EbtGSamplerCube);
-    TType *gsampler3D = new TType(EbtGSampler3D);
-    TType *gsampler2DArray = new TType(EbtGSampler2DArray);
+	TType *gsampler2D = new TType(EbtGSampler2D);
+	TType *gsamplerCube = new TType(EbtGSamplerCube);
+	TType *gsampler3D = new TType(EbtGSampler3D);
+	TType *gsampler2DArray = new TType(EbtGSampler2DArray);
 
-    //
-    // Texture Functions for GLSL ES 3.0
-    //
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
+	//
+	// Texture Functions for GLSL ES 3.0
+	//
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
+	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
 
-    if(type == GL_FRAGMENT_SHADER)
-    {
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
-    }
+	if(type == GL_FRAGMENT_SHADER)
+	{
+		symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
+		symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
+		symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1);
+		symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1);
+		symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
+		symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
+		symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
+	}
 
 	TType *sampler2DShadow = new TType(EbtSampler2DShadow);
 	TType *samplerCubeShadow = new TType(EbtSamplerCubeShadow);
@@ -406,9 +414,9 @@
 	symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3, float3, int3);
 	symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2, float2, int2);
 
-    //
-    // Depth range in window coordinates
-    //
+	//
+	// Depth range in window coordinates
+	//
 	TFieldList *fields = NewPoolTFieldList();
 	TSourceLoc zeroSourceLoc = { 0, 0, 0, 0 };
 	TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), zeroSourceLoc);
@@ -424,73 +432,73 @@
 	depthRange->setQualifier(EvqUniform);
 	symbolTable.insert(COMMON_BUILTINS, *depthRange);
 
-    //
-    // Implementation dependent built-in constants.
-    //
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", resources.MaxTextureImageUnits);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors);
-    symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors);
-    symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers);
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors);
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", resources.MaxFragmentInputVectors);
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", resources.MinProgramTexelOffset);
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", resources.MaxProgramTexelOffset);
+	//
+	// Implementation dependent built-in constants.
+	//
+	symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs);
+	symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors);
+	symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits);
+	symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits);
+	symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", resources.MaxTextureImageUnits);
+	symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors);
+	symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors);
+	symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers);
+	symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors);
+	symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", resources.MaxFragmentInputVectors);
+	symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", resources.MinProgramTexelOffset);
+	symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", resources.MaxProgramTexelOffset);
 }
 
 void IdentifyBuiltIns(GLenum shaderType,
                       const ShBuiltInResources &resources,
                       TSymbolTable &symbolTable)
 {
-    //
-    // First, insert some special built-in variables that are not in
-    // the built-in header files.
-    //
-    switch(shaderType)
+	//
+	// First, insert some special built-in variables that are not in
+	// the built-in header files.
+	//
+	switch(shaderType)
 	{
-    case GL_FRAGMENT_SHADER:
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
-        symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
-        symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
-        symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
-        break;
-    case GL_VERTEX_SHADER:
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition,    4)));
-        symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
-        symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
-        break;
-    default: assert(false && "Language not supported");
-    }
+	case GL_FRAGMENT_SHADER:
+		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
+		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
+		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
+		symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
+		symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
+		symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
+		break;
+	case GL_VERTEX_SHADER:
+		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition,    4)));
+		symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
+		symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
+		break;
+	default: assert(false && "Language not supported");
+	}
 
-    // Finally add resource-specific variables.
-    switch(shaderType)
-    {
-    case GL_FRAGMENT_SHADER:
+	// Finally add resource-specific variables.
+	switch(shaderType)
+	{
+	case GL_FRAGMENT_SHADER:
 		{
-            // Set up gl_FragData.  The array size.
-            TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
-            fragData.setArraySize(resources.MaxDrawBuffers);
-            symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData"), fragData));
+			// Set up gl_FragData.  The array size.
+			TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
+			fragData.setArraySize(resources.MaxDrawBuffers);
+			symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData"), fragData));
 		}
 		break;
-    default: break;
-    }
+	default: break;
+	}
 }
 
 void InitExtensionBehavior(const ShBuiltInResources& resources,
                            TExtensionBehavior& extBehavior)
 {
-    if(resources.OES_standard_derivatives)
-        extBehavior["GL_OES_standard_derivatives"] = EBhUndefined;
+	if(resources.OES_standard_derivatives)
+		extBehavior["GL_OES_standard_derivatives"] = EBhUndefined;
 	if(resources.OES_fragment_precision_high)
-        extBehavior["GL_FRAGMENT_PRECISION_HIGH"] = EBhUndefined;
-    if(resources.OES_EGL_image_external)
-        extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
+		extBehavior["GL_FRAGMENT_PRECISION_HIGH"] = EBhUndefined;
+	if(resources.OES_EGL_image_external)
+		extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
 	if(resources.EXT_draw_buffers)
-        extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
+		extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
 }
diff --git a/src/OpenGL/compiler/Initialize.h b/src/OpenGL/compiler/Initialize.h
index e96aa69..e5fcbf2 100644
--- a/src/OpenGL/compiler/Initialize.h
+++ b/src/OpenGL/compiler/Initialize.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _INITIALIZE_INCLUDED_
 #define _INITIALIZE_INCLUDED_
diff --git a/src/OpenGL/compiler/InitializeGlobals.h b/src/OpenGL/compiler/InitializeGlobals.h
index 0715941..3ddb048 100644
--- a/src/OpenGL/compiler/InitializeGlobals.h
+++ b/src/OpenGL/compiler/InitializeGlobals.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef __INITIALIZE_GLOBALS_INCLUDED_
 #define __INITIALIZE_GLOBALS_INCLUDED_
diff --git a/src/OpenGL/compiler/InitializeParseContext.cpp b/src/OpenGL/compiler/InitializeParseContext.cpp
index 70116bd..06b72d9 100644
--- a/src/OpenGL/compiler/InitializeParseContext.cpp
+++ b/src/OpenGL/compiler/InitializeParseContext.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "InitializeParseContext.h"
 
@@ -12,29 +20,29 @@
 
 bool InitializeParseContextIndex()
 {
-    assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
+	assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
 
-    GlobalParseContextIndex = OS_AllocTLSIndex();
-    return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
+	GlobalParseContextIndex = OS_AllocTLSIndex();
+	return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
 }
 
 void FreeParseContextIndex()
 {
-    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+	assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
 
-    OS_FreeTLSIndex(GlobalParseContextIndex);
-    GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+	OS_FreeTLSIndex(GlobalParseContextIndex);
+	GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
 }
 
 void SetGlobalParseContext(TParseContext* context)
 {
-    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
-    OS_SetTLSValue(GlobalParseContextIndex, context);
+	assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+	OS_SetTLSValue(GlobalParseContextIndex, context);
 }
 
 TParseContext* GetGlobalParseContext()
 {
-    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
-    return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
+	assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+	return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
 }
 
diff --git a/src/OpenGL/compiler/InitializeParseContext.h b/src/OpenGL/compiler/InitializeParseContext.h
index 79d691f..c55eae2 100644
--- a/src/OpenGL/compiler/InitializeParseContext.h
+++ b/src/OpenGL/compiler/InitializeParseContext.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
 #define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/src/OpenGL/compiler/IntermTraverse.cpp b/src/OpenGL/compiler/IntermTraverse.cpp
index 3ed50e2..09c8e6e 100644
--- a/src/OpenGL/compiler/IntermTraverse.cpp
+++ b/src/OpenGL/compiler/IntermTraverse.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "intermediate.h"
 
@@ -47,7 +55,7 @@
 	{
 		visit = it->visitBinary(PreVisit, this);
 	}
-	
+
 	//
 	// Visit the children, in the right order.
 	//
@@ -55,13 +63,13 @@
 	{
 		it->incrementDepth(this);
 
-		if(it->rightToLeft) 
+		if(it->rightToLeft)
 		{
 			if(right)
 			{
 				right->traverse(it);
 			}
-			
+
 			if(it->inVisit)
 			{
 				visit = it->visitBinary(InVisit, this);
@@ -78,7 +86,7 @@
 			{
 				left->traverse(it);
 			}
-			
+
 			if(it->inVisit)
 			{
 				visit = it->visitBinary(InVisit, this);
@@ -118,7 +126,7 @@
 		operand->traverse(it);
 		it->decrementDepth();
 	}
-	
+
 	if (visit && it->postVisit)
 		it->visitUnary(PostVisit, this);
 }
@@ -129,12 +137,12 @@
 void TIntermAggregate::traverse(TIntermTraverser* it)
 {
 	bool visit = true;
-	
+
 	if(it->preVisit)
 	{
 		visit = it->visitAggregate(PreVisit, this);
 	}
-	
+
 	if(visit)
 	{
 		it->incrementDepth(this);
@@ -169,7 +177,7 @@
 				}
 			}
 		}
-		
+
 		it->decrementDepth();
 	}
 
@@ -188,7 +196,7 @@
 
 	if (it->preVisit)
 		visit = it->visitSelection(PreVisit, this);
-	
+
 	if (visit) {
 		it->incrementDepth(this);
 		if (it->rightToLeft) {
@@ -276,7 +284,7 @@
 	{
 		visit = it->visitLoop(PreVisit, this);
 	}
-	
+
 	if(visit)
 	{
 		it->incrementDepth(this);
@@ -334,7 +342,7 @@
 
 	if (it->preVisit)
 		visit = it->visitBranch(PreVisit, this);
-	
+
 	if (visit && expression) {
 		it->incrementDepth(this);
 		expression->traverse(it);
diff --git a/src/OpenGL/compiler/Intermediate.cpp b/src/OpenGL/compiler/Intermediate.cpp
index ca0e59e..dbbfb19 100644
--- a/src/OpenGL/compiler/Intermediate.cpp
+++ b/src/OpenGL/compiler/Intermediate.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 //
 // Build the intermediate representation.
@@ -19,7 +27,7 @@
 bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);
 
 static TPrecision GetHigherPrecision( TPrecision left, TPrecision right ){
-    return left > right ? left : right;
+	return left > right ? left : right;
 }
 
 static bool ValidateMultiplication(TOperator op, const TType &left, const TType &right)
@@ -55,114 +63,114 @@
 }
 
 const char* getOperatorString(TOperator op) {
-    switch (op) {
-      case EOpInitialize: return "=";
-      case EOpAssign: return "=";
-      case EOpAddAssign: return "+=";
-      case EOpSubAssign: return "-=";
-      case EOpDivAssign: return "/=";
-      case EOpIModAssign: return "%=";
-      case EOpBitShiftLeftAssign: return "<<=";
-      case EOpBitShiftRightAssign: return ">>=";
-      case EOpBitwiseAndAssign: return "&=";
-      case EOpBitwiseXorAssign: return "^=";
-      case EOpBitwiseOrAssign: return "|=";
+	switch (op) {
+	case EOpInitialize: return "=";
+	case EOpAssign: return "=";
+	case EOpAddAssign: return "+=";
+	case EOpSubAssign: return "-=";
+	case EOpDivAssign: return "/=";
+	case EOpIModAssign: return "%=";
+	case EOpBitShiftLeftAssign: return "<<=";
+	case EOpBitShiftRightAssign: return ">>=";
+	case EOpBitwiseAndAssign: return "&=";
+	case EOpBitwiseXorAssign: return "^=";
+	case EOpBitwiseOrAssign: return "|=";
 
-      // Fall-through.
-      case EOpMulAssign:
-      case EOpVectorTimesMatrixAssign:
-      case EOpVectorTimesScalarAssign:
-      case EOpMatrixTimesScalarAssign:
-      case EOpMatrixTimesMatrixAssign: return "*=";
+	// Fall-through.
+	case EOpMulAssign:
+	case EOpVectorTimesMatrixAssign:
+	case EOpVectorTimesScalarAssign:
+	case EOpMatrixTimesScalarAssign:
+	case EOpMatrixTimesMatrixAssign: return "*=";
 
-      // Fall-through.
-      case EOpIndexDirect:
-      case EOpIndexIndirect: return "[]";
+	// Fall-through.
+	case EOpIndexDirect:
+	case EOpIndexIndirect: return "[]";
 
-      case EOpIndexDirectStruct: return ".";
-      case EOpVectorSwizzle: return ".";
-      case EOpAdd: return "+";
-      case EOpSub: return "-";
-      case EOpMul: return "*";
-      case EOpDiv: return "/";
-      case EOpMod: UNIMPLEMENTED(); break;
-      case EOpEqual: return "==";
-      case EOpNotEqual: return "!=";
-      case EOpLessThan: return "<";
-      case EOpGreaterThan: return ">";
-      case EOpLessThanEqual: return "<=";
-      case EOpGreaterThanEqual: return ">=";
+	case EOpIndexDirectStruct: return ".";
+	case EOpVectorSwizzle: return ".";
+	case EOpAdd: return "+";
+	case EOpSub: return "-";
+	case EOpMul: return "*";
+	case EOpDiv: return "/";
+	case EOpMod: UNIMPLEMENTED(); break;
+	case EOpEqual: return "==";
+	case EOpNotEqual: return "!=";
+	case EOpLessThan: return "<";
+	case EOpGreaterThan: return ">";
+	case EOpLessThanEqual: return "<=";
+	case EOpGreaterThanEqual: return ">=";
 
-      // Fall-through.
-      case EOpVectorTimesScalar:
-      case EOpVectorTimesMatrix:
-      case EOpMatrixTimesVector:
-      case EOpMatrixTimesScalar:
-      case EOpMatrixTimesMatrix: return "*";
+	// Fall-through.
+	case EOpVectorTimesScalar:
+	case EOpVectorTimesMatrix:
+	case EOpMatrixTimesVector:
+	case EOpMatrixTimesScalar:
+	case EOpMatrixTimesMatrix: return "*";
 
-      case EOpLogicalOr: return "||";
-      case EOpLogicalXor: return "^^";
-      case EOpLogicalAnd: return "&&";
-      case EOpIMod: return "%";
-      case EOpBitShiftLeft: return "<<";
-      case EOpBitShiftRight: return ">>";
-      case EOpBitwiseAnd: return "&";
-      case EOpBitwiseXor: return "^";
-      case EOpBitwiseOr: return "|";
-      case EOpNegative: return "-";
-      case EOpVectorLogicalNot: return "not";
-      case EOpLogicalNot: return "!";
-      case EOpBitwiseNot: return "~";
-      case EOpPostIncrement: return "++";
-      case EOpPostDecrement: return "--";
-      case EOpPreIncrement: return "++";
-      case EOpPreDecrement: return "--";
+	case EOpLogicalOr: return "||";
+	case EOpLogicalXor: return "^^";
+	case EOpLogicalAnd: return "&&";
+	case EOpIMod: return "%";
+	case EOpBitShiftLeft: return "<<";
+	case EOpBitShiftRight: return ">>";
+	case EOpBitwiseAnd: return "&";
+	case EOpBitwiseXor: return "^";
+	case EOpBitwiseOr: return "|";
+	case EOpNegative: return "-";
+	case EOpVectorLogicalNot: return "not";
+	case EOpLogicalNot: return "!";
+	case EOpBitwiseNot: return "~";
+	case EOpPostIncrement: return "++";
+	case EOpPostDecrement: return "--";
+	case EOpPreIncrement: return "++";
+	case EOpPreDecrement: return "--";
 
-      case EOpRadians: return "radians";
-      case EOpDegrees: return "degrees";
-      case EOpSin: return "sin";
-      case EOpCos: return "cos";
-      case EOpTan: return "tan";
-      case EOpAsin: return "asin";
-      case EOpAcos: return "acos";
-      case EOpAtan: return "atan";
-      case EOpSinh: return "sinh";
-      case EOpCosh: return "cosh";
-      case EOpTanh: return "tanh";
-      case EOpAsinh: return "asinh";
-      case EOpAcosh: return "acosh";
-      case EOpAtanh: return "atanh";
-      case EOpExp: return "exp";
-      case EOpLog: return "log";
-      case EOpExp2: return "exp2";
-      case EOpLog2: return "log2";
-      case EOpSqrt: return "sqrt";
-      case EOpInverseSqrt: return "inversesqrt";
-      case EOpAbs: return "abs";
-      case EOpSign: return "sign";
-      case EOpFloor: return "floor";
-      case EOpTrunc: return "trunc";
-      case EOpRound: return "round";
-      case EOpRoundEven: return "roundEven";
-      case EOpCeil: return "ceil";
-      case EOpFract: return "fract";
-      case EOpLength: return "length";
-      case EOpNormalize: return "normalize";
-      case EOpDFdx: return "dFdx";
-      case EOpDFdy: return "dFdy";
-      case EOpFwidth: return "fwidth";
-      case EOpAny: return "any";
-      case EOpAll: return "all";
-      case EOpIsNan: return "isnan";
-      case EOpIsInf: return "isinf";
-      case EOpOuterProduct: return "outerProduct";
-      case EOpTranspose: return "transpose";
-      case EOpDeterminant: return "determinant";
-      case EOpInverse: return "inverse";
+	case EOpRadians: return "radians";
+	case EOpDegrees: return "degrees";
+	case EOpSin: return "sin";
+	case EOpCos: return "cos";
+	case EOpTan: return "tan";
+	case EOpAsin: return "asin";
+	case EOpAcos: return "acos";
+	case EOpAtan: return "atan";
+	case EOpSinh: return "sinh";
+	case EOpCosh: return "cosh";
+	case EOpTanh: return "tanh";
+	case EOpAsinh: return "asinh";
+	case EOpAcosh: return "acosh";
+	case EOpAtanh: return "atanh";
+	case EOpExp: return "exp";
+	case EOpLog: return "log";
+	case EOpExp2: return "exp2";
+	case EOpLog2: return "log2";
+	case EOpSqrt: return "sqrt";
+	case EOpInverseSqrt: return "inversesqrt";
+	case EOpAbs: return "abs";
+	case EOpSign: return "sign";
+	case EOpFloor: return "floor";
+	case EOpTrunc: return "trunc";
+	case EOpRound: return "round";
+	case EOpRoundEven: return "roundEven";
+	case EOpCeil: return "ceil";
+	case EOpFract: return "fract";
+	case EOpLength: return "length";
+	case EOpNormalize: return "normalize";
+	case EOpDFdx: return "dFdx";
+	case EOpDFdy: return "dFdy";
+	case EOpFwidth: return "fwidth";
+	case EOpAny: return "any";
+	case EOpAll: return "all";
+	case EOpIsNan: return "isnan";
+	case EOpIsInf: return "isinf";
+	case EOpOuterProduct: return "outerProduct";
+	case EOpTranspose: return "transpose";
+	case EOpDeterminant: return "determinant";
+	case EOpInverse: return "inverse";
 
-      default: break;
-    }
-    return "";
+	default: break;
+	}
+	return "";
 }
 
 ////////////////////////////////////////////////////////////////////////////
@@ -180,10 +188,10 @@
 //
 TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TSourceLoc &line)
 {
-    TIntermSymbol* node = new TIntermSymbol(id, name, type);
-    node->setLine(line);
+	TIntermSymbol* node = new TIntermSymbol(id, name, type);
+	node->setLine(line);
 
-    return node;
+	return node;
 }
 
 //
@@ -193,94 +201,94 @@
 //
 TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc &line)
 {
-    bool isBitShift = false;
-    switch (op) {
-        case EOpEqual:
-        case EOpNotEqual:
-            if (left->isArray())
-                return 0;
-            break;
-        case EOpLessThan:
-        case EOpGreaterThan:
-        case EOpLessThanEqual:
-        case EOpGreaterThanEqual:
-            if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
-                return 0;
-            }
-            break;
-        case EOpLogicalOr:
-        case EOpLogicalXor:
-        case EOpLogicalAnd:
-            if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
-                return 0;
-            }
-            break;
-        case EOpBitwiseOr:
-        case EOpBitwiseXor:
-        case EOpBitwiseAnd:
-            if (!IsInteger(left->getBasicType()) || left->isMatrix() || left->isArray()) {
-                return 0;
-            }
-            break;
-        case EOpAdd:
-        case EOpSub:
-        case EOpDiv:
-        case EOpMul:
-            if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) {
-                return 0;
-            }
-            break;
-        case EOpIMod:
-            // Note that this is only for the % operator, not for mod()
-            if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) {
-                return 0;
-            }
-            break;
-		case EOpBitShiftLeft:
-		case EOpBitShiftRight:
-		case EOpBitShiftLeftAssign:
-		case EOpBitShiftRightAssign:
-			// Unsigned can be bit-shifted by signed and vice versa, but we need to
-			// check that the basic type is an integer type.
-			isBitShift = true;
-			if(!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
-			{
-				return 0;
-			}
-			break;
-        default: break;
-    }
+	bool isBitShift = false;
+	switch (op) {
+	case EOpEqual:
+	case EOpNotEqual:
+		if (left->isArray())
+			return 0;
+		break;
+	case EOpLessThan:
+	case EOpGreaterThan:
+	case EOpLessThanEqual:
+	case EOpGreaterThanEqual:
+		if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
+			return 0;
+		}
+		break;
+	case EOpLogicalOr:
+	case EOpLogicalXor:
+	case EOpLogicalAnd:
+		if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
+			return 0;
+		}
+		break;
+	case EOpBitwiseOr:
+	case EOpBitwiseXor:
+	case EOpBitwiseAnd:
+		if (!IsInteger(left->getBasicType()) || left->isMatrix() || left->isArray()) {
+			return 0;
+		}
+		break;
+	case EOpAdd:
+	case EOpSub:
+	case EOpDiv:
+	case EOpMul:
+		if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) {
+			return 0;
+		}
+		break;
+	case EOpIMod:
+		// Note that this is only for the % operator, not for mod()
+		if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) {
+			return 0;
+		}
+		break;
+	case EOpBitShiftLeft:
+	case EOpBitShiftRight:
+	case EOpBitShiftLeftAssign:
+	case EOpBitShiftRightAssign:
+		// Unsigned can be bit-shifted by signed and vice versa, but we need to
+		// check that the basic type is an integer type.
+		isBitShift = true;
+		if(!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
+		{
+			return 0;
+		}
+		break;
+	default: break;
+	}
 
-    if(!isBitShift && left->getBasicType() != right->getBasicType())
-    {
-        return 0;
-    }
+	if(!isBitShift && left->getBasicType() != right->getBasicType())
+	{
+		return 0;
+	}
 
-    //
-    // Need a new node holding things together then.  Make
-    // one and promote it to the right type.
-    //
-    TIntermBinary* node = new TIntermBinary(op);
-    node->setLine(line);
+	//
+	// Need a new node holding things together then.  Make
+	// one and promote it to the right type.
+	//
+	TIntermBinary* node = new TIntermBinary(op);
+	node->setLine(line);
 
-    node->setLeft(left);
-    node->setRight(right);
-    if (!node->promote(infoSink))
-        return 0;
+	node->setLeft(left);
+	node->setRight(right);
+	if (!node->promote(infoSink))
+		return 0;
 
-    //
-    // See if we can fold constants.
-    //
-    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
-    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
-    if (leftTempConstant && rightTempConstant) {
-        TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
+	//
+	// See if we can fold constants.
+	//
+	TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
+	TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
+	if (leftTempConstant && rightTempConstant) {
+		TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
 
-        if (typedReturnNode)
-            return typedReturnNode;
-    }
+		if (typedReturnNode)
+			return typedReturnNode;
+	}
 
-    return node;
+	return node;
 }
 
 //
@@ -290,23 +298,23 @@
 //
 TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc &line)
 {
-    if (left->getType().getStruct() || right->getType().getStruct())
-    {
-        if (left->getType() != right->getType())
-        {
-            return 0;
-        }
-    }
+	if (left->getType().getStruct() || right->getType().getStruct())
+	{
+		if (left->getType() != right->getType())
+		{
+			return 0;
+		}
+	}
 
-    TIntermBinary* node = new TIntermBinary(op);
-    node->setLine(line);
+	TIntermBinary* node = new TIntermBinary(op);
+	node->setLine(line);
 
-    node->setLeft(left);
-    node->setRight(right);
-    if (! node->promote(infoSink))
-        return 0;
+	node->setLeft(left);
+	node->setRight(right);
+	if (! node->promote(infoSink))
+		return 0;
 
-    return node;
+	return node;
 }
 
 //
@@ -318,14 +326,14 @@
 //
 TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc &line)
 {
-    TIntermBinary* node = new TIntermBinary(op);
-    node->setLine(line);
-    node->setLeft(base);
-    node->setRight(index);
+	TIntermBinary* node = new TIntermBinary(op);
+	node->setLine(line);
+	node->setLeft(base);
+	node->setRight(index);
 
-    // caller should set the type
+	// caller should set the type
 
-    return node;
+	return node;
 }
 
 //
@@ -335,56 +343,56 @@
 //
 TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, const TSourceLoc &line, const TType *funcReturnType)
 {
-    if (child == 0) {
-        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
-        return 0;
-    }
+	if (child == 0) {
+		infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
+		return 0;
+	}
 
-    switch (op) {
-        case EOpBitwiseNot:
-            if (!IsInteger(child->getType().getBasicType()) || child->getType().isMatrix() || child->getType().isArray()) {
-                return 0;
-            }
-            break;
+	switch (op) {
+	case EOpBitwiseNot:
+		if (!IsInteger(child->getType().getBasicType()) || child->getType().isMatrix() || child->getType().isArray()) {
+			return 0;
+		}
+		break;
 
-        case EOpLogicalNot:
-            if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
-                return 0;
-            }
-            break;
+	case EOpLogicalNot:
+		if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
+			return 0;
+		}
+		break;
 
-        case EOpPostIncrement:
-        case EOpPreIncrement:
-        case EOpPostDecrement:
-        case EOpPreDecrement:
-        case EOpNegative:
-            if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
-                return 0;
-        default: break;
-    }
+	case EOpPostIncrement:
+	case EOpPreIncrement:
+	case EOpPostDecrement:
+	case EOpPreDecrement:
+	case EOpNegative:
+		if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
+			return 0;
+	default: break;
+	}
 
-    TIntermConstantUnion *childTempConstant = 0;
-    if (child->getAsConstantUnion())
-        childTempConstant = child->getAsConstantUnion();
+	TIntermConstantUnion *childTempConstant = 0;
+	if (child->getAsConstantUnion())
+		childTempConstant = child->getAsConstantUnion();
 
-    //
-    // Make a new node for the operator.
-    //
-    TIntermUnary *node = new TIntermUnary(op);
-    node->setLine(line);
-    node->setOperand(child);
+	//
+	// Make a new node for the operator.
+	//
+	TIntermUnary *node = new TIntermUnary(op);
+	node->setLine(line);
+	node->setOperand(child);
 
-    if (! node->promote(infoSink, funcReturnType))
-        return 0;
+	if (! node->promote(infoSink, funcReturnType))
+		return 0;
 
-    if (childTempConstant)  {
-        TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);
+	if (childTempConstant)  {
+		TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);
 
-        if (newChild)
-            return newChild;
-    }
+		if (newChild)
+			return newChild;
+	}
 
-    return node;
+	return node;
 }
 
 //
@@ -399,29 +407,29 @@
 //
 TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TSourceLoc &line)
 {
-    TIntermAggregate* aggNode;
+	TIntermAggregate* aggNode;
 
-    //
-    // Make sure we have an aggregate.  If not turn it into one.
-    //
-    if (node) {
-        aggNode = node->getAsAggregate();
-        if (aggNode == 0 || aggNode->getOp() != EOpNull) {
-            //
-            // Make an aggregate containing this node.
-            //
-            aggNode = new TIntermAggregate();
-            aggNode->getSequence().push_back(node);
-        }
-    } else
-        aggNode = new TIntermAggregate();
+	//
+	// Make sure we have an aggregate.  If not turn it into one.
+	//
+	if (node) {
+		aggNode = node->getAsAggregate();
+		if (aggNode == 0 || aggNode->getOp() != EOpNull) {
+			//
+			// Make an aggregate containing this node.
+			//
+			aggNode = new TIntermAggregate();
+			aggNode->getSequence().push_back(node);
+		}
+	} else
+		aggNode = new TIntermAggregate();
 
-    //
-    // Set the operator.
-    //
-    aggNode->setOp(op);
+	//
+	// Set the operator.
+	//
+	aggNode->setOp(op);
 
-    return aggNode;
+	return aggNode;
 }
 
 //
@@ -433,24 +441,24 @@
 //
 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc &line)
 {
-    if (left == 0 && right == 0)
-        return 0;
+	if (left == 0 && right == 0)
+		return 0;
 
-    TIntermAggregate* aggNode = 0;
-    if (left)
-        aggNode = left->getAsAggregate();
-    if (!aggNode || aggNode->getOp() != EOpNull) {
-        aggNode = new TIntermAggregate;
-        if (left)
-            aggNode->getSequence().push_back(left);
-    }
+	TIntermAggregate* aggNode = 0;
+	if (left)
+		aggNode = left->getAsAggregate();
+	if (!aggNode || aggNode->getOp() != EOpNull) {
+		aggNode = new TIntermAggregate;
+		if (left)
+			aggNode->getSequence().push_back(left);
+	}
 
-    if (right)
-        aggNode->getSequence().push_back(right);
+	if (right)
+		aggNode->getSequence().push_back(right);
 
-    aggNode->setLine(line);
+	aggNode->setLine(line);
 
-    return aggNode;
+	return aggNode;
 }
 
 //
@@ -460,15 +468,15 @@
 //
 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc &line)
 {
-    if (node == 0)
-        return 0;
+	if (node == 0)
+		return 0;
 
-    TIntermAggregate* aggNode = new TIntermAggregate;
-    aggNode->getSequence().push_back(node);
+	TIntermAggregate* aggNode = new TIntermAggregate;
+	aggNode->getSequence().push_back(node);
 
-    aggNode->setLine(line);
+	aggNode->setLine(line);
 
-    return aggNode;
+	return aggNode;
 }
 
 //
@@ -480,36 +488,36 @@
 //
 TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc &line)
 {
-    //
-    // For compile time constant selections, prune the code and
-    // test now.
-    //
+	//
+	// For compile time constant selections, prune the code and
+	// test now.
+	//
 
-    if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
-        if (cond->getAsConstantUnion()->getBConst(0) == true)
-            return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
-        else
-            return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
-    }
+	if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
+		if (cond->getAsConstantUnion()->getBConst(0) == true)
+			return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : nullptr;
+		else
+			return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : nullptr;
+	}
 
-    TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
-    node->setLine(line);
+	TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
+	node->setLine(line);
 
-    return node;
+	return node;
 }
 
 
 TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc &line)
 {
-    if (left->getType().getQualifier() == EvqConstExpr && right->getType().getQualifier() == EvqConstExpr) {
-        return right;
-    } else {
-        TIntermTyped *commaAggregate = growAggregate(left, right, line);
-        commaAggregate->getAsAggregate()->setOp(EOpComma);
-        commaAggregate->setType(right->getType());
-        commaAggregate->getTypePointer()->setQualifier(EvqTemporary);
-        return commaAggregate;
-    }
+	if (left->getType().getQualifier() == EvqConstExpr && right->getType().getQualifier() == EvqConstExpr) {
+		return right;
+	} else {
+		TIntermTyped *commaAggregate = growAggregate(left, right, line);
+		commaAggregate->getAsAggregate()->setOp(EOpComma);
+		commaAggregate->setType(right->getType());
+		commaAggregate->getTypePointer()->setQualifier(EvqTemporary);
+		return commaAggregate;
+	}
 }
 
 //
@@ -521,30 +529,30 @@
 //
 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc &line)
 {
-    if (trueBlock->getType() != falseBlock->getType())
-    {
-        return 0;
-    }
+	if (trueBlock->getType() != falseBlock->getType())
+	{
+		return 0;
+	}
 
-    //
-    // See if all the operands are constant, then fold it otherwise not.
-    //
+	//
+	// See if all the operands are constant, then fold it otherwise not.
+	//
 
-    if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
-        if (cond->getAsConstantUnion()->getBConst(0))
-            return trueBlock;
-        else
-            return falseBlock;
-    }
+	if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
+		if (cond->getAsConstantUnion()->getBConst(0))
+			return trueBlock;
+		else
+			return falseBlock;
+	}
 
-    //
-    // Make a selection node.
-    //
-    TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
-    node->getTypePointer()->setQualifier(EvqTemporary);
-    node->setLine(line);
+	//
+	// Make a selection node.
+	//
+	TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
+	node->getTypePointer()->setQualifier(EvqTemporary);
+	node->setLine(line);
 
-    return node;
+	return node;
 }
 
 TIntermSwitch *TIntermediate::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line)
@@ -571,30 +579,30 @@
 
 TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, const TSourceLoc &line)
 {
-    TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
-    node->setLine(line);
+	TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
+	node->setLine(line);
 
-    return node;
+	return node;
 }
 
 TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc &line)
 {
 
-    TIntermAggregate* node = new TIntermAggregate(EOpSequence);
+	TIntermAggregate* node = new TIntermAggregate(EOpSequence);
 
-    node->setLine(line);
-    TIntermConstantUnion* constIntNode;
-    TIntermSequence &sequenceVector = node->getSequence();
-    ConstantUnion* unionArray;
+	node->setLine(line);
+	TIntermConstantUnion* constIntNode;
+	TIntermSequence &sequenceVector = node->getSequence();
+	ConstantUnion* unionArray;
 
-    for (int i = 0; i < fields.num; i++) {
-        unionArray = new ConstantUnion[1];
-        unionArray->setIConst(fields.offsets[i]);
-        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), line);
-        sequenceVector.push_back(constIntNode);
-    }
+	for (int i = 0; i < fields.num; i++) {
+		unionArray = new ConstantUnion[1];
+		unionArray->setIConst(fields.offsets[i]);
+		constIntNode = addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), line);
+		sequenceVector.push_back(constIntNode);
+	}
 
-    return node;
+	return node;
 }
 
 //
@@ -602,10 +610,10 @@
 //
 TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, const TSourceLoc &line)
 {
-    TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
-    node->setLine(line);
+	TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
+	node->setLine(line);
 
-    return node;
+	return node;
 }
 
 //
@@ -613,15 +621,15 @@
 //
 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc &line)
 {
-    return addBranch(branchOp, 0, line);
+	return addBranch(branchOp, 0, line);
 }
 
 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc &line)
 {
-    TIntermBranch* node = new TIntermBranch(branchOp, expression);
-    node->setLine(line);
+	TIntermBranch* node = new TIntermBranch(branchOp, expression);
+	node->setLine(line);
 
-    return node;
+	return node;
 }
 
 //
@@ -630,17 +638,17 @@
 //
 bool TIntermediate::postProcess(TIntermNode* root)
 {
-    if (root == 0)
-        return true;
+	if (root == 0)
+		return true;
 
-    //
-    // First, finish off the top level sequence, if any
-    //
-    TIntermAggregate* aggRoot = root->getAsAggregate();
-    if (aggRoot && aggRoot->getOp() == EOpNull)
-        aggRoot->setOp(EOpSequence);
+	//
+	// First, finish off the top level sequence, if any
+	//
+	TIntermAggregate* aggRoot = root->getAsAggregate();
+	if (aggRoot && aggRoot->getOp() == EOpNull)
+		aggRoot->setOp(EOpSequence);
 
-    return true;
+	return true;
 }
 
 ////////////////////////////////////////////////////////////////
@@ -656,30 +664,30 @@
 //
 bool TIntermOperator::modifiesState() const
 {
-    switch (op) {
-        case EOpPostIncrement:
-        case EOpPostDecrement:
-        case EOpPreIncrement:
-        case EOpPreDecrement:
-        case EOpAssign:
-        case EOpAddAssign:
-        case EOpSubAssign:
-        case EOpMulAssign:
-        case EOpVectorTimesMatrixAssign:
-        case EOpVectorTimesScalarAssign:
-        case EOpMatrixTimesScalarAssign:
-        case EOpMatrixTimesMatrixAssign:
-        case EOpDivAssign:
-        case EOpIModAssign:
-        case EOpBitShiftLeftAssign:
-        case EOpBitShiftRightAssign:
-        case EOpBitwiseAndAssign:
-        case EOpBitwiseXorAssign:
-        case EOpBitwiseOrAssign:
-            return true;
-        default:
-            return false;
-    }
+	switch (op) {
+		case EOpPostIncrement:
+		case EOpPostDecrement:
+		case EOpPreIncrement:
+		case EOpPreDecrement:
+		case EOpAssign:
+		case EOpAddAssign:
+		case EOpSubAssign:
+		case EOpMulAssign:
+		case EOpVectorTimesMatrixAssign:
+		case EOpVectorTimesScalarAssign:
+		case EOpMatrixTimesScalarAssign:
+		case EOpMatrixTimesMatrixAssign:
+		case EOpDivAssign:
+		case EOpIModAssign:
+		case EOpBitShiftLeftAssign:
+		case EOpBitShiftRightAssign:
+		case EOpBitwiseAndAssign:
+		case EOpBitwiseXorAssign:
+		case EOpBitwiseOrAssign:
+			return true;
+		default:
+			return false;
+	}
 }
 
 //
@@ -687,37 +695,37 @@
 //
 bool TIntermOperator::isConstructor() const
 {
-    switch (op) {
-        case EOpConstructVec2:
-        case EOpConstructVec3:
-        case EOpConstructVec4:
-        case EOpConstructMat2:
-        case EOpConstructMat2x3:
-        case EOpConstructMat2x4:
-        case EOpConstructMat3x2:
-        case EOpConstructMat3:
-        case EOpConstructMat3x4:
-        case EOpConstructMat4x2:
-        case EOpConstructMat4x3:
-        case EOpConstructMat4:
-        case EOpConstructFloat:
-        case EOpConstructIVec2:
-        case EOpConstructIVec3:
-        case EOpConstructIVec4:
-        case EOpConstructInt:
-        case EOpConstructUVec2:
-        case EOpConstructUVec3:
-        case EOpConstructUVec4:
-        case EOpConstructUInt:
-        case EOpConstructBVec2:
-        case EOpConstructBVec3:
-        case EOpConstructBVec4:
-        case EOpConstructBool:
-        case EOpConstructStruct:
-            return true;
-        default:
-            return false;
-    }
+	switch (op) {
+		case EOpConstructVec2:
+		case EOpConstructVec3:
+		case EOpConstructVec4:
+		case EOpConstructMat2:
+		case EOpConstructMat2x3:
+		case EOpConstructMat2x4:
+		case EOpConstructMat3x2:
+		case EOpConstructMat3:
+		case EOpConstructMat3x4:
+		case EOpConstructMat4x2:
+		case EOpConstructMat4x3:
+		case EOpConstructMat4:
+		case EOpConstructFloat:
+		case EOpConstructIVec2:
+		case EOpConstructIVec3:
+		case EOpConstructIVec4:
+		case EOpConstructInt:
+		case EOpConstructUVec2:
+		case EOpConstructUVec3:
+		case EOpConstructUVec4:
+		case EOpConstructUInt:
+		case EOpConstructBVec2:
+		case EOpConstructBVec3:
+		case EOpConstructBVec4:
+		case EOpConstructBool:
+		case EOpConstructStruct:
+			return true;
+		default:
+			return false;
+	}
 }
 
 //
@@ -731,33 +739,33 @@
 	setType(funcReturnType ? *funcReturnType : operand->getType());
 
 	// Unary operations result in temporary variables unless const.
-    if(type.getQualifier() != EvqConstExpr)
+	if(type.getQualifier() != EvqConstExpr)
 	{
-        type.setQualifier(EvqTemporary);
-    }
+		type.setQualifier(EvqTemporary);
+	}
 
-    switch (op) {
-        case EOpLogicalNot:
-            if (operand->getBasicType() != EbtBool)
-                return false;
-            break;
-        case EOpBitwiseNot:
-            if (!IsInteger(operand->getBasicType()))
-                return false;
-            break;
-        case EOpNegative:
-        case EOpPostIncrement:
-        case EOpPostDecrement:
-        case EOpPreIncrement:
-        case EOpPreDecrement:
-            if (operand->getBasicType() == EbtBool)
-                return false;
-            break;
+	switch (op) {
+		case EOpLogicalNot:
+			if (operand->getBasicType() != EbtBool)
+				return false;
+			break;
+		case EOpBitwiseNot:
+			if (!IsInteger(operand->getBasicType()))
+				return false;
+			break;
+		case EOpNegative:
+		case EOpPostIncrement:
+		case EOpPostDecrement:
+		case EOpPreIncrement:
+		case EOpPreDecrement:
+			if (operand->getBasicType() == EbtBool)
+				return false;
+			break;
 
-            // operators for built-ins are already type checked against their prototype
-        case EOpAny:
-        case EOpAll:
-        case EOpVectorLogicalNot:
+			// operators for built-ins are already type checked against their prototype
+		case EOpAny:
+		case EOpAll:
+		case EOpVectorLogicalNot:
 		case EOpAbs:
 		case EOpSign:
 		case EOpIsNan:
@@ -772,14 +780,14 @@
 		case EOpUnpackSnorm2x16:
 		case EOpUnpackUnorm2x16:
 		case EOpUnpackHalf2x16:
-            return true;
+			return true;
 
-        default:
-            if (operand->getBasicType() != EbtFloat)
-                return false;
-    }
+		default:
+			if (operand->getBasicType() != EbtFloat)
+				return false;
+	}
 
-    return true;
+	return true;
 }
 
 //
@@ -792,228 +800,228 @@
 {
 	ASSERT(left->isArray() == right->isArray());
 
-    // GLSL ES 2.0 does not support implicit type casting.
-    // So the basic type should always match.
+	// GLSL ES 2.0 does not support implicit type casting.
+	// So the basic type should always match.
 	// GLSL ES 3.0 supports integer shift operands of different signedness.
 	if(op != EOpBitShiftLeft &&
 	   op != EOpBitShiftRight &&
 	   op != EOpBitShiftLeftAssign &&
 	   op != EOpBitShiftRightAssign &&
 	   left->getBasicType() != right->getBasicType())
-    {
-        return false;
-    }
+	{
+		return false;
+	}
 
-    //
-    // Base assumption:  just make the type the same as the left
-    // operand.  Then only deviations from this need be coded.
-    //
-    setType(left->getType());
+	//
+	// Base assumption:  just make the type the same as the left
+	// operand.  Then only deviations from this need be coded.
+	//
+	setType(left->getType());
 
-    // The result gets promoted to the highest precision.
-    TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
-    getTypePointer()->setPrecision(higherPrecision);
+	// The result gets promoted to the highest precision.
+	TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
+	getTypePointer()->setPrecision(higherPrecision);
 
-    // Binary operations results in temporary variables unless both
-    // operands are const.
-    if (left->getQualifier() != EvqConstExpr || right->getQualifier() != EvqConstExpr) {
-        getTypePointer()->setQualifier(EvqTemporary);
-    }
+	// Binary operations results in temporary variables unless both
+	// operands are const.
+	if (left->getQualifier() != EvqConstExpr || right->getQualifier() != EvqConstExpr) {
+		getTypePointer()->setQualifier(EvqTemporary);
+	}
 
-    int primarySize = std::max(left->getNominalSize(), right->getNominalSize());
+	int primarySize = std::max(left->getNominalSize(), right->getNominalSize());
 
-    //
-    // All scalars. Code after this test assumes this case is removed!
-    //
-    if (primarySize == 1) {
-        switch (op) {
-            //
-            // Promote to conditional
-            //
-            case EOpEqual:
-            case EOpNotEqual:
-            case EOpLessThan:
-            case EOpGreaterThan:
-            case EOpLessThanEqual:
-            case EOpGreaterThanEqual:
-                setType(TType(EbtBool, EbpUndefined));
-                break;
+	//
+	// All scalars. Code after this test assumes this case is removed!
+	//
+	if (primarySize == 1) {
+		switch (op) {
+			//
+			// Promote to conditional
+			//
+			case EOpEqual:
+			case EOpNotEqual:
+			case EOpLessThan:
+			case EOpGreaterThan:
+			case EOpLessThanEqual:
+			case EOpGreaterThanEqual:
+				setType(TType(EbtBool, EbpUndefined));
+				break;
 
-            //
-            // And and Or operate on conditionals
-            //
-            case EOpLogicalAnd:
-            case EOpLogicalOr:
-            case EOpLogicalXor:
-                // Both operands must be of type bool.
-                if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
-                    return false;
-                setType(TType(EbtBool, EbpUndefined));
-                break;
+			//
+			// And and Or operate on conditionals
+			//
+			case EOpLogicalAnd:
+			case EOpLogicalOr:
+			case EOpLogicalXor:
+				// Both operands must be of type bool.
+				if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
+					return false;
+				setType(TType(EbtBool, EbpUndefined));
+				break;
 
-            default:
-                break;
-        }
-        return true;
-    }
+			default:
+				break;
+		}
+		return true;
+	}
 
-    // If we reach here, at least one of the operands is vector or matrix.
-    // The other operand could be a scalar, vector, or matrix.
-    // Can these two operands be combined?
-    //
-    TBasicType basicType = left->getBasicType();
-    switch (op) {
-        case EOpMul:
-            if (!left->isMatrix() && right->isMatrix()) {
-                if (left->isVector())
-                {
-                    op = EOpVectorTimesMatrix;
-                    setType(TType(basicType, higherPrecision, EvqTemporary,
-                        static_cast<unsigned char>(right->getNominalSize()), 1));
-                }
-                else {
-                    op = EOpMatrixTimesScalar;
-                    setType(TType(basicType, higherPrecision, EvqTemporary,
-                        static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(right->getSecondarySize())));
-                }
-            } else if (left->isMatrix() && !right->isMatrix()) {
-                if (right->isVector()) {
-                    op = EOpMatrixTimesVector;
-                    setType(TType(basicType, higherPrecision, EvqTemporary,
-                        static_cast<unsigned char>(left->getSecondarySize()), 1));
-                } else {
-                    op = EOpMatrixTimesScalar;
-                }
-            } else if (left->isMatrix() && right->isMatrix()) {
-                op = EOpMatrixTimesMatrix;
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                    static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(left->getSecondarySize())));
-            } else if (!left->isMatrix() && !right->isMatrix()) {
-                if (left->isVector() && right->isVector()) {
-                    // leave as component product
-                } else if (left->isVector() || right->isVector()) {
-                    op = EOpVectorTimesScalar;
-                    setType(TType(basicType, higherPrecision, EvqTemporary,
-                        static_cast<unsigned char>(primarySize), 1));
-                }
-            } else {
-                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
-                return false;
-            }
+	// If we reach here, at least one of the operands is vector or matrix.
+	// The other operand could be a scalar, vector, or matrix.
+	// Can these two operands be combined?
+	//
+	TBasicType basicType = left->getBasicType();
+	switch (op) {
+		case EOpMul:
+			if (!left->isMatrix() && right->isMatrix()) {
+				if (left->isVector())
+				{
+					op = EOpVectorTimesMatrix;
+					setType(TType(basicType, higherPrecision, EvqTemporary,
+						static_cast<unsigned char>(right->getNominalSize()), 1));
+				}
+				else {
+					op = EOpMatrixTimesScalar;
+					setType(TType(basicType, higherPrecision, EvqTemporary,
+						static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(right->getSecondarySize())));
+				}
+			} else if (left->isMatrix() && !right->isMatrix()) {
+				if (right->isVector()) {
+					op = EOpMatrixTimesVector;
+					setType(TType(basicType, higherPrecision, EvqTemporary,
+						static_cast<unsigned char>(left->getSecondarySize()), 1));
+				} else {
+					op = EOpMatrixTimesScalar;
+				}
+			} else if (left->isMatrix() && right->isMatrix()) {
+				op = EOpMatrixTimesMatrix;
+				setType(TType(basicType, higherPrecision, EvqTemporary,
+					static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(left->getSecondarySize())));
+			} else if (!left->isMatrix() && !right->isMatrix()) {
+				if (left->isVector() && right->isVector()) {
+					// leave as component product
+				} else if (left->isVector() || right->isVector()) {
+					op = EOpVectorTimesScalar;
+					setType(TType(basicType, higherPrecision, EvqTemporary,
+						static_cast<unsigned char>(primarySize), 1));
+				}
+			} else {
+				infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+				return false;
+			}
 
-            if(!ValidateMultiplication(op, left->getType(), right->getType()))
-            {
-                return false;
-            }
-            break;
-        case EOpMulAssign:
-            if (!left->isMatrix() && right->isMatrix()) {
-                if (left->isVector())
-                    op = EOpVectorTimesMatrixAssign;
-                else {
-                    return false;
-                }
-            } else if (left->isMatrix() && !right->isMatrix()) {
-                if (right->isVector()) {
-                    return false;
-                } else {
-                    op = EOpMatrixTimesScalarAssign;
-                }
-            } else if (left->isMatrix() && right->isMatrix()) {
-                op = EOpMatrixTimesMatrixAssign;
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                    static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(left->getSecondarySize())));
-            } else if (!left->isMatrix() && !right->isMatrix()) {
-                if (left->isVector() && right->isVector()) {
-                    // leave as component product
-                } else if (left->isVector() || right->isVector()) {
-                    if (! left->isVector())
-                        return false;
-                    op = EOpVectorTimesScalarAssign;
-                    setType(TType(basicType, higherPrecision, EvqTemporary,
-                        static_cast<unsigned char>(left->getNominalSize()), 1));
-                }
-            } else {
-                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
-                return false;
-            }
+			if(!ValidateMultiplication(op, left->getType(), right->getType()))
+			{
+				return false;
+			}
+			break;
+		case EOpMulAssign:
+			if (!left->isMatrix() && right->isMatrix()) {
+				if (left->isVector())
+					op = EOpVectorTimesMatrixAssign;
+				else {
+					return false;
+				}
+			} else if (left->isMatrix() && !right->isMatrix()) {
+				if (right->isVector()) {
+					return false;
+				} else {
+					op = EOpMatrixTimesScalarAssign;
+				}
+			} else if (left->isMatrix() && right->isMatrix()) {
+				op = EOpMatrixTimesMatrixAssign;
+				setType(TType(basicType, higherPrecision, EvqTemporary,
+					static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(left->getSecondarySize())));
+			} else if (!left->isMatrix() && !right->isMatrix()) {
+				if (left->isVector() && right->isVector()) {
+					// leave as component product
+				} else if (left->isVector() || right->isVector()) {
+					if (! left->isVector())
+						return false;
+					op = EOpVectorTimesScalarAssign;
+					setType(TType(basicType, higherPrecision, EvqTemporary,
+						static_cast<unsigned char>(left->getNominalSize()), 1));
+				}
+			} else {
+				infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+				return false;
+			}
 
-            if(!ValidateMultiplication(op, left->getType(), right->getType()))
-            {
-                return false;
-            }
-            break;
+			if(!ValidateMultiplication(op, left->getType(), right->getType()))
+			{
+				return false;
+			}
+			break;
 
-        case EOpAssign:
-        case EOpInitialize:
-            // No more additional checks are needed.
-            if ((left->getNominalSize() != right->getNominalSize()) ||
-                (left->getSecondarySize() != right->getSecondarySize()))
-                return false;
-            break;
-        case EOpAdd:
-        case EOpSub:
-        case EOpDiv:
-        case EOpIMod:
-        case EOpBitShiftLeft:
-        case EOpBitShiftRight:
-        case EOpBitwiseAnd:
-        case EOpBitwiseXor:
-        case EOpBitwiseOr:
-        case EOpAddAssign:
-        case EOpSubAssign:
-        case EOpDivAssign:
-        case EOpIModAssign:
-        case EOpBitShiftLeftAssign:
-        case EOpBitShiftRightAssign:
-        case EOpBitwiseAndAssign:
-        case EOpBitwiseXorAssign:
-        case EOpBitwiseOrAssign:
-            if ((left->isMatrix() && right->isVector()) ||
-                (left->isVector() && right->isMatrix()))
-                return false;
+		case EOpAssign:
+		case EOpInitialize:
+			// No more additional checks are needed.
+			if ((left->getNominalSize() != right->getNominalSize()) ||
+				(left->getSecondarySize() != right->getSecondarySize()))
+				return false;
+			break;
+		case EOpAdd:
+		case EOpSub:
+		case EOpDiv:
+		case EOpIMod:
+		case EOpBitShiftLeft:
+		case EOpBitShiftRight:
+		case EOpBitwiseAnd:
+		case EOpBitwiseXor:
+		case EOpBitwiseOr:
+		case EOpAddAssign:
+		case EOpSubAssign:
+		case EOpDivAssign:
+		case EOpIModAssign:
+		case EOpBitShiftLeftAssign:
+		case EOpBitShiftRightAssign:
+		case EOpBitwiseAndAssign:
+		case EOpBitwiseXorAssign:
+		case EOpBitwiseOrAssign:
+			if ((left->isMatrix() && right->isVector()) ||
+				(left->isVector() && right->isMatrix()))
+				return false;
 
-            // Are the sizes compatible?
-            if(left->getNominalSize() != right->getNominalSize() ||
-               left->getSecondarySize() != right->getSecondarySize())
-            {
-                // If the nominal sizes of operands do not match:
-                // One of them must be a scalar.
-                if(!left->isScalar() && !right->isScalar())
-                    return false;
+			// Are the sizes compatible?
+			if(left->getNominalSize() != right->getNominalSize() ||
+			   left->getSecondarySize() != right->getSecondarySize())
+			{
+				// If the nominal sizes of operands do not match:
+				// One of them must be a scalar.
+				if(!left->isScalar() && !right->isScalar())
+					return false;
 
-                // In the case of compound assignment other than multiply-assign,
-                // the right side needs to be a scalar. Otherwise a vector/matrix
-                // would be assigned to a scalar. A scalar can't be shifted by a
-                // vector either.
-                if(!right->isScalar() && (modifiesState() || op == EOpBitShiftLeft || op == EOpBitShiftRight))
-                    return false;
-            }
+				// In the case of compound assignment other than multiply-assign,
+				// the right side needs to be a scalar. Otherwise a vector/matrix
+				// would be assigned to a scalar. A scalar can't be shifted by a
+				// vector either.
+				if(!right->isScalar() && (modifiesState() || op == EOpBitShiftLeft || op == EOpBitShiftRight))
+					return false;
+			}
 
-            {
-                const int secondarySize = std::max(
-                    left->getSecondarySize(), right->getSecondarySize());
-                setType(TType(basicType, higherPrecision, EvqTemporary,
-                    static_cast<unsigned char>(primarySize), static_cast<unsigned char>(secondarySize)));
-                if(left->isArray())
-                {
-                    ASSERT(left->getArraySize() == right->getArraySize());
-                    type.setArraySize(left->getArraySize());
-                }
-            }
-            break;
+			{
+				const int secondarySize = std::max(
+					left->getSecondarySize(), right->getSecondarySize());
+				setType(TType(basicType, higherPrecision, EvqTemporary,
+					static_cast<unsigned char>(primarySize), static_cast<unsigned char>(secondarySize)));
+				if(left->isArray())
+				{
+					ASSERT(left->getArraySize() == right->getArraySize());
+					type.setArraySize(left->getArraySize());
+				}
+			}
+			break;
 
-        case EOpEqual:
-        case EOpNotEqual:
-        case EOpLessThan:
-        case EOpGreaterThan:
-        case EOpLessThanEqual:
-        case EOpGreaterThanEqual:
-            if ((left->getNominalSize() != right->getNominalSize()) ||
-                (left->getSecondarySize() != right->getSecondarySize()))
-                return false;
-            setType(TType(EbtBool, EbpUndefined));
-            break;
+		case EOpEqual:
+		case EOpNotEqual:
+		case EOpLessThan:
+		case EOpGreaterThan:
+		case EOpLessThanEqual:
+		case EOpGreaterThanEqual:
+			if ((left->getNominalSize() != right->getNominalSize()) ||
+				(left->getSecondarySize() != right->getSecondarySize()))
+				return false;
+			setType(TType(EbtBool, EbpUndefined));
+			break;
 
 		case EOpOuterProduct:
 			if(!left->isVector() || !right->isVector())
@@ -1039,54 +1047,54 @@
 			setType(right->getType());
 			break;
 
-        default:
-            return false;
-    }
+		default:
+			return false;
+	}
 
-    return true;
+	return true;
 }
 
 bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
 {
-    const TFieldList& fields = leftNodeType.getStruct()->fields();
+	const TFieldList& fields = leftNodeType.getStruct()->fields();
 
-    size_t structSize = fields.size();
-    int index = 0;
+	size_t structSize = fields.size();
+	int index = 0;
 
-    for (size_t j = 0; j < structSize; j++) {
-        size_t size = fields[j]->type()->getObjectSize();
-        for(size_t i = 0; i < size; i++) {
-            if (fields[j]->type()->getBasicType() == EbtStruct) {
-                if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
-                    return false;
-            } else {
-                if (leftUnionArray[index] != rightUnionArray[index])
-                    return false;
-                index++;
-            }
+	for (size_t j = 0; j < structSize; j++) {
+		size_t size = fields[j]->type()->getObjectSize();
+		for(size_t i = 0; i < size; i++) {
+			if (fields[j]->type()->getBasicType() == EbtStruct) {
+				if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
+					return false;
+			} else {
+				if (leftUnionArray[index] != rightUnionArray[index])
+					return false;
+				index++;
+			}
 
-        }
-    }
-    return true;
+		}
+	}
+	return true;
 }
 
 bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
 {
-    if (leftNodeType.isArray()) {
-        TType typeWithoutArrayness = leftNodeType;
-        typeWithoutArrayness.clearArrayness();
+	if (leftNodeType.isArray()) {
+		TType typeWithoutArrayness = leftNodeType;
+		typeWithoutArrayness.clearArrayness();
 
-        int arraySize = leftNodeType.getArraySize();
+		int arraySize = leftNodeType.getArraySize();
 
-        for (int i = 0; i < arraySize; ++i) {
-            size_t offset = typeWithoutArrayness.getObjectSize() * i;
-            if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset]))
-                return false;
-        }
-    } else
-        return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
+		for (int i = 0; i < arraySize; ++i) {
+			size_t offset = typeWithoutArrayness.getObjectSize() * i;
+			if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset]))
+				return false;
+		}
+	} else
+		return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
 
-    return true;
+	return true;
 }
 
 float determinant2(float m00, float m01, float m10, float m11)
@@ -1095,23 +1103,23 @@
 }
 
 float determinant3(float m00, float m01, float m02,
-                   float m10, float m11, float m12,
-                   float m20, float m21, float m22)
+				   float m10, float m11, float m12,
+				   float m20, float m21, float m22)
 {
 	return m00 * determinant2(m11, m12, m21, m22) -
-	       m10 * determinant2(m01, m02, m21, m22) +
-	       m20 * determinant2(m01, m02, m11, m12);
+		   m10 * determinant2(m01, m02, m21, m22) +
+		   m20 * determinant2(m01, m02, m11, m12);
 }
 
 float determinant4(float m00, float m01, float m02, float m03,
-                   float m10, float m11, float m12, float m13,
-                   float m20, float m21, float m22, float m23,
-                   float m30, float m31, float m32, float m33)
+				   float m10, float m11, float m12, float m13,
+				   float m20, float m21, float m22, float m23,
+				   float m30, float m31, float m32, float m33)
 {
 	return m00 * determinant3(m11, m12, m13, m21, m22, m23, m31, m32, m33) -
-	       m10 * determinant3(m01, m02, m03, m21, m22, m23, m31, m32, m33) +
-	       m20 * determinant3(m01, m02, m03, m11, m12, m13, m31, m32, m33) -
-	       m30 * determinant3(m01, m02, m03, m11, m12, m13, m21, m22, m23);
+		   m10 * determinant3(m01, m02, m03, m21, m22, m23, m31, m32, m33) +
+		   m20 * determinant3(m01, m02, m03, m11, m12, m13, m31, m32, m33) -
+		   m30 * determinant3(m01, m02, m03, m11, m12, m13, m21, m22, m23);
 }
 
 float ComputeDeterminant(int size, ConstantUnion* unionArray)
@@ -1120,36 +1128,36 @@
 	{
 	case 2:
 		return determinant2(unionArray[0].getFConst(),
-		                    unionArray[1].getFConst(),
-		                    unionArray[2].getFConst(),
-		                    unionArray[3].getFConst());
+							unionArray[1].getFConst(),
+							unionArray[2].getFConst(),
+							unionArray[3].getFConst());
 	case 3:
 		return determinant3(unionArray[0].getFConst(),
-		                    unionArray[1].getFConst(),
-		                    unionArray[2].getFConst(),
-		                    unionArray[3].getFConst(),
-		                    unionArray[4].getFConst(),
-		                    unionArray[5].getFConst(),
-		                    unionArray[6].getFConst(),
-		                    unionArray[7].getFConst(),
-		                    unionArray[8].getFConst());
+							unionArray[1].getFConst(),
+							unionArray[2].getFConst(),
+							unionArray[3].getFConst(),
+							unionArray[4].getFConst(),
+							unionArray[5].getFConst(),
+							unionArray[6].getFConst(),
+							unionArray[7].getFConst(),
+							unionArray[8].getFConst());
 	case 4:
 		return determinant4(unionArray[0].getFConst(),
-		                    unionArray[1].getFConst(),
-		                    unionArray[2].getFConst(),
-		                    unionArray[3].getFConst(),
-		                    unionArray[4].getFConst(),
-		                    unionArray[5].getFConst(),
-		                    unionArray[6].getFConst(),
-		                    unionArray[7].getFConst(),
-		                    unionArray[8].getFConst(),
-		                    unionArray[9].getFConst(),
-		                    unionArray[10].getFConst(),
-		                    unionArray[11].getFConst(),
-		                    unionArray[12].getFConst(),
-		                    unionArray[13].getFConst(),
-		                    unionArray[14].getFConst(),
-		                    unionArray[15].getFConst());
+							unionArray[1].getFConst(),
+							unionArray[2].getFConst(),
+							unionArray[3].getFConst(),
+							unionArray[4].getFConst(),
+							unionArray[5].getFConst(),
+							unionArray[6].getFConst(),
+							unionArray[7].getFConst(),
+							unionArray[8].getFConst(),
+							unionArray[9].getFConst(),
+							unionArray[10].getFConst(),
+							unionArray[11].getFConst(),
+							unionArray[12].getFConst(),
+							unionArray[13].getFConst(),
+							unionArray[14].getFConst(),
+							unionArray[15].getFConst());
 	default:
 		UNREACHABLE(size);
 		return 0.0f;
@@ -1253,88 +1261,88 @@
 
 TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
 {
-    ConstantUnion *unionArray = getUnionArrayPointer();
-    size_t objectSize = getType().getObjectSize();
+	ConstantUnion *unionArray = getUnionArrayPointer();
+	size_t objectSize = getType().getObjectSize();
 
-    if (constantNode) {  // binary operations
-        TIntermConstantUnion *node = constantNode->getAsConstantUnion();
-        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
-        TType returnType = getType();
+	if (constantNode) {  // binary operations
+		TIntermConstantUnion *node = constantNode->getAsConstantUnion();
+		ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
+		TType returnType = getType();
 
-        // for a case like float f = 1.2 + vec4(2,3,4,5);
-        if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
-            rightUnionArray = new ConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; ++i)
-                rightUnionArray[i] = *node->getUnionArrayPointer();
-            returnType = getType();
-        } else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
-            // for a case like float f = vec4(2,3,4,5) + 1.2;
-            unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
-            for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
-                unionArray[i] = *getUnionArrayPointer();
-            returnType = node->getType();
-            objectSize = constantNode->getType().getObjectSize();
-        }
+		// for a case like float f = 1.2 + vec4(2,3,4,5);
+		if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
+			rightUnionArray = new ConstantUnion[objectSize];
+			for (size_t i = 0; i < objectSize; ++i)
+				rightUnionArray[i] = *node->getUnionArrayPointer();
+			returnType = getType();
+		} else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
+			// for a case like float f = vec4(2,3,4,5) + 1.2;
+			unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
+			for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
+				unionArray[i] = *getUnionArrayPointer();
+			returnType = node->getType();
+			objectSize = constantNode->getType().getObjectSize();
+		}
 
-        ConstantUnion* tempConstArray = 0;
-        TIntermConstantUnion *tempNode;
+		ConstantUnion* tempConstArray = 0;
+		TIntermConstantUnion *tempNode;
 
-        switch(op) {
-            case EOpAdd:
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        tempConstArray[i] = unionArray[i] + rightUnionArray[i];
-                }
-                break;
-            case EOpSub:
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        tempConstArray[i] = unionArray[i] - rightUnionArray[i];
-                }
-                break;
+		switch(op) {
+			case EOpAdd:
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						tempConstArray[i] = unionArray[i] + rightUnionArray[i];
+				}
+				break;
+			case EOpSub:
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						tempConstArray[i] = unionArray[i] - rightUnionArray[i];
+				}
+				break;
 
-            case EOpMul:
-            case EOpVectorTimesScalar:
-            case EOpMatrixTimesScalar:
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        tempConstArray[i] = unionArray[i] * rightUnionArray[i];
-                }
-                break;
-            case EOpMatrixTimesMatrix:
-                if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
-                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
-                    return 0;
-                }
-                {// support MSVC++6.0
-                    int leftNumCols = getNominalSize();
-                    int leftNumRows = getSecondarySize();
-                    int rightNumCols = node->getNominalSize();
-                    int rightNumRows = node->getSecondarySize();
-                    if(leftNumCols != rightNumRows) {
-                        infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
-                        return 0;
-                    }
-                    int tempNumCols = rightNumCols;
-                    int tempNumRows = leftNumRows;
-                    int tempNumAdds = leftNumCols;
-                    tempConstArray = new ConstantUnion[tempNumCols*tempNumRows];
-                    for (int row = 0; row < tempNumRows; row++) {
-                        for (int column = 0; column < tempNumCols; column++) {
-                            tempConstArray[tempNumRows * column + row].setFConst(0.0f);
-                            for (int i = 0; i < tempNumAdds; i++) {
-                                tempConstArray[tempNumRows * column + row].setFConst(tempConstArray[tempNumRows * column + row].getFConst() + unionArray[i * leftNumRows + row].getFConst() * (rightUnionArray[column * rightNumRows + i].getFConst()));
-                            }
-                        }
-                    }
-                    // update return type for matrix product
-                    returnType.setNominalSize(static_cast<unsigned char>(tempNumCols));
-                    returnType.setSecondarySize(static_cast<unsigned char>(tempNumRows));
-                }
-                break;
+			case EOpMul:
+			case EOpVectorTimesScalar:
+			case EOpMatrixTimesScalar:
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						tempConstArray[i] = unionArray[i] * rightUnionArray[i];
+				}
+				break;
+			case EOpMatrixTimesMatrix:
+				if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
+					infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
+					return 0;
+				}
+				{// support MSVC++6.0
+					int leftNumCols = getNominalSize();
+					int leftNumRows = getSecondarySize();
+					int rightNumCols = node->getNominalSize();
+					int rightNumRows = node->getSecondarySize();
+					if(leftNumCols != rightNumRows) {
+						infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
+						return 0;
+					}
+					int tempNumCols = rightNumCols;
+					int tempNumRows = leftNumRows;
+					int tempNumAdds = leftNumCols;
+					tempConstArray = new ConstantUnion[tempNumCols*tempNumRows];
+					for (int row = 0; row < tempNumRows; row++) {
+						for (int column = 0; column < tempNumCols; column++) {
+							tempConstArray[tempNumRows * column + row].setFConst(0.0f);
+							for (int i = 0; i < tempNumAdds; i++) {
+								tempConstArray[tempNumRows * column + row].setFConst(tempConstArray[tempNumRows * column + row].getFConst() + unionArray[i * leftNumRows + row].getFConst() * (rightUnionArray[column * rightNumRows + i].getFConst()));
+							}
+						}
+					}
+					// update return type for matrix product
+					returnType.setNominalSize(static_cast<unsigned char>(tempNumCols));
+					returnType.setSecondarySize(static_cast<unsigned char>(tempNumRows));
+				}
+				break;
 
 			case EOpOuterProduct:
 				{
@@ -1395,267 +1403,267 @@
 				}
 				break;
 
-            case EOpDiv:
-            case EOpIMod:
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++) {
-                        switch (getType().getBasicType()) {
-                            case EbtFloat:
-                                if (rightUnionArray[i] == 0.0f) {
-                                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
-                                    tempConstArray[i].setFConst(FLT_MAX);
-                                } else {
-                                    ASSERT(op == EOpDiv);
-                                    tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
-                                }
-                                break;
-
-                            case EbtInt:
-                                if (rightUnionArray[i] == 0) {
-                                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
-                                    tempConstArray[i].setIConst(INT_MAX);
-                                } else {
-                                    if(op == EOpDiv) {
-                                        tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
-                                    } else {
-                                        ASSERT(op == EOpIMod);
-                                        tempConstArray[i].setIConst(unionArray[i].getIConst() % rightUnionArray[i].getIConst());
-                                    }
-                                }
-                                break;
-                            case EbtUInt:
-                                if (rightUnionArray[i] == 0) {
-                                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
-                                    tempConstArray[i].setUConst(UINT_MAX);
-                                } else {
-                                    if(op == EOpDiv) {
-                                        tempConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
-                                    } else {
-                                        ASSERT(op == EOpIMod);
-                                        tempConstArray[i].setUConst(unionArray[i].getUConst() % rightUnionArray[i].getUConst());
-                                    }
-                                }
-                                break;
-                            default:
-                                infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
-                                return 0;
-                        }
-                    }
-                }
-                break;
-
-            case EOpMatrixTimesVector:
-                if (node->getBasicType() != EbtFloat) {
-                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
-                    return 0;
-                }
-                tempConstArray = new ConstantUnion[getNominalSize()];
-
-                {// support MSVC++6.0
-                    for (int size = getNominalSize(), i = 0; i < size; i++) {
-                        tempConstArray[i].setFConst(0.0f);
-                        for (int j = 0; j < size; j++) {
-                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst()));
-                        }
-                    }
-                }
-
-                tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
-                tempNode->setLine(getLine());
-
-                return tempNode;
-
-            case EOpVectorTimesMatrix:
-                if (getType().getBasicType() != EbtFloat) {
-                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
-                    return 0;
-                }
-
-                tempConstArray = new ConstantUnion[getNominalSize()];
-                {// support MSVC++6.0
-                    for (int size = getNominalSize(), i = 0; i < size; i++) {
-                        tempConstArray[i].setFConst(0.0f);
-                        for (int j = 0; j < size; j++) {
-                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst()));
-                        }
-                    }
-                }
-                break;
-
-            case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        tempConstArray[i] = unionArray[i] && rightUnionArray[i];
-                }
-                break;
-
-            case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        tempConstArray[i] = unionArray[i] || rightUnionArray[i];
-                }
-                break;
-
-            case EOpLogicalXor:
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        switch (getType().getBasicType()) {
-                            case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
-                            default: assert(false && "Default missing");
-                    }
-                }
-                break;
-
-            case EOpBitwiseAnd:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] & rightUnionArray[i];
-                break;
-            case EOpBitwiseXor:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
-                break;
-            case EOpBitwiseOr:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] | rightUnionArray[i];
-                break;
-            case EOpBitShiftLeft:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] << rightUnionArray[i];
-                break;
-            case EOpBitShiftRight:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
-                break;
-
-            case EOpLessThan:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
-					tempConstArray[i].setBConst(unionArray[i] < rightUnionArray[i]);
-                returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
-                break;
-            case EOpGreaterThan:
+			case EOpDiv:
+			case EOpIMod:
 				tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++) {
+						switch (getType().getBasicType()) {
+							case EbtFloat:
+								if (rightUnionArray[i] == 0.0f) {
+									infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+									tempConstArray[i].setFConst(FLT_MAX);
+								} else {
+									ASSERT(op == EOpDiv);
+									tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
+								}
+								break;
+
+							case EbtInt:
+								if (rightUnionArray[i] == 0) {
+									infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+									tempConstArray[i].setIConst(INT_MAX);
+								} else {
+									if(op == EOpDiv) {
+										tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
+									} else {
+										ASSERT(op == EOpIMod);
+										tempConstArray[i].setIConst(unionArray[i].getIConst() % rightUnionArray[i].getIConst());
+									}
+								}
+								break;
+							case EbtUInt:
+								if (rightUnionArray[i] == 0) {
+									infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+									tempConstArray[i].setUConst(UINT_MAX);
+								} else {
+									if(op == EOpDiv) {
+										tempConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
+									} else {
+										ASSERT(op == EOpIMod);
+										tempConstArray[i].setUConst(unionArray[i].getUConst() % rightUnionArray[i].getUConst());
+									}
+								}
+								break;
+							default:
+								infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
+								return 0;
+						}
+					}
+				}
+				break;
+
+			case EOpMatrixTimesVector:
+				if (node->getBasicType() != EbtFloat) {
+					infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
+					return 0;
+				}
+				tempConstArray = new ConstantUnion[getNominalSize()];
+
+				{// support MSVC++6.0
+					for (int size = getNominalSize(), i = 0; i < size; i++) {
+						tempConstArray[i].setFConst(0.0f);
+						for (int j = 0; j < size; j++) {
+							tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst()));
+						}
+					}
+				}
+
+				tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
+				tempNode->setLine(getLine());
+
+				return tempNode;
+
+			case EOpVectorTimesMatrix:
+				if (getType().getBasicType() != EbtFloat) {
+					infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
+					return 0;
+				}
+
+				tempConstArray = new ConstantUnion[getNominalSize()];
+				{// support MSVC++6.0
+					for (int size = getNominalSize(), i = 0; i < size; i++) {
+						tempConstArray[i].setFConst(0.0f);
+						for (int j = 0; j < size; j++) {
+							tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst()));
+						}
+					}
+				}
+				break;
+
+			case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						tempConstArray[i] = unionArray[i] && rightUnionArray[i];
+				}
+				break;
+
+			case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						tempConstArray[i] = unionArray[i] || rightUnionArray[i];
+				}
+				break;
+
+			case EOpLogicalXor:
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						switch (getType().getBasicType()) {
+							case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
+							default: assert(false && "Default missing");
+					}
+				}
+				break;
+
+			case EOpBitwiseAnd:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
+					tempConstArray[i] = unionArray[i] & rightUnionArray[i];
+				break;
+			case EOpBitwiseXor:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
+					tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
+				break;
+			case EOpBitwiseOr:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
+					tempConstArray[i] = unionArray[i] | rightUnionArray[i];
+				break;
+			case EOpBitShiftLeft:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
+					tempConstArray[i] = unionArray[i] << rightUnionArray[i];
+				break;
+			case EOpBitShiftRight:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
+					tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
+				break;
+
+			case EOpLessThan:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
+					tempConstArray[i].setBConst(unionArray[i] < rightUnionArray[i]);
+				returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
+				break;
+			case EOpGreaterThan:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
 					tempConstArray[i].setBConst(unionArray[i] > rightUnionArray[i]);
-                returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
-                break;
-            case EOpLessThanEqual:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
+				returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
+				break;
+			case EOpLessThanEqual:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
 					tempConstArray[i].setBConst(unionArray[i] <= rightUnionArray[i]);
-                returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
-                break;
-            case EOpGreaterThanEqual:
-                tempConstArray = new ConstantUnion[objectSize];
-                for(size_t i = 0; i < objectSize; i++)
+				returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
+				break;
+			case EOpGreaterThanEqual:
+				tempConstArray = new ConstantUnion[objectSize];
+				for(size_t i = 0; i < objectSize; i++)
 					tempConstArray[i].setBConst(unionArray[i] >= rightUnionArray[i]);
-                returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
-                break;
-            case EOpEqual:
+				returnType = TType(EbtBool, EbpUndefined, EvqConstExpr, objectSize);
+				break;
+			case EOpEqual:
 				tempConstArray = new ConstantUnion[1];
 
 				if(getType().getBasicType() == EbtStruct) {
 					tempConstArray->setBConst(CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray));
-                } else {
+				} else {
 					bool boolNodeFlag = true;
-                    for (size_t i = 0; i < objectSize; i++) {
-                        if (unionArray[i] != rightUnionArray[i]) {
-                            boolNodeFlag = false;
-                            break;  // break out of for loop
-                        }
-                    }
+					for (size_t i = 0; i < objectSize; i++) {
+						if (unionArray[i] != rightUnionArray[i]) {
+							boolNodeFlag = false;
+							break;  // break out of for loop
+						}
+					}
 					tempConstArray->setBConst(boolNodeFlag);
-                }
+				}
 
-                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConstExpr));
-                tempNode->setLine(getLine());
+				tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConstExpr));
+				tempNode->setLine(getLine());
 
-                return tempNode;
+				return tempNode;
 
-            case EOpNotEqual:
+			case EOpNotEqual:
 				tempConstArray = new ConstantUnion[1];
 
 				if(getType().getBasicType() == EbtStruct) {
 					tempConstArray->setBConst(!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray));
-                } else {
+				} else {
 					bool boolNodeFlag = false;
-                    for (size_t i = 0; i < objectSize; i++) {
-                        if (unionArray[i] != rightUnionArray[i]) {
-                            boolNodeFlag = true;
-                            break;  // break out of for loop
-                        }
-                    }
+					for (size_t i = 0; i < objectSize; i++) {
+						if (unionArray[i] != rightUnionArray[i]) {
+							boolNodeFlag = true;
+							break;  // break out of for loop
+						}
+					}
 					tempConstArray->setBConst(boolNodeFlag);
-                }
+				}
 
-                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConstExpr));
-                tempNode->setLine(getLine());
+				tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConstExpr));
+				tempNode->setLine(getLine());
 
-                return tempNode;
+				return tempNode;
 			case EOpMax:
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        tempConstArray[i] = unionArray[i] > rightUnionArray[i] ? unionArray[i] : rightUnionArray[i];
-                }
-                break;
-            case EOpMin:
-                tempConstArray = new ConstantUnion[objectSize];
-                {// support MSVC++6.0
-                    for (size_t i = 0; i < objectSize; i++)
-                        tempConstArray[i] = unionArray[i] < rightUnionArray[i] ? unionArray[i] : rightUnionArray[i];
-                }
-                break;
-            default:
-                return 0;
-        }
-        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
-        tempNode->setLine(getLine());
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						tempConstArray[i] = unionArray[i] > rightUnionArray[i] ? unionArray[i] : rightUnionArray[i];
+				}
+				break;
+			case EOpMin:
+				tempConstArray = new ConstantUnion[objectSize];
+				{// support MSVC++6.0
+					for (size_t i = 0; i < objectSize; i++)
+						tempConstArray[i] = unionArray[i] < rightUnionArray[i] ? unionArray[i] : rightUnionArray[i];
+				}
+				break;
+			default:
+				return 0;
+		}
+		tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+		tempNode->setLine(getLine());
 
-        return tempNode;
-    } else {
-        //
-        // Do unary operations
-        //
-        TIntermConstantUnion *newNode = 0;
-        ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++) {
-            switch(op) {
-                case EOpNegative:
-                    switch (getType().getBasicType()) {
-                        case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
-                        case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
-                        default:
-                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
-                            return 0;
-                    }
-                    break;
-                case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
-                    switch (getType().getBasicType()) {
-                        case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
-                        default:
-                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
-                            return 0;
-                    }
-                    break;
-                case EOpBitwiseNot:
-                    switch(getType().getBasicType()) {
-                        case EbtInt: tempConstArray[i].setIConst(~unionArray[i].getIConst()); break;
-                        case EbtUInt: tempConstArray[i].setUConst(~unionArray[i].getUConst()); break;
-                        default:
-                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
-                            return 0;
-                    }
-                    break;
+		return tempNode;
+	} else {
+		//
+		// Do unary operations
+		//
+		TIntermConstantUnion *newNode = 0;
+		ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
+		for (size_t i = 0; i < objectSize; i++) {
+			switch(op) {
+				case EOpNegative:
+					switch (getType().getBasicType()) {
+						case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
+						case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
+						default:
+							infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+							return 0;
+					}
+					break;
+				case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
+					switch (getType().getBasicType()) {
+						case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
+						default:
+							infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+							return 0;
+					}
+					break;
+				case EOpBitwiseNot:
+					switch(getType().getBasicType()) {
+						case EbtInt: tempConstArray[i].setIConst(~unionArray[i].getIConst()); break;
+						case EbtUInt: tempConstArray[i].setUConst(~unionArray[i].getUConst()); break;
+						default:
+							infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+							return 0;
+					}
+					break;
 				case EOpRadians:
 					switch(getType().getBasicType()) {
 					case EbtFloat: tempConstArray[i].setFConst(unionArray[i].getFConst() * 1.74532925e-2f); break;
@@ -1817,108 +1825,108 @@
 					}
 					break;
 				default:
-                    return 0;
-            }
-        }
-        newNode = new TIntermConstantUnion(tempConstArray, getType());
-        newNode->setLine(getLine());
-        return newNode;
-    }
+					return 0;
+			}
+		}
+		newNode = new TIntermConstantUnion(tempConstArray, getType());
+		newNode->setLine(getLine());
+		return newNode;
+	}
 }
 
 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
 {
-    size_t size = node->getType().getObjectSize();
+	size_t size = node->getType().getObjectSize();
 
-    ConstantUnion *leftUnionArray = new ConstantUnion[size];
+	ConstantUnion *leftUnionArray = new ConstantUnion[size];
 
-    for(size_t i = 0; i < size; i++) {
-        switch (promoteTo) {
-            case EbtFloat:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i)));
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getUConst(i)));
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i)));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
-                        return 0;
-                }
-                break;
-            case EbtInt:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i)));
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getUConst(i)));
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i)));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
-                        return 0;
-                }
-                break;
-            case EbtUInt:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getIConst(i)));
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getUConst(i)));
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getBConst(i)));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getFConst(i)));
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
-                        return 0;
-                }
-                break;
-            case EbtBool:
-                switch (node->getType().getBasicType()) {
-                    case EbtInt:
-                        leftUnionArray[i].setBConst(node->getIConst(i) != 0);
-                        break;
-                    case EbtUInt:
-                        leftUnionArray[i].setBConst(node->getUConst(i) != 0);
-                        break;
-                    case EbtBool:
-                        leftUnionArray[i].setBConst(node->getBConst(i));
-                        break;
-                    case EbtFloat:
-                        leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
-                        break;
-                    default:
-                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
-                        return 0;
-                }
+	for(size_t i = 0; i < size; i++) {
+		switch (promoteTo) {
+			case EbtFloat:
+				switch (node->getType().getBasicType()) {
+					case EbtInt:
+						leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i)));
+						break;
+					case EbtUInt:
+						leftUnionArray[i].setFConst(static_cast<float>(node->getUConst(i)));
+						break;
+					case EbtBool:
+						leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i)));
+						break;
+					case EbtFloat:
+						leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+						return 0;
+				}
+				break;
+			case EbtInt:
+				switch (node->getType().getBasicType()) {
+					case EbtInt:
+						leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i)));
+						break;
+					case EbtUInt:
+						leftUnionArray[i].setIConst(static_cast<int>(node->getUConst(i)));
+						break;
+					case EbtBool:
+						leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i)));
+						break;
+					case EbtFloat:
+						leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+						return 0;
+				}
+				break;
+			case EbtUInt:
+				switch (node->getType().getBasicType()) {
+					case EbtInt:
+						leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getIConst(i)));
+						break;
+					case EbtUInt:
+						leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getUConst(i)));
+						break;
+					case EbtBool:
+						leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getBConst(i)));
+						break;
+					case EbtFloat:
+						leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getFConst(i)));
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+						return 0;
+				}
+				break;
+			case EbtBool:
+				switch (node->getType().getBasicType()) {
+					case EbtInt:
+						leftUnionArray[i].setBConst(node->getIConst(i) != 0);
+						break;
+					case EbtUInt:
+						leftUnionArray[i].setBConst(node->getUConst(i) != 0);
+						break;
+					case EbtBool:
+						leftUnionArray[i].setBConst(node->getBConst(i));
+						break;
+					case EbtFloat:
+						leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+						return 0;
+				}
 
-                break;
-            default:
-                infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
-                return 0;
-        }
+				break;
+			default:
+				infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
+				return 0;
+		}
 
-    }
+	}
 
-    const TType& t = node->getType();
+	const TType& t = node->getType();
 
 	return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.getSecondarySize(), t.isArray()), node->getLine());
 }
diff --git a/src/OpenGL/compiler/MMap.h b/src/OpenGL/compiler/MMap.h
index a308671..925cf6e 100644
--- a/src/OpenGL/compiler/MMap.h
+++ b/src/OpenGL/compiler/MMap.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _MMAP_INCLUDED_
 #define _MMAP_INCLUDED_
@@ -13,44 +21,44 @@
 
 class TMMap {
 public:
-    TMMap(const char* fileName) : 
-        fSize(-1), // -1 is the error value returned by GetFileSize()
-        fp(NULL),
-        fBuff(0)   // 0 is the error value returned by MapViewOfFile()
-    {
-        if ((fp = fopen(fileName, "r")) == NULL)
-            return;
-        char c = getc(fp);
-        fSize = 0;
-        while (c != EOF) {
-            fSize++;
-            c = getc(fp);
-        }
-        if (c == EOF)
-            fSize++;
-        rewind(fp);
-        fBuff = (char*)malloc(sizeof(char) * fSize);
-        int count = 0;
-        c = getc(fp);
-        while (c != EOF) {
-            fBuff[count++] = c;
-            c = getc(fp);
-        }
-        fBuff[count++] = c;
-    }
+	TMMap(const char* fileName) :
+		fSize(-1), // -1 is the error value returned by GetFileSize()
+		fp(nullptr),
+		fBuff(0)   // 0 is the error value returned by MapViewOfFile()
+	{
+		if ((fp = fopen(fileName, "r")) == NULL)
+			return;
+		char c = getc(fp);
+		fSize = 0;
+		while (c != EOF) {
+			fSize++;
+			c = getc(fp);
+		}
+		if (c == EOF)
+			fSize++;
+		rewind(fp);
+		fBuff = (char*)malloc(sizeof(char) * fSize);
+		int count = 0;
+		c = getc(fp);
+		while (c != EOF) {
+			fBuff[count++] = c;
+			c = getc(fp);
+		}
+		fBuff[count++] = c;
+	}
 
-    char* getData() { return fBuff; }
-    int   getSize() { return fSize; }
+	char* getData() { return fBuff; }
+	int   getSize() { return fSize; }
 
-    ~TMMap() {
-        if (fp != NULL)
-            fclose(fp);
-    }
-    
+	~TMMap() {
+		if (fp != NULL)
+			fclose(fp);
+	}
+
 private:
-    int             fSize;      // size of file to map in
-    FILE *fp;
-    char*           fBuff;      // the actual data;
+	int             fSize;      // size of file to map in
+	FILE *fp;
+	char*           fBuff;      // the actual data;
 };
 
 #endif // _MMAP_INCLUDED_
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 91f6418..59949f1 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -1,3581 +1,3584 @@
-// 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.

-//

-

-#include "OutputASM.h"

-#include "Common/Math.hpp"

-

-#include "common/debug.h"

-#include "InfoSink.h"

-

-#include "libGLESv2/Shader.h"

-

-#include <GLES2/gl2.h>

-#include <GLES2/gl2ext.h>

-#include <GLES3/gl3.h>

-

-namespace glsl

-{

-	// Integer to TString conversion

-	TString str(int i)

-	{

-		char buffer[20];

-		sprintf(buffer, "%d", i);

-		return buffer;

-	}

-

-	class Temporary : public TIntermSymbol

-	{

-	public:

-		Temporary(OutputASM *assembler) : TIntermSymbol(TSymbolTableLevel::nextUniqueId(), "tmp", TType(EbtFloat, EbpHigh, EvqTemporary, 4, 1, false)), assembler(assembler)

-		{

-		}

-

-		~Temporary()

-		{

-			assembler->freeTemporary(this);

-		}

-

-	private:

-		OutputASM *const assembler;

-	};

-

-	class Constant : public TIntermConstantUnion

-	{

-	public:

-		Constant(float x, float y, float z, float w) : TIntermConstantUnion(constants, TType(EbtFloat, EbpHigh, EvqConstExpr, 4, 1, false))

-		{

-			constants[0].setFConst(x);

-			constants[1].setFConst(y);

-			constants[2].setFConst(z);

-			constants[3].setFConst(w);

-		}

-

-		Constant(bool b) : TIntermConstantUnion(constants, TType(EbtBool, EbpHigh, EvqConstExpr, 1, 1, false))

-		{

-			constants[0].setBConst(b);

-		}

-

-		Constant(int i) : TIntermConstantUnion(constants, TType(EbtInt, EbpHigh, EvqConstExpr, 1, 1, false))

-		{

-			constants[0].setIConst(i);

-		}

-

-		~Constant()

-		{

-		}

-

-	private:

-		ConstantUnion constants[4];

-	};

-

-	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo) :

-		type(type), precision(precision), name(name), arraySize(arraySize), registerIndex(registerIndex), blockId(blockId), blockInfo(blockMemberInfo)

-	{

-	}

-

-	UniformBlock::UniformBlock(const std::string& name, unsigned int dataSize, unsigned int arraySize,

-	                           TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId) :

-		name(name), dataSize(dataSize), arraySize(arraySize), layout(layout),

-		isRowMajorLayout(isRowMajorLayout), registerIndex(registerIndex), blockId(blockId)

-	{

-	}

-

-	BlockLayoutEncoder::BlockLayoutEncoder(bool rowMajor)

-		: mCurrentOffset(0), isRowMajor(rowMajor)

-	{

-	}

-

-	BlockMemberInfo BlockLayoutEncoder::encodeType(const TType &type)

-	{

-		int arrayStride;

-		int matrixStride;

-

-		getBlockLayoutInfo(type, type.getArraySize(), isRowMajor, &arrayStride, &matrixStride);

-

-		const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * BytesPerComponent),

-		                                 static_cast<int>(arrayStride * BytesPerComponent),

-		                                 static_cast<int>(matrixStride * BytesPerComponent),

-		                                 (matrixStride > 0) && isRowMajor);

-

-		advanceOffset(type, type.getArraySize(), isRowMajor, arrayStride, matrixStride);

-

-		return memberInfo;

-	}

-

-	// static

-	size_t BlockLayoutEncoder::getBlockRegister(const BlockMemberInfo &info)

-	{

-		return (info.offset / BytesPerComponent) / ComponentsPerRegister;

-	}

-

-	// static

-	size_t BlockLayoutEncoder::getBlockRegisterElement(const BlockMemberInfo &info)

-	{

-		return (info.offset / BytesPerComponent) % ComponentsPerRegister;

-	}

-

-	void BlockLayoutEncoder::nextRegister()

-	{

-		mCurrentOffset = sw::align(mCurrentOffset, ComponentsPerRegister);

-	}

-

-	Std140BlockEncoder::Std140BlockEncoder(bool rowMajor) : BlockLayoutEncoder(rowMajor)

-	{

-	}

-

-	void Std140BlockEncoder::enterAggregateType()

-	{

-		nextRegister();

-	}

-

-	void Std140BlockEncoder::exitAggregateType()

-	{

-		nextRegister();

-	}

-

-	void Std140BlockEncoder::getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)

-	{

-		size_t baseAlignment = 0;

-		int matrixStride = 0;

-		int arrayStride = 0;

-

-		if(type.isMatrix())

-		{

-			baseAlignment = ComponentsPerRegister;

-			matrixStride = ComponentsPerRegister;

-

-			if(arraySize > 0)

-			{

-				const int numRegisters = isRowMajorMatrix ? type.getSecondarySize() : type.getNominalSize();

-				arrayStride = ComponentsPerRegister * numRegisters;

-			}

-		}

-		else if(arraySize > 0)

-		{

-			baseAlignment = ComponentsPerRegister;

-			arrayStride = ComponentsPerRegister;

-		}

-		else

-		{

-			const size_t numComponents = type.getElementSize();

-			baseAlignment = (numComponents == 3 ? 4u : numComponents);

-		}

-

-		mCurrentOffset = sw::align(mCurrentOffset, baseAlignment);

-

-		*matrixStrideOut = matrixStride;

-		*arrayStrideOut = arrayStride;

-	}

-

-	void Std140BlockEncoder::advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)

-	{

-		if(arraySize > 0)

-		{

-			mCurrentOffset += arrayStride * arraySize;

-		}

-		else if(type.isMatrix())

-		{

-			ASSERT(matrixStride == ComponentsPerRegister);

-			const int numRegisters = isRowMajorMatrix ? type.getSecondarySize() : type.getNominalSize();

-			mCurrentOffset += ComponentsPerRegister * numRegisters;

-		}

-		else

-		{

-			mCurrentOffset += type.getElementSize();

-		}

-	}

-

-	Attribute::Attribute()

-	{

-		type = GL_NONE;

-		arraySize = 0;

-		registerIndex = 0;

-	}

-

-	Attribute::Attribute(GLenum type, const std::string &name, int arraySize, int location, int registerIndex)

-	{

-		this->type = type;

-		this->name = name;

-		this->arraySize = arraySize;

-		this->location = location;

-		this->registerIndex = registerIndex;

-	}

-

-	sw::PixelShader *Shader::getPixelShader() const

-	{

-		return 0;

-	}

-

-	sw::VertexShader *Shader::getVertexShader() const

-	{

-		return 0;

-	}

-

-	OutputASM::TextureFunction::TextureFunction(const TString& nodeName) : method(IMPLICIT), proj(false), offset(false)

-	{

-		TString name = TFunction::unmangleName(nodeName);

-

-		if(name == "texture2D" || name == "textureCube" || name == "texture" || name == "texture3D")

-		{

-			method = IMPLICIT;

-		}

-		else if(name == "texture2DProj" || name == "textureProj")

-		{

-			method = IMPLICIT;

-			proj = true;

-		}

-		else if(name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod")

-		{

-			method = LOD;

-		}

-		else if(name == "texture2DProjLod" || name == "textureProjLod")

-		{

-			method = LOD;

-			proj = true;

-		}

-		else if(name == "textureSize")

-		{

-			method = SIZE;

-		}

-		else if(name == "textureOffset")

-		{

-			method = IMPLICIT;

-			offset = true;

-		}

-		else if(name == "textureProjOffset")

-		{

-			method = IMPLICIT;

-			offset = true;

-			proj = true;

-		}

-		else if(name == "textureLodOffset")

-		{

-			method = LOD;

-			offset = true;

-		}

-		else if(name == "textureProjLodOffset")

-		{

-			method = LOD;

-			proj = true;

-			offset = true;

-		}

-		else if(name == "texelFetch")

-		{

-			method = FETCH;

-		}

-		else if(name == "texelFetchOffset")

-		{

-			method = FETCH;

-			offset = true;

-		}

-		else if(name == "textureGrad")

-		{

-			method = GRAD;

-		}

-		else if(name == "textureGradOffset")

-		{

-			method = GRAD;

-			offset = true;

-		}

-		else if(name == "textureProjGrad")

-		{

-			method = GRAD;

-			proj = true;

-		}

-		else if(name == "textureProjGradOffset")

-		{

-			method = GRAD;

-			proj = true;

-			offset = true;

-		}

-		else UNREACHABLE(0);

-	}

-

-	OutputASM::OutputASM(TParseContext &context, Shader *shaderObject) : TIntermTraverser(true, true, true), shaderObject(shaderObject), mContext(context)

-	{

-		shader = 0;

-		pixelShader = 0;

-		vertexShader = 0;

-

-		if(shaderObject)

-		{

-			shader = shaderObject->getShader();

-			pixelShader = shaderObject->getPixelShader();

-			vertexShader = shaderObject->getVertexShader();

-		}

-

-		functionArray.push_back(Function(0, "main(", 0, 0));

-		currentFunction = 0;

-		outputQualifier = EvqOutput; // Set outputQualifier to any value other than EvqFragColor or EvqFragData

-	}

-

-	OutputASM::~OutputASM()

-	{

-	}

-

-	void OutputASM::output()

-	{

-		if(shader)

-		{

-			emitShader(GLOBAL);

-

-			if(functionArray.size() > 1)   // Only call main() when there are other functions

-			{

-				Instruction *callMain = emit(sw::Shader::OPCODE_CALL);

-				callMain->dst.type = sw::Shader::PARAMETER_LABEL;

-				callMain->dst.index = 0;   // main()

-

-				emit(sw::Shader::OPCODE_RET);

-			}

-

-			emitShader(FUNCTION);

-		}

-	}

-

-	void OutputASM::emitShader(Scope scope)

-	{

-		emitScope = scope;

-		currentScope = GLOBAL;

-		mContext.getTreeRoot()->traverse(this);

-	}

-

-	void OutputASM::freeTemporary(Temporary *temporary)

-	{

-		free(temporaries, temporary);

-	}

-

-	sw::Shader::Opcode OutputASM::getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const

-	{

-		TBasicType baseType = in->getType().getBasicType();

-

-		switch(op)

-		{

-		case sw::Shader::OPCODE_NEG:

-			switch(baseType)

-			{

-			case EbtInt:

-			case EbtUInt:

-				return sw::Shader::OPCODE_INEG;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_ABS:

-			switch(baseType)

-			{

-			case EbtInt:

-				return sw::Shader::OPCODE_IABS;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_SGN:

-			switch(baseType)

-			{

-			case EbtInt:

-				return sw::Shader::OPCODE_ISGN;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_ADD:

-			switch(baseType)

-			{

-			case EbtInt:

-			case EbtUInt:

-				return sw::Shader::OPCODE_IADD;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_SUB:

-			switch(baseType)

-			{

-			case EbtInt:

-			case EbtUInt:

-				return sw::Shader::OPCODE_ISUB;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_MUL:

-			switch(baseType)

-			{

-			case EbtInt:

-			case EbtUInt:

-				return sw::Shader::OPCODE_IMUL;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_DIV:

-			switch(baseType)

-			{

-			case EbtInt:

-				return sw::Shader::OPCODE_IDIV;

-			case EbtUInt:

-				return sw::Shader::OPCODE_UDIV;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_IMOD:

-			return baseType == EbtUInt ? sw::Shader::OPCODE_UMOD : op;

-		case sw::Shader::OPCODE_ISHR:

-			return baseType == EbtUInt ? sw::Shader::OPCODE_USHR : op;

-		case sw::Shader::OPCODE_MIN:

-			switch(baseType)

-			{

-			case EbtInt:

-				return sw::Shader::OPCODE_IMIN;

-			case EbtUInt:

-				return sw::Shader::OPCODE_UMIN;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		case sw::Shader::OPCODE_MAX:

-			switch(baseType)

-			{

-			case EbtInt:

-				return sw::Shader::OPCODE_IMAX;

-			case EbtUInt:

-				return sw::Shader::OPCODE_UMAX;

-			case EbtFloat:

-			default:

-				return op;

-			}

-		default:

-			return op;

-		}

-	}

-

-	void OutputASM::visitSymbol(TIntermSymbol *symbol)

-	{

-		// Vertex varyings don't have to be actively used to successfully link

-		// against pixel shaders that use them. So make sure they're declared.

-		if(symbol->getQualifier() == EvqVaryingOut || symbol->getQualifier() == EvqInvariantVaryingOut || symbol->getQualifier() == EvqVertexOut)

-		{

-			if(symbol->getBasicType() != EbtInvariant)   // Typeless declarations are not new varyings

-			{

-				declareVarying(symbol, -1);

-			}

-		}

-

-		TInterfaceBlock* block = symbol->getType().getInterfaceBlock();

-		// OpenGL ES 3.0.4 spec, section 2.12.6 Uniform Variables:

-		// "All members of a named uniform block declared with a shared or std140 layout qualifier

-		// are considered active, even if they are not referenced in any shader in the program.

-		// The uniform block itself is also considered active, even if no member of the block is referenced."

-		if(block && ((block->blockStorage() == EbsShared) || (block->blockStorage() == EbsStd140)))

-		{

-			uniformRegister(symbol);

-		}

-	}

-

-	bool OutputASM::visitBinary(Visit visit, TIntermBinary *node)

-	{

-		if(currentScope != emitScope)

-		{

-			return false;

-		}

-

-		TIntermTyped *result = node;

-		TIntermTyped *left = node->getLeft();

-		TIntermTyped *right = node->getRight();

-		const TType &leftType = left->getType();

-		const TType &rightType = right->getType();

-		const TType &resultType = node->getType();

-

-		if(isSamplerRegister(result))

-		{

-			return false;   // Don't traverse, the register index is determined statically

-		}

-

-		switch(node->getOp())

-		{

-		case EOpAssign:

-			if(visit == PostVisit)

-			{

-				assignLvalue(left, right);

-				copy(result, right);

-			}

-			break;

-		case EOpInitialize:

-			if(visit == PostVisit)

-			{

-				copy(left, right);

-			}

-			break;

-		case EOpMatrixTimesScalarAssign:

-			if(visit == PostVisit)

-			{

-				for(int i = 0; i < leftType.getNominalSize(); i++)

-				{

-					emit(sw::Shader::OPCODE_MUL, result, i, left, i, right);

-				}

-

-				assignLvalue(left, result);

-			}

-			break;

-		case EOpVectorTimesMatrixAssign:

-			if(visit == PostVisit)

-			{

-				int size = leftType.getNominalSize();

-

-				for(int i = 0; i < size; i++)

-				{

-					Instruction *dot = emit(sw::Shader::OPCODE_DP(size), result, 0, left, 0, right, i);

-					dot->dst.mask = 1 << i;

-				}

-

-				assignLvalue(left, result);

-			}

-			break;

-		case EOpMatrixTimesMatrixAssign:

-			if(visit == PostVisit)

-			{

-				int dim = leftType.getNominalSize();

-

-				for(int i = 0; i < dim; i++)

-				{

-					Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, i, left, 0, right, i);

-					mul->src[1].swizzle = 0x00;

-

-					for(int j = 1; j < dim; j++)

-					{

-						Instruction *mad = emit(sw::Shader::OPCODE_MAD, result, i, left, j, right, i, result, i);

-						mad->src[1].swizzle = j * 0x55;

-					}

-				}

-

-				assignLvalue(left, result);

-			}

-			break;

-		case EOpIndexDirect:

-			if(visit == PostVisit)

-			{

-				int index = right->getAsConstantUnion()->getIConst(0);

-

-				if(result->isMatrix() || result->isStruct() || result->isInterfaceBlock())

- 				{

-					ASSERT(left->isArray());

-					copy(result, left, index * left->elementRegisterCount());

- 				}

-				else if(result->isRegister())

- 				{

-					int srcIndex = 0;

-					if(left->isRegister())

-					{

-						srcIndex = 0;

-					}

-					else if(left->isArray())

-					{

-						srcIndex = index * left->elementRegisterCount();

-					}

-					else if(left->isMatrix())

-					{

-						ASSERT(index < left->getNominalSize());   // FIXME: Report semantic error

-						srcIndex = index;

-					}

-					else UNREACHABLE(0);

-

-					Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, 0, left, srcIndex);

-

-					if(left->isRegister())

-					{

-						mov->src[0].swizzle = index;

-					}

- 				}

-				else UNREACHABLE(0);

-			}

-			break;

-		case EOpIndexIndirect:

-			if(visit == PostVisit)

-			{

-				if(left->isArray() || left->isMatrix())

-				{

-					for(int index = 0; index < result->totalRegisterCount(); index++)

-					{

-						Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, index, left, index);

-						mov->dst.mask = writeMask(result, index);

-

-						if(left->totalRegisterCount() > 1)

-						{

-							sw::Shader::SourceParameter relativeRegister;

-							argument(relativeRegister, right);

-

-							mov->src[0].rel.type = relativeRegister.type;

-							mov->src[0].rel.index = relativeRegister.index;

-							mov->src[0].rel.scale =	result->totalRegisterCount();

-							mov->src[0].rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);

-						}

-					}

-				}

-				else if(left->isRegister())

-				{

-					emit(sw::Shader::OPCODE_EXTRACT, result, left, right);

-				}

-				else UNREACHABLE(0);

-			}

-			break;

-		case EOpIndexDirectStruct:

-		case EOpIndexDirectInterfaceBlock:

-			if(visit == PostVisit)

-			{

-				ASSERT(leftType.isStruct() || (leftType.isInterfaceBlock()));

-

-				const TFieldList& fields = (node->getOp() == EOpIndexDirectStruct) ?

-				                           leftType.getStruct()->fields() :

-				                           leftType.getInterfaceBlock()->fields();

-				int index = right->getAsConstantUnion()->getIConst(0);

-				int fieldOffset = 0;

-

-				for(int i = 0; i < index; i++)

-				{

-					fieldOffset += fields[i]->type()->totalRegisterCount();

-				}

-

-				copy(result, left, fieldOffset);

-			}

-			break;

-		case EOpVectorSwizzle:

-			if(visit == PostVisit)

-			{

-				int swizzle = 0;

-				TIntermAggregate *components = right->getAsAggregate();

-

-				if(components)

-				{

-					TIntermSequence &sequence = components->getSequence();

-					int component = 0;

-

-					for(TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)

-					{

-						TIntermConstantUnion *element = (*sit)->getAsConstantUnion();

-

-						if(element)

-						{

-							int i = element->getUnionArrayPointer()[0].getIConst();

-							swizzle |= i << (component * 2);

-							component++;

-						}

-						else UNREACHABLE(0);

-					}

-				}

-				else UNREACHABLE(0);

-

-				Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, left);

-				mov->src[0].swizzle = swizzle;

-			}

-			break;

-		case EOpAddAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_ADD, result), result, left, left, right); break;

-		case EOpAdd:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_ADD, result), result, left, right);       break;

-		case EOpSubAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_SUB, result), result, left, left, right); break;

-		case EOpSub:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_SUB, result), result, left, right);       break;

-		case EOpMulAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_MUL, result), result, left, left, right); break;

-		case EOpMul:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_MUL, result), result, left, right);       break;

-		case EOpDivAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_DIV, result), result, left, left, right); break;

-		case EOpDiv:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_DIV, result), result, left, right);       break;

-		case EOpIModAssign:          if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_IMOD, result), result, left, left, right); break;

-		case EOpIMod:                if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_IMOD, result), result, left, right);       break;

-		case EOpBitShiftLeftAssign:  if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_SHL, result, left, left, right); break;

-		case EOpBitShiftLeft:        if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_SHL, result, left, right);       break;

-		case EOpBitShiftRightAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_ISHR, result), result, left, left, right); break;

-		case EOpBitShiftRight:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_ISHR, result), result, left, right);       break;

-		case EOpBitwiseAndAssign:    if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_AND, result, left, left, right); break;

-		case EOpBitwiseAnd:          if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_AND, result, left, right);       break;

-		case EOpBitwiseXorAssign:    if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_XOR, result, left, left, right); break;

-		case EOpBitwiseXor:          if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_XOR, result, left, right);       break;

-		case EOpBitwiseOrAssign:     if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_OR, result, left, left, right);  break;

-		case EOpBitwiseOr:           if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_OR, result, left, right);        break;

-		case EOpEqual:

-			if(visit == PostVisit)

-			{

-				emitBinary(sw::Shader::OPCODE_EQ, result, left, right);

-

-				for(int index = 1; index < left->totalRegisterCount(); index++)

-				{

-					Temporary equal(this);

-					emit(sw::Shader::OPCODE_EQ, &equal, 0, left, index, right, index);

-					emit(sw::Shader::OPCODE_AND, result, result, &equal);

-				}

-			}

-			break;

-		case EOpNotEqual:

-			if(visit == PostVisit)

-			{

-				emitBinary(sw::Shader::OPCODE_NE, result, left, right);

-

-				for(int index = 1; index < left->totalRegisterCount(); index++)

-				{

-					Temporary notEqual(this);

-					emit(sw::Shader::OPCODE_NE, &notEqual, 0, left, index, right, index);

-					emit(sw::Shader::OPCODE_OR, result, result, &notEqual);

-				}

-			}

-			break;

-		case EOpLessThan:                if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LT, result, left, right); break;

-		case EOpGreaterThan:             if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GT, result, left, right); break;

-		case EOpLessThanEqual:           if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LE, result, left, right); break;

-		case EOpGreaterThanEqual:        if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GE, result, left, right); break;

-		case EOpVectorTimesScalarAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_MUL, left), result, left, left, right); break;

-		case EOpVectorTimesScalar:       if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MUL, left), result, left, right); break;

-		case EOpMatrixTimesScalar:

-			if(visit == PostVisit)

-			{

-				if(left->isMatrix())

-				{

-					for(int i = 0; i < leftType.getNominalSize(); i++)

-					{

-						emit(sw::Shader::OPCODE_MUL, result, i, left, i, right, 0);

-					}

-				}

-				else if(right->isMatrix())

-				{

-					for(int i = 0; i < rightType.getNominalSize(); i++)

-					{

-						emit(sw::Shader::OPCODE_MUL, result, i, left, 0, right, i);

-					}

-				}

-				else UNREACHABLE(0);

-			}

-			break;

-		case EOpVectorTimesMatrix:

-			if(visit == PostVisit)

-			{

-				sw::Shader::Opcode dpOpcode = sw::Shader::OPCODE_DP(leftType.getNominalSize());

-

-				int size = rightType.getNominalSize();

-				for(int i = 0; i < size; i++)

-				{

-					Instruction *dot = emit(dpOpcode, result, 0, left, 0, right, i);

-					dot->dst.mask = 1 << i;

-				}

-			}

-			break;

-		case EOpMatrixTimesVector:

-			if(visit == PostVisit)

-			{

-				Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, left, right);

-				mul->src[1].swizzle = 0x00;

-

-				int size = rightType.getNominalSize();

-				for(int i = 1; i < size; i++)

-				{

-					Instruction *mad = emit(sw::Shader::OPCODE_MAD, result, 0, left, i, right, 0, result);

-					mad->src[1].swizzle = i * 0x55;

-				}

-			}

-			break;

-		case EOpMatrixTimesMatrix:

-			if(visit == PostVisit)

-			{

-				int dim = leftType.getNominalSize();

-

-				int size = rightType.getNominalSize();

-				for(int i = 0; i < size; i++)

-				{

-					Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, i, left, 0, right, i);

-					mul->src[1].swizzle = 0x00;

-

-					for(int j = 1; j < dim; j++)

-					{

-						Instruction *mad = emit(sw::Shader::OPCODE_MAD, result, i, left, j, right, i, result, i);

-						mad->src[1].swizzle = j * 0x55;

-					}

-				}

-			}

-			break;

-		case EOpLogicalOr:

-			if(trivial(right, 6))

-			{

-				if(visit == PostVisit)

-				{

-					emit(sw::Shader::OPCODE_OR, result, left, right);

-				}

-			}

-			else   // Short-circuit evaluation

-			{

-				if(visit == InVisit)

-				{

-					emit(sw::Shader::OPCODE_MOV, result, left);

-					Instruction *ifnot = emit(sw::Shader::OPCODE_IF, 0, result);

-					ifnot->src[0].modifier = sw::Shader::MODIFIER_NOT;

-				}

-				else if(visit == PostVisit)

-				{

-					emit(sw::Shader::OPCODE_MOV, result, right);

-					emit(sw::Shader::OPCODE_ENDIF);

-				}

-			}

-			break;

-		case EOpLogicalXor:        if(visit == PostVisit) emit(sw::Shader::OPCODE_XOR, result, left, right); break;

-		case EOpLogicalAnd:

-			if(trivial(right, 6))

-			{

-				if(visit == PostVisit)

-				{

-					emit(sw::Shader::OPCODE_AND, result, left, right);

-				}

-			}

-			else   // Short-circuit evaluation

-			{

-				if(visit == InVisit)

-				{

-					emit(sw::Shader::OPCODE_MOV, result, left);

-					emit(sw::Shader::OPCODE_IF, 0, result);

-				}

-				else if(visit == PostVisit)

-				{

-					emit(sw::Shader::OPCODE_MOV, result, right);

-					emit(sw::Shader::OPCODE_ENDIF);

-				}

-			}

-			break;

-		default: UNREACHABLE(node->getOp());

-		}

-

-		return true;

-	}

-

-	void OutputASM::emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col, int row, int outCol, int outRow)

-	{

-		switch(size)

-		{

-		case 1: // Used for cofactor computation only

-			{

-				// For a 2x2 matrix, the cofactor is simply a transposed move or negate

-				bool isMov = (row == col);

-				sw::Shader::Opcode op = isMov ? sw::Shader::OPCODE_MOV : sw::Shader::OPCODE_NEG;

-				Instruction *mov = emit(op, result, outCol, arg, isMov ? 1 - row : row);

-				mov->src[0].swizzle = 0x55 * (isMov ? 1 - col : col);

-				mov->dst.mask = 1 << outRow;

-			}

-			break;

-		case 2:

-			{

-				static const unsigned int swizzle[3] = { 0x99, 0x88, 0x44 }; // xy?? : yzyz, xzxz, xyxy

-

-				bool isCofactor = (col >= 0) && (row >= 0);

-				int col0 = (isCofactor && (col <= 0)) ? 1 : 0;

-				int col1 = (isCofactor && (col <= 1)) ? 2 : 1;

-				bool negate = isCofactor && ((col & 0x01) ^ (row & 0x01));

-

-				Instruction *det = emit(sw::Shader::OPCODE_DET2, result, outCol, arg, negate ? col1 : col0, arg, negate ? col0 : col1);

-				det->src[0].swizzle = det->src[1].swizzle = swizzle[isCofactor ? row : 2];

-				det->dst.mask = 1 << outRow;

-			}

-			break;

-		case 3:

-			{

-				static const unsigned int swizzle[4] = { 0xF9, 0xF8, 0xF4, 0xE4 }; // xyz? : yzww, xzww, xyww, xyzw

-

-				bool isCofactor = (col >= 0) && (row >= 0);

-				int col0 = (isCofactor && (col <= 0)) ? 1 : 0;

-				int col1 = (isCofactor && (col <= 1)) ? 2 : 1;

-				int col2 = (isCofactor && (col <= 2)) ? 3 : 2;

-				bool negate = isCofactor && ((col & 0x01) ^ (row & 0x01));

-

-				Instruction *det = emit(sw::Shader::OPCODE_DET3, result, outCol, arg, col0, arg, negate ? col2 : col1, arg, negate ? col1 : col2);

-				det->src[0].swizzle = det->src[1].swizzle = det->src[2].swizzle = swizzle[isCofactor ? row : 3];

-				det->dst.mask = 1 << outRow;

-			}

-			break;

-		case 4:

-			{

-				Instruction *det = emit(sw::Shader::OPCODE_DET4, result, outCol, arg, 0, arg, 1, arg, 2, arg, 3);

-				det->dst.mask = 1 << outRow;

-			}

-			break;

-		default:

-			UNREACHABLE(size);

-			break;

-		}

-	}

-

-	bool OutputASM::visitUnary(Visit visit, TIntermUnary *node)

-	{

-		if(currentScope != emitScope)

-		{

-			return false;

-		}

-

-		TIntermTyped *result = node;

-		TIntermTyped *arg = node->getOperand();

-		TBasicType basicType = arg->getType().getBasicType();

-

-		union

-		{

-			float f;

-			int i;

-		} one_value;

-

-		if(basicType == EbtInt || basicType == EbtUInt)

-		{

-			one_value.i = 1;

-		}

-		else

-		{

-			one_value.f = 1.0f;

-		}

-

-		Constant one(one_value.f, one_value.f, one_value.f, one_value.f);

-		Constant rad(1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f);

-		Constant deg(5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f);

-

-		switch(node->getOp())

-		{

-		case EOpNegative:

-			if(visit == PostVisit)

-			{

-				sw::Shader::Opcode negOpcode = getOpcode(sw::Shader::OPCODE_NEG, arg);

-				for(int index = 0; index < arg->totalRegisterCount(); index++)

-				{

-					emit(negOpcode, result, index, arg, index);

-				}

-			}

-			break;

-		case EOpVectorLogicalNot: if(visit == PostVisit) emit(sw::Shader::OPCODE_NOT, result, arg); break;

-		case EOpLogicalNot:       if(visit == PostVisit) emit(sw::Shader::OPCODE_NOT, result, arg); break;

-		case EOpPostIncrement:

-			if(visit == PostVisit)

-			{

-				copy(result, arg);

-

-				sw::Shader::Opcode addOpcode = getOpcode(sw::Shader::OPCODE_ADD, arg);

-				for(int index = 0; index < arg->totalRegisterCount(); index++)

-				{

-					emit(addOpcode, arg, index, arg, index, &one);

-				}

-

-				assignLvalue(arg, arg);

-			}

-			break;

-		case EOpPostDecrement:

-			if(visit == PostVisit)

-			{

-				copy(result, arg);

-

-				sw::Shader::Opcode subOpcode = getOpcode(sw::Shader::OPCODE_SUB, arg);

-				for(int index = 0; index < arg->totalRegisterCount(); index++)

-				{

-					emit(subOpcode, arg, index, arg, index, &one);

-				}

-

-				assignLvalue(arg, arg);

-			}

-			break;

-		case EOpPreIncrement:

-			if(visit == PostVisit)

-			{

-				sw::Shader::Opcode addOpcode = getOpcode(sw::Shader::OPCODE_ADD, arg);

-				for(int index = 0; index < arg->totalRegisterCount(); index++)

-				{

-					emit(addOpcode, result, index, arg, index, &one);

-				}

-

-				assignLvalue(arg, result);

-			}

-			break;

-		case EOpPreDecrement:

-			if(visit == PostVisit)

-			{

-				sw::Shader::Opcode subOpcode = getOpcode(sw::Shader::OPCODE_SUB, arg);

-				for(int index = 0; index < arg->totalRegisterCount(); index++)

-				{

-					emit(subOpcode, result, index, arg, index, &one);

-				}

-

-				assignLvalue(arg, result);

-			}

-			break;

-		case EOpRadians:          if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, arg, &rad); break;

-		case EOpDegrees:          if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, arg, &deg); break;

-		case EOpSin:              if(visit == PostVisit) emit(sw::Shader::OPCODE_SIN, result, arg); break;

-		case EOpCos:              if(visit == PostVisit) emit(sw::Shader::OPCODE_COS, result, arg); break;

-		case EOpTan:              if(visit == PostVisit) emit(sw::Shader::OPCODE_TAN, result, arg); break;

-		case EOpAsin:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ASIN, result, arg); break;

-		case EOpAcos:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ACOS, result, arg); break;

-		case EOpAtan:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ATAN, result, arg); break;

-		case EOpSinh:             if(visit == PostVisit) emit(sw::Shader::OPCODE_SINH, result, arg); break;

-		case EOpCosh:             if(visit == PostVisit) emit(sw::Shader::OPCODE_COSH, result, arg); break;

-		case EOpTanh:             if(visit == PostVisit) emit(sw::Shader::OPCODE_TANH, result, arg); break;

-		case EOpAsinh:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ASINH, result, arg); break;

-		case EOpAcosh:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ACOSH, result, arg); break;

-		case EOpAtanh:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ATANH, result, arg); break;

-		case EOpExp:              if(visit == PostVisit) emit(sw::Shader::OPCODE_EXP, result, arg); break;

-		case EOpLog:              if(visit == PostVisit) emit(sw::Shader::OPCODE_LOG, result, arg); break;

-		case EOpExp2:             if(visit == PostVisit) emit(sw::Shader::OPCODE_EXP2, result, arg); break;

-		case EOpLog2:             if(visit == PostVisit) emit(sw::Shader::OPCODE_LOG2, result, arg); break;

-		case EOpSqrt:             if(visit == PostVisit) emit(sw::Shader::OPCODE_SQRT, result, arg); break;

-		case EOpInverseSqrt:      if(visit == PostVisit) emit(sw::Shader::OPCODE_RSQ, result, arg); break;

-		case EOpAbs:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_ABS, result), result, arg); break;

-		case EOpSign:             if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_SGN, result), result, arg); break;

-		case EOpFloor:            if(visit == PostVisit) emit(sw::Shader::OPCODE_FLOOR, result, arg); break;

-		case EOpTrunc:            if(visit == PostVisit) emit(sw::Shader::OPCODE_TRUNC, result, arg); break;

-		case EOpRound:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ROUND, result, arg); break;

-		case EOpRoundEven:        if(visit == PostVisit) emit(sw::Shader::OPCODE_ROUNDEVEN, result, arg); break;

-		case EOpCeil:             if(visit == PostVisit) emit(sw::Shader::OPCODE_CEIL, result, arg, result); break;

-		case EOpFract:            if(visit == PostVisit) emit(sw::Shader::OPCODE_FRC, result, arg); break;

-		case EOpIsNan:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ISNAN, result, arg); break;

-		case EOpIsInf:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ISINF, result, arg); break;

-		case EOpLength:           if(visit == PostVisit) emit(sw::Shader::OPCODE_LEN(dim(arg)), result, arg); break;

-		case EOpNormalize:        if(visit == PostVisit) emit(sw::Shader::OPCODE_NRM(dim(arg)), result, arg); break;

-		case EOpDFdx:             if(visit == PostVisit) emit(sw::Shader::OPCODE_DFDX, result, arg); break;

-		case EOpDFdy:             if(visit == PostVisit) emit(sw::Shader::OPCODE_DFDY, result, arg); break;

-		case EOpFwidth:           if(visit == PostVisit) emit(sw::Shader::OPCODE_FWIDTH, result, arg); break;

-		case EOpAny:              if(visit == PostVisit) emit(sw::Shader::OPCODE_ANY, result, arg); break;

-		case EOpAll:              if(visit == PostVisit) emit(sw::Shader::OPCODE_ALL, result, arg); break;

-		case EOpFloatBitsToInt:   if(visit == PostVisit) emit(sw::Shader::OPCODE_FLOATBITSTOINT, result, arg); break;

-		case EOpFloatBitsToUint:  if(visit == PostVisit) emit(sw::Shader::OPCODE_FLOATBITSTOUINT, result, arg); break;

-		case EOpIntBitsToFloat:   if(visit == PostVisit) emit(sw::Shader::OPCODE_INTBITSTOFLOAT, result, arg); break;

-		case EOpUintBitsToFloat:  if(visit == PostVisit) emit(sw::Shader::OPCODE_UINTBITSTOFLOAT, result, arg); break;

-		case EOpPackSnorm2x16:    if(visit == PostVisit) emit(sw::Shader::OPCODE_PACKSNORM2x16, result, arg); break;

-		case EOpPackUnorm2x16:    if(visit == PostVisit) emit(sw::Shader::OPCODE_PACKUNORM2x16, result, arg); break;

-		case EOpPackHalf2x16:     if(visit == PostVisit) emit(sw::Shader::OPCODE_PACKHALF2x16, result, arg); break;

-		case EOpUnpackSnorm2x16:  if(visit == PostVisit) emit(sw::Shader::OPCODE_UNPACKSNORM2x16, result, arg); break;

-		case EOpUnpackUnorm2x16:  if(visit == PostVisit) emit(sw::Shader::OPCODE_UNPACKUNORM2x16, result, arg); break;

-		case EOpUnpackHalf2x16:   if(visit == PostVisit) emit(sw::Shader::OPCODE_UNPACKHALF2x16, result, arg); break;

-		case EOpTranspose:

-			if(visit == PostVisit)

-			{

-				int numCols = arg->getNominalSize();

-				int numRows = arg->getSecondarySize();

-				for(int i = 0; i < numCols; ++i)

-				{

-					for(int j = 0; j < numRows; ++j)

-					{

-						Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, j, arg, i);

-						mov->src[0].swizzle = 0x55 * j;

-						mov->dst.mask = 1 << i;

-					}

-				}

-			}

-			break;

-		case EOpDeterminant:

-			if(visit == PostVisit)

-			{

-				int size = arg->getNominalSize();

-				ASSERT(size == arg->getSecondarySize());

-

-				emitDeterminant(result, arg, size);

-			}

-			break;

-		case EOpInverse:

-			if(visit == PostVisit)

-			{

-				int size = arg->getNominalSize();

-				ASSERT(size == arg->getSecondarySize());

-

-				// Compute transposed matrix of cofactors

-				for(int i = 0; i < size; ++i)

-				{

-					for(int j = 0; j < size; ++j)

-					{

-						// For a 2x2 matrix, the cofactor is simply a transposed move or negate

-						// For a 3x3 or 4x4 matrix, the cofactor is a transposed determinant

-						emitDeterminant(result, arg, size - 1, j, i, i, j);

-					}

-				}

-

-				// Compute 1 / determinant

-				Temporary invDet(this);

-				emitDeterminant(&invDet, arg, size);

-				Constant one(1.0f, 1.0f, 1.0f, 1.0f);

-				Instruction *div = emit(sw::Shader::OPCODE_DIV, &invDet, &one, &invDet);

-				div->src[1].swizzle = 0x00; // xxxx

-

-				// Divide transposed matrix of cofactors by determinant

-				for(int i = 0; i < size; ++i)

-				{

-					emit(sw::Shader::OPCODE_MUL, result, i, result, i, &invDet);

-				}

-			}

-			break;

-		default: UNREACHABLE(node->getOp());

-		}

-

-		return true;

-	}

-

-	bool OutputASM::visitAggregate(Visit visit, TIntermAggregate *node)

-	{

-		if(currentScope != emitScope && node->getOp() != EOpFunction && node->getOp() != EOpSequence)

-		{

-			return false;

-		}

-

-		Constant zero(0.0f, 0.0f, 0.0f, 0.0f);

-

-		TIntermTyped *result = node;

-		const TType &resultType = node->getType();

-		TIntermSequence &arg = node->getSequence();

-		size_t argumentCount = arg.size();

-

-		switch(node->getOp())

-		{

-		case EOpSequence:             break;

-		case EOpDeclaration:          break;

-		case EOpInvariantDeclaration: break;

-		case EOpPrototype:            break;

-		case EOpComma:

-			if(visit == PostVisit)

-			{

-				copy(result, arg[1]);

-			}

-			break;

-		case EOpFunction:

-			if(visit == PreVisit)

-			{

-				const TString &name = node->getName();

-

-				if(emitScope == FUNCTION)

-				{

-					if(functionArray.size() > 1)   // No need for a label when there's only main()

-					{

-						Instruction *label = emit(sw::Shader::OPCODE_LABEL);

-						label->dst.type = sw::Shader::PARAMETER_LABEL;

-

-						const Function *function = findFunction(name);

-						ASSERT(function);   // Should have been added during global pass

-						label->dst.index = function->label;

-						currentFunction = function->label;

-					}

-				}

-				else if(emitScope == GLOBAL)

-				{

-					if(name != "main(")

-					{

-						TIntermSequence &arguments = node->getSequence()[0]->getAsAggregate()->getSequence();

-						functionArray.push_back(Function(functionArray.size(), name, &arguments, node));

-					}

-				}

-				else UNREACHABLE(emitScope);

-

-				currentScope = FUNCTION;

-			}

-			else if(visit == PostVisit)

-			{

-				if(emitScope == FUNCTION)

-				{

-					if(functionArray.size() > 1)   // No need to return when there's only main()

-					{

-						emit(sw::Shader::OPCODE_RET);

-					}

-				}

-

-				currentScope = GLOBAL;

-			}

-			break;

-		case EOpFunctionCall:

-			if(visit == PostVisit)

-			{

-				if(node->isUserDefined())

-				{

-					const TString &name = node->getName();

-					const Function *function = findFunction(name);

-

-					if(!function)

-					{

-						mContext.error(node->getLine(), "function definition not found", name.c_str());

-						return false;

-					}

-

-					TIntermSequence &arguments = *function->arg;

-

-					for(size_t i = 0; i < argumentCount; i++)

-					{

-						TIntermTyped *in = arguments[i]->getAsTyped();

-

-						if(in->getQualifier() == EvqIn ||

-						   in->getQualifier() == EvqInOut ||

-						   in->getQualifier() == EvqConstReadOnly)

-						{

-							copy(in, arg[i]);

-						}

-					}

-

-					Instruction *call = emit(sw::Shader::OPCODE_CALL);

-					call->dst.type = sw::Shader::PARAMETER_LABEL;

-					call->dst.index = function->label;

-

-					if(function->ret && function->ret->getType().getBasicType() != EbtVoid)

-					{

-						copy(result, function->ret);

-					}

-

-					for(size_t i = 0; i < argumentCount; i++)

-					{

-						TIntermTyped *argument = arguments[i]->getAsTyped();

-						TIntermTyped *out = arg[i]->getAsTyped();

-

-						if(argument->getQualifier() == EvqOut ||

-						   argument->getQualifier() == EvqInOut)

-						{

-							copy(out, argument);

-						}

-					}

-				}

-				else

-				{

-					const TextureFunction textureFunction(node->getName());

-					TIntermTyped *t = arg[1]->getAsTyped();

-

-					Temporary coord(this);

-

-					if(textureFunction.proj)

-					{

-						TIntermConstantUnion* constant = arg[1]->getAsConstantUnion();

-						if(constant)

-						{

-							float projFactor = 1.0f / constant->getFConst(t->getNominalSize() - 1);

-							Constant projCoord(constant->getFConst(0) * projFactor,

-							                   constant->getFConst(1) * projFactor,

-							                   constant->getFConst(2) * projFactor,

-							                   0.0f);

-							emit(sw::Shader::OPCODE_MOV, &coord, &projCoord);

-						}

-						else

-						{

-							Instruction *rcp = emit(sw::Shader::OPCODE_RCPX, &coord, arg[1]);

-							rcp->src[0].swizzle = 0x55 * (t->getNominalSize() - 1);

-							rcp->dst.mask = 0x7;

-

-							Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);

-							mul->dst.mask = 0x7;

-						}

-					}

-					else

-					{

-						emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);

-					}

-

-					switch(textureFunction.method)

-					{

-					case TextureFunction::IMPLICIT:

-						{

-							TIntermNode* offset = textureFunction.offset ? arg[2] : 0;

-

-							if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))

-							{

-								Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,

-								                        result, &coord, arg[0], offset);

-							}

-							else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))   // bias

-							{

-								Instruction *bias = emit(sw::Shader::OPCODE_MOV, &coord, arg[textureFunction.offset ? 3 : 2]);

-								bias->dst.mask = 0x8;

-

-								Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,

-								                        result, &coord, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction

-								tex->bias = true;

-							}

-							else UNREACHABLE(argumentCount);

-						}

-						break;

-					case TextureFunction::LOD:

-						{

-							Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);

-							lod->dst.mask = 0x8;

-

-							emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL,

-							     result, &coord, arg[0], textureFunction.offset ? arg[3] : nullptr);

-						}

-						break;

-					case TextureFunction::FETCH:

-						{

-							if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))

-							{

-								TIntermNode *offset = textureFunction.offset ? arg[3] : nullptr;

-

-								emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH,

-								     result, arg[1], arg[0], arg[2], offset);

-							}

-							else UNREACHABLE(argumentCount);

-						}

-						break;

-					case TextureFunction::GRAD:

-						{

-							if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5))

-							{

-								TIntermNode *offset = textureFunction.offset ? arg[4] : nullptr;

-

-								emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD,

-								     result, &coord, arg[0], arg[2], arg[3], offset);

-							}

-							else UNREACHABLE(argumentCount);

-						}

-						break;

-					case TextureFunction::SIZE:

-						emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], arg[0]);

-						break;

-					default:

-						UNREACHABLE(textureFunction.method);

-					}

-				}

-			}

-			break;

-		case EOpParameters:

-			break;

-		case EOpConstructFloat:

-		case EOpConstructVec2:

-		case EOpConstructVec3:

-		case EOpConstructVec4:

-		case EOpConstructBool:

-		case EOpConstructBVec2:

-		case EOpConstructBVec3:

-		case EOpConstructBVec4:

-		case EOpConstructInt:

-		case EOpConstructIVec2:

-		case EOpConstructIVec3:

-		case EOpConstructIVec4:

-		case EOpConstructUInt:

-		case EOpConstructUVec2:

-		case EOpConstructUVec3:

-		case EOpConstructUVec4:

-			if(visit == PostVisit)

-			{

-				int component = 0;

-

-				for(size_t i = 0; i < argumentCount; i++)

-				{

-					TIntermTyped *argi = arg[i]->getAsTyped();

-					int size = argi->getNominalSize();

-

-					if(!argi->isMatrix())

-					{

-						Instruction *mov = emitCast(result, argi);

-						mov->dst.mask = (0xF << component) & 0xF;

-						mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);

-

-						component += size;

-					}

-					else   // Matrix

-					{

-						int column = 0;

-

-						while(component < resultType.getNominalSize())

-						{

-							Instruction *mov = emitCast(result, 0, argi, column);

-							mov->dst.mask = (0xF << component) & 0xF;

-							mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);

-

-							column++;

-							component += size;

-						}

-					}

-				}

-			}

-			break;

-		case EOpConstructMat2:

-		case EOpConstructMat2x3:

-		case EOpConstructMat2x4:

-		case EOpConstructMat3x2:

-		case EOpConstructMat3:

-		case EOpConstructMat3x4:

-		case EOpConstructMat4x2:

-		case EOpConstructMat4x3:

-		case EOpConstructMat4:

-			if(visit == PostVisit)

-			{

-				TIntermTyped *arg0 = arg[0]->getAsTyped();

-				const int outCols = result->getNominalSize();

-				const int outRows = result->getSecondarySize();

-

-				if(arg0->isScalar() && arg.size() == 1)   // Construct scale matrix

-				{

-					for(int i = 0; i < outCols; i++)

-					{

-						Instruction *init = emit(sw::Shader::OPCODE_MOV, result, i, &zero);

-						Instruction *mov = emitCast(result, i, arg0, 0);

-						mov->dst.mask = 1 << i;

-						ASSERT(mov->src[0].swizzle == 0x00);

-					}

-				}

-				else if(arg0->isMatrix())

-				{

-					const int inCols = arg0->getNominalSize();

-					const int inRows = arg0->getSecondarySize();

-

-					for(int i = 0; i < outCols; i++)

-					{

-						if(i >= inCols || outRows > inRows)

-						{

-							// Initialize to identity matrix

-							Constant col((i == 0 ? 1.0f : 0.0f), (i == 1 ? 1.0f : 0.0f), (i == 2 ? 1.0f : 0.0f), (i == 3 ? 1.0f : 0.0f));

-							Instruction *mov = emitCast(result, i, &col, 0);

-						}

-

-						if(i < inCols)

-						{

-							Instruction *mov = emitCast(result, i, arg0, i);

-							mov->dst.mask = 0xF >> (4 - inRows);

-						}

-					}

-				}

-				else

-				{

-					int column = 0;

-					int row = 0;

-

-					for(size_t i = 0; i < argumentCount; i++)

-					{

-						TIntermTyped *argi = arg[i]->getAsTyped();

-						int size = argi->getNominalSize();

-						int element = 0;

-

-						while(element < size)

-						{

-							Instruction *mov = emitCast(result, column, argi, 0);

-							mov->dst.mask = (0xF << row) & 0xF;

-							mov->src[0].swizzle = (readSwizzle(argi, size) << (row * 2)) + 0x55 * element;

-

-							int end = row + size - element;

-							column = end >= outRows ? column + 1 : column;

-							element = element + outRows - row;

-							row = end >= outRows ? 0 : end;

-						}

-					}

-				}

-			}

-			break;

-		case EOpConstructStruct:

-			if(visit == PostVisit)

-			{

-				int offset = 0;

-				for(size_t i = 0; i < argumentCount; i++)

-				{

-					TIntermTyped *argi = arg[i]->getAsTyped();

-					int size = argi->totalRegisterCount();

-

-					for(int index = 0; index < size; index++)

-					{

-						Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, index + offset, argi, index);

-						mov->dst.mask = writeMask(result, offset + index);

-					}

-

-					offset += size;

-				}

-			}

-			break;

-		case EOpLessThan:         if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LT, result, arg[0], arg[1]); break;

-		case EOpGreaterThan:      if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GT, result, arg[0], arg[1]); break;

-		case EOpLessThanEqual:    if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LE, result, arg[0], arg[1]); break;

-		case EOpGreaterThanEqual: if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GE, result, arg[0], arg[1]); break;

-		case EOpVectorEqual:      if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_EQ, result, arg[0], arg[1]); break;

-		case EOpVectorNotEqual:   if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_NE, result, arg[0], arg[1]); break;

-		case EOpMod:              if(visit == PostVisit) emit(sw::Shader::OPCODE_MOD, result, arg[0], arg[1]); break;

-		case EOpModf:

-			if(visit == PostVisit)

-			{

-				TIntermTyped* arg1 = arg[1]->getAsTyped();

-				emit(sw::Shader::OPCODE_TRUNC, arg1, arg[0]);

-				assignLvalue(arg1, arg1);

-				emitBinary(sw::Shader::OPCODE_SUB, result, arg[0], arg1);

-			}

-			break;

-		case EOpPow:              if(visit == PostVisit) emit(sw::Shader::OPCODE_POW, result, arg[0], arg[1]); break;

-		case EOpAtan:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ATAN2, result, arg[0], arg[1]); break;

-		case EOpMin:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, arg[0], arg[1]); break;

-		case EOpMax:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MAX, result), result, arg[0], arg[1]); break;

-		case EOpClamp:

-			if(visit == PostVisit)

-			{

-				emit(getOpcode(sw::Shader::OPCODE_MAX, result), result, arg[0], arg[1]);

-				emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, result, arg[2]);

-			}

-			break;

-		case EOpMix:         if(visit == PostVisit) emit(sw::Shader::OPCODE_LRP, result, arg[2], arg[1], arg[0]); break;

-		case EOpStep:        if(visit == PostVisit) emit(sw::Shader::OPCODE_STEP, result, arg[0], arg[1]); break;

-		case EOpSmoothStep:  if(visit == PostVisit) emit(sw::Shader::OPCODE_SMOOTH, result, arg[0], arg[1], arg[2]); break;

-		case EOpDistance:    if(visit == PostVisit) emit(sw::Shader::OPCODE_DIST(dim(arg[0])), result, arg[0], arg[1]); break;

-		case EOpDot:         if(visit == PostVisit) emit(sw::Shader::OPCODE_DP(dim(arg[0])), result, arg[0], arg[1]); break;

-		case EOpCross:       if(visit == PostVisit) emit(sw::Shader::OPCODE_CRS, result, arg[0], arg[1]); break;

-		case EOpFaceForward: if(visit == PostVisit) emit(sw::Shader::OPCODE_FORWARD(dim(arg[0])), result, arg[0], arg[1], arg[2]); break;

-		case EOpReflect:     if(visit == PostVisit) emit(sw::Shader::OPCODE_REFLECT(dim(arg[0])), result, arg[0], arg[1]); break;

-		case EOpRefract:     if(visit == PostVisit) emit(sw::Shader::OPCODE_REFRACT(dim(arg[0])), result, arg[0], arg[1], arg[2]); break;

-		case EOpMul:

-			if(visit == PostVisit)

-			{

-				TIntermTyped *arg0 = arg[0]->getAsTyped();

-				TIntermTyped *arg1 = arg[1]->getAsTyped();

-				ASSERT((arg0->getNominalSize() == arg1->getNominalSize()) && (arg0->getSecondarySize() == arg1->getSecondarySize()));

-

-				int size = arg0->getNominalSize();

-				for(int i = 0; i < size; i++)

-				{

-					emit(sw::Shader::OPCODE_MUL, result, i, arg[0], i, arg[1], i);

-				}

-			}

-			break;

-		case EOpOuterProduct:

-			if(visit == PostVisit)

-			{

-				for(int i = 0; i < dim(arg[1]); i++)

-				{

-					Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, i, arg[0], 0, arg[1]);

-					mul->src[1].swizzle = 0x55 * i;

-				}

-			}

-			break;

-		default: UNREACHABLE(node->getOp());

-		}

-

-		return true;

-	}

-

-	bool OutputASM::visitSelection(Visit visit, TIntermSelection *node)

-	{

-		if(currentScope != emitScope)

-		{

-			return false;

-		}

-

-		TIntermTyped *condition = node->getCondition();

-		TIntermNode *trueBlock = node->getTrueBlock();

-		TIntermNode *falseBlock = node->getFalseBlock();

-		TIntermConstantUnion *constantCondition = condition->getAsConstantUnion();

-

-		condition->traverse(this);

-

-		if(node->usesTernaryOperator())

-		{

-			if(constantCondition)

-			{

-				bool trueCondition = constantCondition->getUnionArrayPointer()->getBConst();

-

-				if(trueCondition)

-				{

-					trueBlock->traverse(this);

-					copy(node, trueBlock);

-				}

-				else

-				{

-					falseBlock->traverse(this);

-					copy(node, falseBlock);

-				}

-			}

-			else if(trivial(node, 6))   // Fast to compute both potential results and no side effects

-			{

-				trueBlock->traverse(this);

-				falseBlock->traverse(this);

-				emit(sw::Shader::OPCODE_SELECT, node, condition, trueBlock, falseBlock);

-			}

-			else

-			{

-				emit(sw::Shader::OPCODE_IF, 0, condition);

-

-				if(trueBlock)

-				{

-					trueBlock->traverse(this);

-					copy(node, trueBlock);

-				}

-

-				if(falseBlock)

-				{

-					emit(sw::Shader::OPCODE_ELSE);

-					falseBlock->traverse(this);

-					copy(node, falseBlock);

-				}

-

-				emit(sw::Shader::OPCODE_ENDIF);

-			}

-		}

-		else  // if/else statement

-		{

-			if(constantCondition)

-			{

-				bool trueCondition = constantCondition->getUnionArrayPointer()->getBConst();

-

-				if(trueCondition)

-				{

-					if(trueBlock)

-					{

-						trueBlock->traverse(this);

-					}

-				}

-				else

-				{

-					if(falseBlock)

-					{

-						falseBlock->traverse(this);

-					}

-				}

-			}

-			else

-			{

-				emit(sw::Shader::OPCODE_IF, 0, condition);

-

-				if(trueBlock)

-				{

-					trueBlock->traverse(this);

-				}

-

-				if(falseBlock)

-				{

-					emit(sw::Shader::OPCODE_ELSE);

-					falseBlock->traverse(this);

-				}

-

-				emit(sw::Shader::OPCODE_ENDIF);

-			}

-		}

-

-		return false;

-	}

-

-	bool OutputASM::visitLoop(Visit visit, TIntermLoop *node)

-	{

-		if(currentScope != emitScope)

-		{

-			return false;

-		}

-

-		unsigned int iterations = loopCount(node);

-

-		if(iterations == 0)

-		{

-			return false;

-		}

-

-		bool unroll = (iterations <= 4);

-

-		if(unroll)

-		{

-			LoopUnrollable loopUnrollable;

-			unroll = loopUnrollable.traverse(node);

-		}

-

-		TIntermNode *init = node->getInit();

-		TIntermTyped *condition = node->getCondition();

-		TIntermTyped *expression = node->getExpression();

-		TIntermNode *body = node->getBody();

-		Constant True(true);

-

-		if(node->getType() == ELoopDoWhile)

-		{

-			Temporary iterate(this);

-			emit(sw::Shader::OPCODE_MOV, &iterate, &True);

-

-			emit(sw::Shader::OPCODE_WHILE, 0, &iterate);   // FIXME: Implement real do-while

-

-			if(body)

-			{

-				body->traverse(this);

-			}

-

-			emit(sw::Shader::OPCODE_TEST);

-

-			condition->traverse(this);

-			emit(sw::Shader::OPCODE_MOV, &iterate, condition);

-

-			emit(sw::Shader::OPCODE_ENDWHILE);

-		}

-		else

-		{

-			if(init)

-			{

-				init->traverse(this);

-			}

-

-			if(unroll)

-			{

-				for(unsigned int i = 0; i < iterations; i++)

-				{

-				//	condition->traverse(this);   // Condition could contain statements, but not in an unrollable loop

-

-					if(body)

-					{

-						body->traverse(this);

-					}

-

-					if(expression)

-					{

-						expression->traverse(this);

-					}

-				}

-			}

-			else

-			{

-				if(condition)

-				{

-					condition->traverse(this);

-				}

-				else

-				{

-					condition = &True;

-				}

-

-				emit(sw::Shader::OPCODE_WHILE, 0, condition);

-

-				if(body)

-				{

-					body->traverse(this);

-				}

-

-				emit(sw::Shader::OPCODE_TEST);

-

-				if(expression)

-				{

-					expression->traverse(this);

-				}

-

-				if(condition)

-				{

-					condition->traverse(this);

-				}

-

-				emit(sw::Shader::OPCODE_ENDWHILE);

-			}

-		}

-

-		return false;

-	}

-

-	bool OutputASM::visitBranch(Visit visit, TIntermBranch *node)

-	{

-		if(currentScope != emitScope)

-		{

-			return false;

-		}

-

-		switch(node->getFlowOp())

-		{

-		case EOpKill:      if(visit == PostVisit) emit(sw::Shader::OPCODE_DISCARD);  break;

-		case EOpBreak:     if(visit == PostVisit) emit(sw::Shader::OPCODE_BREAK);    break;

-		case EOpContinue:  if(visit == PostVisit) emit(sw::Shader::OPCODE_CONTINUE); break;

-		case EOpReturn:

-			if(visit == PostVisit)

-			{

-				TIntermTyped *value = node->getExpression();

-

-				if(value)

-				{

-					copy(functionArray[currentFunction].ret, value);

-				}

-

-				emit(sw::Shader::OPCODE_LEAVE);

-			}

-			break;

-		default: UNREACHABLE(node->getFlowOp());

-		}

-

-		return true;

-	}

-

-	Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2, TIntermNode *src3, TIntermNode *src4)

-	{

-		return emit(op, dst, 0, src0, 0, src1, 0, src2, 0, src3, 0, src4, 0);

-	}

-

-	Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, int dstIndex, TIntermNode *src0, int index0, TIntermNode *src1, int index1,

-	                             TIntermNode *src2, int index2, TIntermNode *src3, int index3, TIntermNode *src4, int index4)

-	{

-		Instruction *instruction = new Instruction(op);

-

-		if(dst)

-		{

-			instruction->dst.type = registerType(dst);

-			instruction->dst.index = registerIndex(dst) + dstIndex;

-			instruction->dst.mask = writeMask(dst);

-			instruction->dst.integer = (dst->getBasicType() == EbtInt);

-		}

-

-		argument(instruction->src[0], src0, index0);

-		argument(instruction->src[1], src1, index1);

-		argument(instruction->src[2], src2, index2);

-		argument(instruction->src[3], src3, index3);

-		argument(instruction->src[4], src4, index4);

-

-		shader->append(instruction);

-

-		return instruction;

-	}

-

-	Instruction *OutputASM::emitCast(TIntermTyped *dst, TIntermTyped *src)

-	{

-		return emitCast(dst, 0, src, 0);

-	}

-

-	Instruction *OutputASM::emitCast(TIntermTyped *dst, int dstIndex, TIntermTyped *src, int srcIndex)

-	{

-		switch(src->getBasicType())

-		{

-		case EbtBool:

-			switch(dst->getBasicType())

-			{

-			case EbtInt:   return emit(sw::Shader::OPCODE_B2I, dst, dstIndex, src, srcIndex);

-			case EbtUInt:  return emit(sw::Shader::OPCODE_B2I, dst, dstIndex, src, srcIndex);

-			case EbtFloat: return emit(sw::Shader::OPCODE_B2F, dst, dstIndex, src, srcIndex);

-			default:       break;

-			}

-			break;

-		case EbtInt:

-			switch(dst->getBasicType())

-			{

-			case EbtBool:  return emit(sw::Shader::OPCODE_I2B, dst, dstIndex, src, srcIndex);

-			case EbtFloat: return emit(sw::Shader::OPCODE_I2F, dst, dstIndex, src, srcIndex);

-			default:       break;

-			}

-			break;

-		case EbtUInt:

-			switch(dst->getBasicType())

-			{

-			case EbtBool:  return emit(sw::Shader::OPCODE_I2B, dst, dstIndex, src, srcIndex);

-			case EbtFloat: return emit(sw::Shader::OPCODE_U2F, dst, dstIndex, src, srcIndex);

-			default:       break;

-			}

-			break;

-		case EbtFloat:

-			switch(dst->getBasicType())

-			{

-			case EbtBool: return emit(sw::Shader::OPCODE_F2B, dst, dstIndex, src, srcIndex);

-			case EbtInt:  return emit(sw::Shader::OPCODE_F2I, dst, dstIndex, src, srcIndex);

-			case EbtUInt: return emit(sw::Shader::OPCODE_F2U, dst, dstIndex, src, srcIndex);

-			default:      break;

-			}

-			break;

-		default:

-			break;

-		}

-

-		ASSERT((src->getBasicType() == dst->getBasicType()) ||

-		      ((src->getBasicType() == EbtInt) && (dst->getBasicType() == EbtUInt)) ||

-		      ((src->getBasicType() == EbtUInt) && (dst->getBasicType() == EbtInt)));

-

-		return emit(sw::Shader::OPCODE_MOV, dst, dstIndex, src, srcIndex);

-	}

-

-	void OutputASM::emitBinary(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2)

-	{

-		for(int index = 0; index < dst->elementRegisterCount(); index++)

-		{

-			emit(op, dst, index, src0, index, src1, index, src2, index);

-		}

-	}

-

-	void OutputASM::emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1)

-	{

-		emitBinary(op, result, src0, src1);

-		assignLvalue(lhs, result);

-	}

-

-	void OutputASM::emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index)

-	{

-		sw::Shader::Opcode opcode;

-		switch(left->getAsTyped()->getBasicType())

-		{

-		case EbtBool:

-		case EbtInt:

-			opcode = sw::Shader::OPCODE_ICMP;

-			break;

-		case EbtUInt:

-			opcode = sw::Shader::OPCODE_UCMP;

-			break;

-		default:

-			opcode = sw::Shader::OPCODE_CMP;

-			break;

-		}

-

-		Instruction *cmp = emit(opcode, dst, 0, left, index, right, index);

-		cmp->control = cmpOp;

-	}

-

-	int componentCount(const TType &type, int registers)

-	{

-		if(registers == 0)

-		{

-			return 0;

-		}

-

-		if(type.isArray() && registers >= type.elementRegisterCount())

-		{

-			int index = registers / type.elementRegisterCount();

-			registers -= index * type.elementRegisterCount();

-			return index * type.getElementSize() + componentCount(type, registers);

-		}

-

-		if(type.isStruct() || type.isInterfaceBlock())

-		{

-			const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();

-			int elements = 0;

-

-			for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)

-			{

-				const TType &fieldType = *((*field)->type());

-

-				if(fieldType.totalRegisterCount() <= registers)

-				{

-					registers -= fieldType.totalRegisterCount();

-					elements += fieldType.getObjectSize();

-				}

-				else   // Register within this field

-				{

-					return elements + componentCount(fieldType, registers);

-				}

-			}

-		}

-		else if(type.isMatrix())

-		{

-			return registers * type.registerSize();

-		}

-

-		UNREACHABLE(0);

-		return 0;

-	}

-

-	int registerSize(const TType &type, int registers)

-	{

-		if(registers == 0)

-		{

-			if(type.isStruct())

-			{

-				return registerSize(*((*(type.getStruct()->fields().begin()))->type()), 0);

-			}

-			else if(type.isInterfaceBlock())

-			{

-				return registerSize(*((*(type.getInterfaceBlock()->fields().begin()))->type()), 0);

-			}

-

-			return type.registerSize();

-		}

-

-		if(type.isArray() && registers >= type.elementRegisterCount())

-		{

-			int index = registers / type.elementRegisterCount();

-			registers -= index * type.elementRegisterCount();

-			return registerSize(type, registers);

-		}

-

-		if(type.isStruct() || type.isInterfaceBlock())

-		{

-			const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();

-			int elements = 0;

-

-			for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)

-			{

-				const TType &fieldType = *((*field)->type());

-

-				if(fieldType.totalRegisterCount() <= registers)

-				{

-					registers -= fieldType.totalRegisterCount();

-					elements += fieldType.getObjectSize();

-				}

-				else   // Register within this field

-				{

-					return registerSize(fieldType, registers);

-				}

-			}

-		}

-		else if(type.isMatrix())

-		{

-			return registerSize(type, 0);

-		}

-

-		UNREACHABLE(0);

-		return 0;

-	}

-

-	int OutputASM::getBlockId(TIntermTyped *arg)

-	{

-		if(arg)

-		{

-			const TType &type = arg->getType();

-			TInterfaceBlock* block = type.getInterfaceBlock();

-			if(block && (type.getQualifier() == EvqUniform))

-			{

-				// Make sure the uniform block is declared

-				uniformRegister(arg);

-

-				const char* blockName = block->name().c_str();

-

-				// Fetch uniform block index from array of blocks

-				for(ActiveUniformBlocks::const_iterator it = shaderObject->activeUniformBlocks.begin(); it != shaderObject->activeUniformBlocks.end(); ++it)

-				{

-					if(blockName == it->name)

-					{

-						return it->blockId;

-					}

-				}

-

-				ASSERT(false);

-			}

-		}

-

-		return -1;

-	}

-

-	OutputASM::ArgumentInfo OutputASM::getArgumentInfo(TIntermTyped *arg, int index)

-	{

-		const TType &type = arg->getType();

-		int blockId = getBlockId(arg);

-		ArgumentInfo argumentInfo(BlockMemberInfo::getDefaultBlockInfo(), type, -1, -1);

-		if(blockId != -1)

-		{

-			argumentInfo.bufferIndex = 0;

-			for(int i = 0; i < blockId; ++i)

-			{

-				int blockArraySize = shaderObject->activeUniformBlocks[i].arraySize;

-				argumentInfo.bufferIndex += blockArraySize > 0 ? blockArraySize : 1;

-			}

-

-			const BlockDefinitionIndexMap& blockDefinition = blockDefinitions[blockId];

-

-			BlockDefinitionIndexMap::const_iterator itEnd = blockDefinition.end();

-			BlockDefinitionIndexMap::const_iterator it = itEnd;

-

-			argumentInfo.clampedIndex = index;

-			if(type.isInterfaceBlock())

-			{

-				// Offset index to the beginning of the selected instance

-				int blockRegisters = type.elementRegisterCount();

-				int bufferOffset = argumentInfo.clampedIndex / blockRegisters;

-				argumentInfo.bufferIndex += bufferOffset;

-				argumentInfo.clampedIndex -= bufferOffset * blockRegisters;

-			}

-

-			int regIndex = registerIndex(arg);

-			for(int i = regIndex + argumentInfo.clampedIndex; i >= regIndex; --i)

-			{

-				it = blockDefinition.find(i);

-				if(it != itEnd)

-				{

-					argumentInfo.clampedIndex -= (i - regIndex);

-					break;

-				}

-			}

-			ASSERT(it != itEnd);

-

-			argumentInfo.typedMemberInfo = it->second;

-

-			int registerCount = argumentInfo.typedMemberInfo.type.totalRegisterCount();

-			argumentInfo.clampedIndex = (argumentInfo.clampedIndex >= registerCount) ? registerCount - 1 : argumentInfo.clampedIndex;

-		}

-		else

-		{

-			argumentInfo.clampedIndex = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;

-		}

-

-		return argumentInfo;

-	}

-

-	void OutputASM::argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index)

-	{

-		if(argument)

-		{

-			TIntermTyped *arg = argument->getAsTyped();

-			Temporary unpackedUniform(this);

-

-			const TType& srcType = arg->getType();

-			TInterfaceBlock* srcBlock = srcType.getInterfaceBlock();

-			if(srcBlock && (srcType.getQualifier() == EvqUniform))

-			{

-				const ArgumentInfo argumentInfo = getArgumentInfo(arg, index);

-				const TType &memberType = argumentInfo.typedMemberInfo.type;

-

-				if(memberType.getBasicType() == EbtBool)

-				{

-					int arraySize = (memberType.isArray() ? memberType.getArraySize() : 1);

-					ASSERT(argumentInfo.clampedIndex < arraySize);

-

-					// Convert the packed bool, which is currently an int, to a true bool

-					Instruction *instruction = new Instruction(sw::Shader::OPCODE_I2B);

-					instruction->dst.type = sw::Shader::PARAMETER_TEMP;

-					instruction->dst.index = registerIndex(&unpackedUniform);

-					instruction->src[0].type = sw::Shader::PARAMETER_CONST;

-					instruction->src[0].bufferIndex = argumentInfo.bufferIndex;

-					instruction->src[0].index = argumentInfo.typedMemberInfo.offset + argumentInfo.clampedIndex * argumentInfo.typedMemberInfo.arrayStride;

-

-					shader->append(instruction);

-

-					arg = &unpackedUniform;

-					index = 0;

-				}

-				else if((srcBlock->matrixPacking() == EmpRowMajor) && memberType.isMatrix())

-				{

-					int numCols = memberType.getNominalSize();

-					int numRows = memberType.getSecondarySize();

-					int arraySize = (memberType.isArray() ? memberType.getArraySize() : 1);

-

-					ASSERT(argumentInfo.clampedIndex < (numCols * arraySize));

-

-					unsigned int dstIndex = registerIndex(&unpackedUniform);

-					unsigned int srcSwizzle = (argumentInfo.clampedIndex % numCols) * 0x55;

-					int arrayIndex = argumentInfo.clampedIndex / numCols;

-					int matrixStartOffset = argumentInfo.typedMemberInfo.offset + arrayIndex * argumentInfo.typedMemberInfo.arrayStride;

-

-					for(int j = 0; j < numRows; ++j)

-					{

-						// Transpose the row major matrix

-						Instruction *instruction = new Instruction(sw::Shader::OPCODE_MOV);

-						instruction->dst.type = sw::Shader::PARAMETER_TEMP;

-						instruction->dst.index = dstIndex;

-						instruction->dst.mask = 1 << j;

-						instruction->src[0].type = sw::Shader::PARAMETER_CONST;

-						instruction->src[0].bufferIndex = argumentInfo.bufferIndex;

-						instruction->src[0].index = matrixStartOffset + j * argumentInfo.typedMemberInfo.matrixStride;

-						instruction->src[0].swizzle = srcSwizzle;

-

-						shader->append(instruction);

-					}

-

-					arg = &unpackedUniform;

-					index = 0;

-				}

-			}

-

-			const ArgumentInfo argumentInfo = getArgumentInfo(arg, index);

-			const TType &type = argumentInfo.typedMemberInfo.type;

-

-			int size = registerSize(type, argumentInfo.clampedIndex);

-

-			parameter.type = registerType(arg);

-			parameter.bufferIndex = argumentInfo.bufferIndex;

-

-			if(arg->getAsConstantUnion() && arg->getAsConstantUnion()->getUnionArrayPointer())

-			{

-				int component = componentCount(type, argumentInfo.clampedIndex);

-				ConstantUnion *constants = arg->getAsConstantUnion()->getUnionArrayPointer();

-

-				for(int i = 0; i < 4; i++)

-				{

-					if(size == 1)   // Replicate

-					{

-						parameter.value[i] = constants[component + 0].getAsFloat();

-					}

-					else if(i < size)

-					{

-						parameter.value[i] = constants[component + i].getAsFloat();

-					}

-					else

-					{

-						parameter.value[i] = 0.0f;

-					}

-				}

-			}

-			else

-			{

-				parameter.index = registerIndex(arg) + argumentInfo.clampedIndex;

-

-				if(parameter.bufferIndex != -1)

-				{

-					int stride = (argumentInfo.typedMemberInfo.matrixStride > 0) ? argumentInfo.typedMemberInfo.matrixStride : argumentInfo.typedMemberInfo.arrayStride;

-					parameter.index = argumentInfo.typedMemberInfo.offset + argumentInfo.clampedIndex * stride;

-				}

-			}

-

-			if(!IsSampler(arg->getBasicType()))

-			{

-				parameter.swizzle = readSwizzle(arg, size);

-			}

-		}

-	}

-

-	void OutputASM::copy(TIntermTyped *dst, TIntermNode *src, int offset)

-	{

-		for(int index = 0; index < dst->totalRegisterCount(); index++)

-		{

-			Instruction *mov = emit(sw::Shader::OPCODE_MOV, dst, index, src, offset + index);

-			mov->dst.mask = writeMask(dst, index);

-		}

-	}

-

-	int swizzleElement(int swizzle, int index)

-	{

-		return (swizzle >> (index * 2)) & 0x03;

-	}

-

-	int swizzleSwizzle(int leftSwizzle, int rightSwizzle)

-	{

-		return (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 0)) << 0) |

-		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 1)) << 2) |

-		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 2)) << 4) |

-		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 3)) << 6);

-	}

-

-	void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)

-	{

-		if(src &&

-			((src->isVector() && (!dst->isVector() || (src->getNominalSize() != dst->getNominalSize()))) ||

-			 (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize()) || (src->getSecondarySize() != dst->getSecondarySize())))))

-		{

-			return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");

-		}

-

-		TIntermBinary *binary = dst->getAsBinaryNode();

-

-		if(binary && binary->getOp() == EOpIndexIndirect && binary->getLeft()->isVector() && dst->isScalar())

-		{

-			Instruction *insert = new Instruction(sw::Shader::OPCODE_INSERT);

-

-			Temporary address(this);

-			lvalue(insert->dst, address, dst);

-

-			insert->src[0].type = insert->dst.type;

-			insert->src[0].index = insert->dst.index;

-			insert->src[0].rel = insert->dst.rel;

-			argument(insert->src[1], src);

-			argument(insert->src[2], binary->getRight());

-

-			shader->append(insert);

-		}

-		else

-		{

-			for(int offset = 0; offset < dst->totalRegisterCount(); offset++)

-			{

-				Instruction *mov = new Instruction(sw::Shader::OPCODE_MOV);

-

-				Temporary address(this);

-				int swizzle = lvalue(mov->dst, address, dst);

-				mov->dst.index += offset;

-

-				if(offset > 0)

-				{

-					mov->dst.mask = writeMask(dst, offset);

-				}

-

-				argument(mov->src[0], src, offset);

-				mov->src[0].swizzle = swizzleSwizzle(mov->src[0].swizzle, swizzle);

-

-				shader->append(mov);

-			}

-		}

-	}

-

-	int OutputASM::lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node)

-	{

-		TIntermTyped *result = node;

-		TIntermBinary *binary = node->getAsBinaryNode();

-		TIntermSymbol *symbol = node->getAsSymbolNode();

-

-		if(binary)

-		{

-			TIntermTyped *left = binary->getLeft();

-			TIntermTyped *right = binary->getRight();

-

-			int leftSwizzle = lvalue(dst, address, left);   // Resolve the l-value of the left side

-

-			switch(binary->getOp())

-			{

-			case EOpIndexDirect:

-				{

-					int rightIndex = right->getAsConstantUnion()->getIConst(0);

-

-					if(left->isRegister())

-					{

-						int leftMask = dst.mask;

-

-						dst.mask = 1;

-						while((leftMask & dst.mask) == 0)

-						{

-							dst.mask = dst.mask << 1;

-						}

-

-						int element = swizzleElement(leftSwizzle, rightIndex);

-						dst.mask = 1 << element;

-

-						return element;

-					}

-					else if(left->isArray() || left->isMatrix())

-					{

-						dst.index += rightIndex * result->totalRegisterCount();

-						return 0xE4;

-					}

-					else UNREACHABLE(0);

-				}

-				break;

-			case EOpIndexIndirect:

-				{

-					if(left->isRegister())

-					{

-						// Requires INSERT instruction (handled by calling function)

-					}

-					else if(left->isArray() || left->isMatrix())

-					{

-						int scale = result->totalRegisterCount();

-

-						if(dst.rel.type == sw::Shader::PARAMETER_VOID)   // Use the index register as the relative address directly

-						{

-							if(left->totalRegisterCount() > 1)

-							{

-								sw::Shader::SourceParameter relativeRegister;

-								argument(relativeRegister, right);

-

-								dst.rel.index = relativeRegister.index;

-								dst.rel.type = relativeRegister.type;

-								dst.rel.scale = scale;

-								dst.rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);

-							}

-						}

-						else if(dst.rel.index != registerIndex(&address))   // Move the previous index register to the address register

-						{

-							if(scale == 1)

-							{

-								Constant oldScale((int)dst.rel.scale);

-								Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right);

-								mad->src[0].index = dst.rel.index;

-								mad->src[0].type = dst.rel.type;

-							}

-							else

-							{

-								Constant oldScale((int)dst.rel.scale);

-								Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale);

-								mul->src[0].index = dst.rel.index;

-								mul->src[0].type = dst.rel.type;

-

-								Constant newScale(scale);

-								emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);

-							}

-

-							dst.rel.type = sw::Shader::PARAMETER_TEMP;

-							dst.rel.index = registerIndex(&address);

-							dst.rel.scale = 1;

-						}

-						else   // Just add the new index to the address register

-						{

-							if(scale == 1)

-							{

-								emit(sw::Shader::OPCODE_IADD, &address, &address, right);

-							}

-							else

-							{

-								Constant newScale(scale);

-								emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);

-							}

-						}

-					}

-					else UNREACHABLE(0);

-				}

-				break;

-			case EOpIndexDirectStruct:

-			case EOpIndexDirectInterfaceBlock:

-				{

-					const TFieldList& fields = (binary->getOp() == EOpIndexDirectStruct) ?

-				                               left->getType().getStruct()->fields() :

-				                               left->getType().getInterfaceBlock()->fields();

-					int index = right->getAsConstantUnion()->getIConst(0);

-					int fieldOffset = 0;

-

-					for(int i = 0; i < index; i++)

-					{

-						fieldOffset += fields[i]->type()->totalRegisterCount();

-					}

-

-					dst.type = registerType(left);

-					dst.index += fieldOffset;

-					dst.mask = writeMask(right);

-

-					return 0xE4;

-				}

-				break;

-			case EOpVectorSwizzle:

-				{

-					ASSERT(left->isRegister());

-

-					int leftMask = dst.mask;

-

-					int swizzle = 0;

-					int rightMask = 0;

-

-					TIntermSequence &sequence = right->getAsAggregate()->getSequence();

-

-					for(unsigned int i = 0; i < sequence.size(); i++)

-					{

-						int index = sequence[i]->getAsConstantUnion()->getIConst(0);

-

-						int element = swizzleElement(leftSwizzle, index);

-						rightMask = rightMask | (1 << element);

-						swizzle = swizzle | swizzleElement(leftSwizzle, i) << (element * 2);

-					}

-

-					dst.mask = leftMask & rightMask;

-

-					return swizzle;

-				}

-				break;

-			default:

-				UNREACHABLE(binary->getOp());   // Not an l-value operator

-				break;

-			}

-		}

-		else if(symbol)

-		{

-			dst.type = registerType(symbol);

-			dst.index = registerIndex(symbol);

-			dst.mask = writeMask(symbol);

-			return 0xE4;

-		}

-

-		return 0xE4;

-	}

-

-	sw::Shader::ParameterType OutputASM::registerType(TIntermTyped *operand)

-	{

-		if(isSamplerRegister(operand))

-		{

-			return sw::Shader::PARAMETER_SAMPLER;

-		}

-

-		const TQualifier qualifier = operand->getQualifier();

-		if((EvqFragColor == qualifier) || (EvqFragData == qualifier))

-		{

-			if(((EvqFragData == qualifier) && (EvqFragColor == outputQualifier)) ||

-			   ((EvqFragColor == qualifier) && (EvqFragData == outputQualifier)))

-			{

-				mContext.error(operand->getLine(), "static assignment to both gl_FragData and gl_FragColor", "");

-			}

-			outputQualifier = qualifier;

-		}

-

-		if(qualifier == EvqConstExpr && (!operand->getAsConstantUnion() || !operand->getAsConstantUnion()->getUnionArrayPointer()))

-		{

-			return sw::Shader::PARAMETER_TEMP;

-		}

-

-		switch(qualifier)

-		{

-		case EvqTemporary:           return sw::Shader::PARAMETER_TEMP;

-		case EvqGlobal:              return sw::Shader::PARAMETER_TEMP;

-		case EvqConstExpr:           return sw::Shader::PARAMETER_FLOAT4LITERAL;   // All converted to float

-		case EvqAttribute:           return sw::Shader::PARAMETER_INPUT;

-		case EvqVaryingIn:           return sw::Shader::PARAMETER_INPUT;

-		case EvqVaryingOut:          return sw::Shader::PARAMETER_OUTPUT;

-		case EvqVertexIn:            return sw::Shader::PARAMETER_INPUT;

-		case EvqFragmentOut:         return sw::Shader::PARAMETER_COLOROUT;

-		case EvqVertexOut:           return sw::Shader::PARAMETER_OUTPUT;

-		case EvqFragmentIn:          return sw::Shader::PARAMETER_INPUT;

-		case EvqInvariantVaryingIn:  return sw::Shader::PARAMETER_INPUT;    // FIXME: Guarantee invariance at the backend

-		case EvqInvariantVaryingOut: return sw::Shader::PARAMETER_OUTPUT;   // FIXME: Guarantee invariance at the backend

-		case EvqSmooth:              return sw::Shader::PARAMETER_OUTPUT;

-		case EvqFlat:                return sw::Shader::PARAMETER_OUTPUT;

-		case EvqCentroidOut:         return sw::Shader::PARAMETER_OUTPUT;

-		case EvqSmoothIn:            return sw::Shader::PARAMETER_INPUT;

-		case EvqFlatIn:              return sw::Shader::PARAMETER_INPUT;

-		case EvqCentroidIn:          return sw::Shader::PARAMETER_INPUT;

-		case EvqUniform:             return sw::Shader::PARAMETER_CONST;

-		case EvqIn:                  return sw::Shader::PARAMETER_TEMP;

-		case EvqOut:                 return sw::Shader::PARAMETER_TEMP;

-		case EvqInOut:               return sw::Shader::PARAMETER_TEMP;

-		case EvqConstReadOnly:       return sw::Shader::PARAMETER_TEMP;

-		case EvqPosition:            return sw::Shader::PARAMETER_OUTPUT;

-		case EvqPointSize:           return sw::Shader::PARAMETER_OUTPUT;

-		case EvqInstanceID:          return sw::Shader::PARAMETER_MISCTYPE;

-		case EvqFragCoord:           return sw::Shader::PARAMETER_MISCTYPE;

-		case EvqFrontFacing:         return sw::Shader::PARAMETER_MISCTYPE;

-		case EvqPointCoord:          return sw::Shader::PARAMETER_INPUT;

-		case EvqFragColor:           return sw::Shader::PARAMETER_COLOROUT;

-		case EvqFragData:            return sw::Shader::PARAMETER_COLOROUT;

-		case EvqFragDepth:           return sw::Shader::PARAMETER_DEPTHOUT;

-		default: UNREACHABLE(qualifier);

-		}

-

-		return sw::Shader::PARAMETER_VOID;

-	}

-

-	unsigned int OutputASM::registerIndex(TIntermTyped *operand)

-	{

-		if(isSamplerRegister(operand))

-		{

-			return samplerRegister(operand);

-		}

-

-		switch(operand->getQualifier())

-		{

-		case EvqTemporary:           return temporaryRegister(operand);

-		case EvqGlobal:              return temporaryRegister(operand);

-		case EvqConstExpr:           return temporaryRegister(operand);   // Unevaluated constant expression

-		case EvqAttribute:           return attributeRegister(operand);

-		case EvqVaryingIn:           return varyingRegister(operand);

-		case EvqVaryingOut:          return varyingRegister(operand);

-		case EvqVertexIn:            return attributeRegister(operand);

-		case EvqFragmentOut:         return fragmentOutputRegister(operand);

-		case EvqVertexOut:           return varyingRegister(operand);

-		case EvqFragmentIn:          return varyingRegister(operand);

-		case EvqInvariantVaryingIn:  return varyingRegister(operand);

-		case EvqInvariantVaryingOut: return varyingRegister(operand);

-		case EvqSmooth:              return varyingRegister(operand);

-		case EvqFlat:                return varyingRegister(operand);

-		case EvqCentroidOut:         return varyingRegister(operand);

-		case EvqSmoothIn:            return varyingRegister(operand);

-		case EvqFlatIn:              return varyingRegister(operand);

-		case EvqCentroidIn:          return varyingRegister(operand);

-		case EvqUniform:             return uniformRegister(operand);

-		case EvqIn:                  return temporaryRegister(operand);

-		case EvqOut:                 return temporaryRegister(operand);

-		case EvqInOut:               return temporaryRegister(operand);

-		case EvqConstReadOnly:       return temporaryRegister(operand);

-		case EvqPosition:            return varyingRegister(operand);

-		case EvqPointSize:           return varyingRegister(operand);

-		case EvqInstanceID:          vertexShader->instanceIdDeclared = true; return 0;

-		case EvqFragCoord:           pixelShader->vPosDeclared = true;  return 0;

-		case EvqFrontFacing:         pixelShader->vFaceDeclared = true; return 1;

-		case EvqPointCoord:          return varyingRegister(operand);

-		case EvqFragColor:           return 0;

-		case EvqFragData:            return fragmentOutputRegister(operand);

-		case EvqFragDepth:           return 0;

-		default: UNREACHABLE(operand->getQualifier());

-		}

-

-		return 0;

-	}

-

-	int OutputASM::writeMask(TIntermTyped *destination, int index)

-	{

-		if(destination->getQualifier() == EvqPointSize)

-		{

-			return 0x2;   // Point size stored in the y component

-		}

-

-		return 0xF >> (4 - registerSize(destination->getType(), index));

-	}

-

-	int OutputASM::readSwizzle(TIntermTyped *argument, int size)

-	{

-		if(argument->getQualifier() == EvqPointSize)

-		{

-			return 0x55;   // Point size stored in the y component

-		}

-

-		static const unsigned char swizzleSize[5] = {0x00, 0x00, 0x54, 0xA4, 0xE4};   // (void), xxxx, xyyy, xyzz, xyzw

-

-		return swizzleSize[size];

-	}

-

-	// Conservatively checks whether an expression is fast to compute and has no side effects

-	bool OutputASM::trivial(TIntermTyped *expression, int budget)

-	{

-		if(!expression->isRegister())

-		{

-			return false;

-		}

-

-		return cost(expression, budget) >= 0;

-	}

-

-	// Returns the remaining computing budget (if < 0 the expression is too expensive or has side effects)

-	int OutputASM::cost(TIntermNode *expression, int budget)

-	{

-		if(budget < 0)

-		{

-			return budget;

-		}

-

-		if(expression->getAsSymbolNode())

-		{

-			return budget;

-		}

-		else if(expression->getAsConstantUnion())

-		{

-			return budget;

-		}

-		else if(expression->getAsBinaryNode())

-		{

-			TIntermBinary *binary = expression->getAsBinaryNode();

-

-			switch(binary->getOp())

-			{

-			case EOpVectorSwizzle:

-			case EOpIndexDirect:

-			case EOpIndexDirectStruct:

-			case EOpIndexDirectInterfaceBlock:

-				return cost(binary->getLeft(), budget - 0);

-			case EOpAdd:

-			case EOpSub:

-			case EOpMul:

-				return cost(binary->getLeft(), cost(binary->getRight(), budget - 1));

-			default:

-				return -1;

-			}

-		}

-		else if(expression->getAsUnaryNode())

-		{

-			TIntermUnary *unary = expression->getAsUnaryNode();

-

-			switch(unary->getOp())

-			{

-			case EOpAbs:

-			case EOpNegative:

-				return cost(unary->getOperand(), budget - 1);

-			default:

-				return -1;

-			}

-		}

-		else if(expression->getAsSelectionNode())

-		{

-			TIntermSelection *selection = expression->getAsSelectionNode();

-

-			if(selection->usesTernaryOperator())

-			{

-				TIntermTyped *condition = selection->getCondition();

-				TIntermNode *trueBlock = selection->getTrueBlock();

-				TIntermNode *falseBlock = selection->getFalseBlock();

-				TIntermConstantUnion *constantCondition = condition->getAsConstantUnion();

-

-				if(constantCondition)

-				{

-					bool trueCondition = constantCondition->getUnionArrayPointer()->getBConst();

-

-					if(trueCondition)

-					{

-						return cost(trueBlock, budget - 0);

-					}

-					else

-					{

-						return cost(falseBlock, budget - 0);

-					}

-				}

-				else

-				{

-					return cost(trueBlock, cost(falseBlock, budget - 2));

-				}

-			}

-		}

-

-		return -1;

-	}

-

-	const Function *OutputASM::findFunction(const TString &name)

-	{

-		for(unsigned int f = 0; f < functionArray.size(); f++)

-		{

-			if(functionArray[f].name == name)

-			{

-				return &functionArray[f];

-			}

-		}

-

-		return 0;

-	}

-

-	int OutputASM::temporaryRegister(TIntermTyped *temporary)

-	{

-		return allocate(temporaries, temporary);

-	}

-

-	int OutputASM::varyingRegister(TIntermTyped *varying)

-	{

-		int var = lookup(varyings, varying);

-

-		if(var == -1)

-		{

-			var = allocate(varyings, varying);

-			int componentCount = varying->registerSize();

-			int registerCount = varying->totalRegisterCount();

-

-			if(pixelShader)

-			{

-				if((var + registerCount) > sw::PixelShader::MAX_INPUT_VARYINGS)

-				{

-					mContext.error(varying->getLine(), "Varyings packing failed: Too many varyings", "fragment shader");

-					return 0;

-				}

-

-				if(varying->getQualifier() == EvqPointCoord)

-				{

-					ASSERT(varying->isRegister());

-					if(componentCount >= 1) pixelShader->semantic[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);

-					if(componentCount >= 2) pixelShader->semantic[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);

-					if(componentCount >= 3) pixelShader->semantic[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);

-					if(componentCount >= 4) pixelShader->semantic[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);

-				}

-				else

-				{

-					for(int i = 0; i < varying->totalRegisterCount(); i++)

-					{

-						if(componentCount >= 1) pixelShader->semantic[var + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);

-						if(componentCount >= 2) pixelShader->semantic[var + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);

-						if(componentCount >= 3) pixelShader->semantic[var + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);

-						if(componentCount >= 4) pixelShader->semantic[var + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);

-					}

-				}

-			}

-			else if(vertexShader)

-			{

-				if((var + registerCount) > sw::VertexShader::MAX_OUTPUT_VARYINGS)

-				{

-					mContext.error(varying->getLine(), "Varyings packing failed: Too many varyings", "vertex shader");

-					return 0;

-				}

-

-				if(varying->getQualifier() == EvqPosition)

-				{

-					ASSERT(varying->isRegister());

-					vertexShader->output[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);

-					vertexShader->output[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);

-					vertexShader->output[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);

-					vertexShader->output[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);

-					vertexShader->positionRegister = var;

-				}

-				else if(varying->getQualifier() == EvqPointSize)

-				{

-					ASSERT(varying->isRegister());

-					vertexShader->output[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);

-					vertexShader->output[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);

-					vertexShader->output[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);

-					vertexShader->output[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);

-					vertexShader->pointSizeRegister = var;

-				}

-				else

-				{

-					// Semantic indexes for user varyings will be assigned during program link to match the pixel shader

-				}

-			}

-			else UNREACHABLE(0);

-

-			declareVarying(varying, var);

-		}

-

-		return var;

-	}

-

-	void OutputASM::declareVarying(TIntermTyped *varying, int reg)

-	{

-		if(varying->getQualifier() != EvqPointCoord)   // gl_PointCoord does not need linking

-		{

-			const TType &type = varying->getType();

-			const char *name = varying->getAsSymbolNode()->getSymbol().c_str();

-			VaryingList &activeVaryings = shaderObject->varyings;

-

-			// Check if this varying has been declared before without having a register assigned

-			for(VaryingList::iterator v = activeVaryings.begin(); v != activeVaryings.end(); v++)

-			{

-				if(v->name == name)

-				{

-					if(reg >= 0)

-					{

-						ASSERT(v->reg < 0 || v->reg == reg);

-						v->reg = reg;

-					}

-

-					return;

-				}

-			}

-

-			activeVaryings.push_back(glsl::Varying(glVariableType(type), name, varying->getArraySize(), reg, 0));

-		}

-	}

-

-	int OutputASM::uniformRegister(TIntermTyped *uniform)

-	{

-		const TType &type = uniform->getType();

-		ASSERT(!IsSampler(type.getBasicType()));

-		TInterfaceBlock *block = type.getAsInterfaceBlock();

-		TIntermSymbol *symbol = uniform->getAsSymbolNode();

-		ASSERT(symbol || block);

-

-		if(symbol || block)

-		{

-			TInterfaceBlock* parentBlock = type.getInterfaceBlock();

-			bool isBlockMember = (!block && parentBlock);

-			int index = isBlockMember ? lookup(uniforms, parentBlock) : lookup(uniforms, uniform);

-

-			if(index == -1 || isBlockMember)

-			{

-				if(index == -1)

-				{

-					index = allocate(uniforms, uniform);

-				}

-

-				// Verify if the current uniform is a member of an already declared block

-				const TString &name = symbol ? symbol->getSymbol() : block->name();

-				int blockMemberIndex = blockMemberLookup(type, name, index);

-				if(blockMemberIndex == -1)

-				{

-					declareUniform(type, name, index);

-				}

-				else

-				{

-					index = blockMemberIndex;

-				}

-			}

-

-			return index;

-		}

-

-		return 0;

-	}

-

-	int OutputASM::attributeRegister(TIntermTyped *attribute)

-	{

-		ASSERT(!attribute->isArray());

-

-		int index = lookup(attributes, attribute);

-

-		if(index == -1)

-		{

-			TIntermSymbol *symbol = attribute->getAsSymbolNode();

-			ASSERT(symbol);

-

-			if(symbol)

-			{

-				index = allocate(attributes, attribute);

-				const TType &type = attribute->getType();

-				int registerCount = attribute->totalRegisterCount();

-

-				if(vertexShader && (index + registerCount) <= sw::VertexShader::MAX_INPUT_ATTRIBUTES)

-				{

-					for(int i = 0; i < registerCount; i++)

-					{

-						vertexShader->input[index + i] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, index + i);

-					}

-				}

-

-				ActiveAttributes &activeAttributes = shaderObject->activeAttributes;

-

-				const char *name = symbol->getSymbol().c_str();

-				activeAttributes.push_back(Attribute(glVariableType(type), name, type.getArraySize(), type.getLayoutQualifier().location, index));

-			}

-		}

-

-		return index;

-	}

-

-	int OutputASM::fragmentOutputRegister(TIntermTyped *fragmentOutput)

-	{

-		return allocate(fragmentOutputs, fragmentOutput);

-	}

-

-	int OutputASM::samplerRegister(TIntermTyped *sampler)

-	{

-		const TType &type = sampler->getType();

-		ASSERT(IsSampler(type.getBasicType()) || type.isStruct());   // Structures can contain samplers

-

-		TIntermSymbol *symbol = sampler->getAsSymbolNode();

-		TIntermBinary *binary = sampler->getAsBinaryNode();

-

-		if(symbol && type.getQualifier() == EvqUniform)

-		{

-			return samplerRegister(symbol);

-		}

-		else if(binary)

-		{

-			TIntermTyped *left = binary->getLeft();

-			TIntermTyped *right = binary->getRight();

-			const TType &leftType = left->getType();

-			int index = right->getAsConstantUnion() ? right->getAsConstantUnion()->getIConst(0) : 0;

-			int offset = 0;

-

-			switch(binary->getOp())

-			{

-			case EOpIndexDirect:

-				ASSERT(left->isArray());

-				offset = index * leftType.elementRegisterCount();

-				break;

-			case EOpIndexDirectStruct:

-				ASSERT(leftType.isStruct());

-				{

-					const TFieldList &fields = leftType.getStruct()->fields();

-

-					for(int i = 0; i < index; i++)

-					{

-						offset += fields[i]->type()->totalRegisterCount();

-					}

-				}

-				break;

-			case EOpIndexIndirect:               // Indirect indexing produces a temporary, not a sampler register

-				return -1;

-			case EOpIndexDirectInterfaceBlock:   // Interface blocks can't contain samplers

-			default:

-				UNREACHABLE(binary->getOp());

-				return -1;

-			}

-

-			int base = samplerRegister(left);

-

-			if(base < 0)

-			{

-				return -1;

-			}

-

-			return base + offset;

-		}

-

-		UNREACHABLE(0);

-		return -1;   // Not a sampler register

-	}

-

-	int OutputASM::samplerRegister(TIntermSymbol *sampler)

-	{

-		const TType &type = sampler->getType();

-		ASSERT(IsSampler(type.getBasicType()) || type.isStruct());   // Structures can contain samplers

-

-		int index = lookup(samplers, sampler);

-

-		if(index == -1)

-		{

-			index = allocate(samplers, sampler);

-

-			if(sampler->getQualifier() == EvqUniform)

-			{

-				const char *name = sampler->getSymbol().c_str();

-				declareUniform(type, name, index);

-			}

-		}

-

-		return index;

-	}

-

-	bool OutputASM::isSamplerRegister(TIntermTyped *operand)

-	{

-		return operand && IsSampler(operand->getBasicType()) && samplerRegister(operand) >= 0;

-	}

-

-	int OutputASM::lookup(VariableArray &list, TIntermTyped *variable)

-	{

-		for(unsigned int i = 0; i < list.size(); i++)

-		{

-			if(list[i] == variable)

-			{

-				return i;   // Pointer match

-			}

-		}

-

-		TIntermSymbol *varSymbol = variable->getAsSymbolNode();

-		TInterfaceBlock *varBlock = variable->getType().getAsInterfaceBlock();

-

-		if(varBlock)

-		{

-			for(unsigned int i = 0; i < list.size(); i++)

-			{

-				if(list[i])

-				{

-					TInterfaceBlock *listBlock = list[i]->getType().getAsInterfaceBlock();

-

-					if(listBlock)

-					{

-						if(listBlock->name() == varBlock->name())

-						{

-							ASSERT(listBlock->arraySize() == varBlock->arraySize());

-							ASSERT(listBlock->fields() == varBlock->fields());

-							ASSERT(listBlock->blockStorage() == varBlock->blockStorage());

-							ASSERT(listBlock->matrixPacking() == varBlock->matrixPacking());

-

-							return i;

-						}

-					}

-				}

-			}

-		}

-		else if(varSymbol)

-		{

-			for(unsigned int i = 0; i < list.size(); i++)

-			{

-				if(list[i])

-				{

-					TIntermSymbol *listSymbol = list[i]->getAsSymbolNode();

-

-					if(listSymbol)

-					{

-						if(listSymbol->getId() == varSymbol->getId())

-						{

-							ASSERT(listSymbol->getSymbol() == varSymbol->getSymbol());

-							ASSERT(listSymbol->getType() == varSymbol->getType());

-							ASSERT(listSymbol->getQualifier() == varSymbol->getQualifier());

-

-							return i;

-						}

-					}

-				}

-			}

-		}

-

-		return -1;

-	}

-

-	int OutputASM::lookup(VariableArray &list, TInterfaceBlock *block)

-	{

-		for(unsigned int i = 0; i < list.size(); i++)

-		{

-			if(list[i] && (list[i]->getType().getInterfaceBlock() == block))

-			{

-				return i;   // Pointer match

-			}

-		}

-		return -1;

-	}

-

-	int OutputASM::allocate(VariableArray &list, TIntermTyped *variable)

-	{

-		int index = lookup(list, variable);

-

-		if(index == -1)

-		{

-			unsigned int registerCount = variable->blockRegisterCount();

-

-			for(unsigned int i = 0; i < list.size(); i++)

-			{

-				if(list[i] == 0)

-				{

-					unsigned int j = 1;

-					for( ; j < registerCount && (i + j) < list.size(); j++)

-					{

-						if(list[i + j] != 0)

-						{

-							break;

-						}

-					}

-

-					if(j == registerCount)   // Found free slots

-					{

-						for(unsigned int j = 0; j < registerCount; j++)

-						{

-							list[i + j] = variable;

-						}

-

-						return i;

-					}

-				}

-			}

-

-			index = list.size();

-

-			for(unsigned int i = 0; i < registerCount; i++)

-			{

-				list.push_back(variable);

-			}

-		}

-

-		return index;

-	}

-

-	void OutputASM::free(VariableArray &list, TIntermTyped *variable)

-	{

-		int index = lookup(list, variable);

-

-		if(index >= 0)

-		{

-			list[index] = 0;

-		}

-	}

-

-	int OutputASM::blockMemberLookup(const TType &type, const TString &name, int registerIndex)

-	{

-		const TInterfaceBlock *block = type.getInterfaceBlock();

-

-		if(block)

-		{

-			ActiveUniformBlocks &activeUniformBlocks = shaderObject->activeUniformBlocks;

-			const TFieldList& fields = block->fields();

-			const TString &blockName = block->name();

-			int fieldRegisterIndex = registerIndex;

-

-			if(!type.isInterfaceBlock())

-			{

-				// This is a uniform that's part of a block, let's see if the block is already defined

-				for(size_t i = 0; i < activeUniformBlocks.size(); ++i)

-				{

-					if(activeUniformBlocks[i].name == blockName.c_str())

-					{

-						// The block is already defined, find the register for the current uniform and return it

-						for(size_t j = 0; j < fields.size(); j++)

-						{

-							const TString &fieldName = fields[j]->name();

-							if(fieldName == name)

-							{

-								return fieldRegisterIndex;

-							}

-

-							fieldRegisterIndex += fields[j]->type()->totalRegisterCount();

-						}

-

-						ASSERT(false);

-						return fieldRegisterIndex;

-					}

-				}

-			}

-		}

-

-		return -1;

-	}

-

-	void OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, int blockId, BlockLayoutEncoder* encoder)

-	{

-		const TStructure *structure = type.getStruct();

-		const TInterfaceBlock *block = (type.isInterfaceBlock() || (blockId == -1)) ? type.getInterfaceBlock() : nullptr;

-

-		if(!structure && !block)

-		{

-			ActiveUniforms &activeUniforms = shaderObject->activeUniforms;

-			const BlockMemberInfo blockInfo = encoder ? encoder->encodeType(type) : BlockMemberInfo::getDefaultBlockInfo();

-			if(blockId >= 0)

-			{

-				blockDefinitions[blockId][registerIndex] = TypedMemberInfo(blockInfo, type);

-				shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size());

-			}

-			int fieldRegisterIndex = encoder ? shaderObject->activeUniformBlocks[blockId].registerIndex + BlockLayoutEncoder::getBlockRegister(blockInfo) : registerIndex;

-			activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(),

-			                                 fieldRegisterIndex, blockId, blockInfo));

-			if(IsSampler(type.getBasicType()))

-			{

-				for(int i = 0; i < type.totalRegisterCount(); i++)

-				{

-					shader->declareSampler(fieldRegisterIndex + i);

-				}

-			}

-		}

-		else if(block)

-		{

-			ActiveUniformBlocks &activeUniformBlocks = shaderObject->activeUniformBlocks;

-			const TFieldList& fields = block->fields();

-			const TString &blockName = block->name();

-			int fieldRegisterIndex = registerIndex;

-			bool isUniformBlockMember = !type.isInterfaceBlock() && (blockId == -1);

-

-			blockId = activeUniformBlocks.size();

-			bool isRowMajor = block->matrixPacking() == EmpRowMajor;

-			activeUniformBlocks.push_back(UniformBlock(blockName.c_str(), 0, block->arraySize(),

-			                                           block->blockStorage(), isRowMajor, registerIndex, blockId));

-			blockDefinitions.push_back(BlockDefinitionIndexMap());

-

-			Std140BlockEncoder currentBlockEncoder(isRowMajor);

-			currentBlockEncoder.enterAggregateType();

-			for(size_t i = 0; i < fields.size(); i++)

-			{

-				const TType &fieldType = *(fields[i]->type());

-				const TString &fieldName = fields[i]->name();

-				if(isUniformBlockMember && (fieldName == name))

-				{

-					registerIndex = fieldRegisterIndex;

-				}

-

-				const TString uniformName = block->hasInstanceName() ? blockName + "." + fieldName : fieldName;

-

-				declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, &currentBlockEncoder);

-				fieldRegisterIndex += fieldType.totalRegisterCount();

-			}

-			currentBlockEncoder.exitAggregateType();

-			activeUniformBlocks[blockId].dataSize = currentBlockEncoder.getBlockSize();

-		}

-		else

-		{

-			int fieldRegisterIndex = registerIndex;

-

-			const TFieldList& fields = structure->fields();

-			if(type.isArray() && (structure || type.isInterfaceBlock()))

-			{

-				for(int i = 0; i < type.getArraySize(); i++)

-				{

-					if(encoder)

-					{

-						encoder->enterAggregateType();

-					}

-					for(size_t j = 0; j < fields.size(); j++)

-					{

-						const TType &fieldType = *(fields[j]->type());

-						const TString &fieldName = fields[j]->name();

-						const TString uniformName = name + "[" + str(i) + "]." + fieldName;

-

-						declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);

-						fieldRegisterIndex += fieldType.totalRegisterCount();

-					}

-					if(encoder)

-					{

-						encoder->exitAggregateType();

-					}

-				}

-			}

-			else

-			{

-				if(encoder)

-				{

-					encoder->enterAggregateType();

-				}

-				for(size_t i = 0; i < fields.size(); i++)

-				{

-					const TType &fieldType = *(fields[i]->type());

-					const TString &fieldName = fields[i]->name();

-					const TString uniformName = name + "." + fieldName;

-

-					declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);

-					fieldRegisterIndex += fieldType.totalRegisterCount();

-				}

-				if(encoder)

-				{

-					encoder->exitAggregateType();

-				}

-			}

-		}

-	}

-

-	GLenum OutputASM::glVariableType(const TType &type)

-	{

-		switch(type.getBasicType())

-		{

-		case EbtFloat:

-			if(type.isScalar())

-			{

-				return GL_FLOAT;

-			}

-			else if(type.isVector())

-			{

-				switch(type.getNominalSize())

-				{

-				case 2: return GL_FLOAT_VEC2;

-				case 3: return GL_FLOAT_VEC3;

-				case 4: return GL_FLOAT_VEC4;

-				default: UNREACHABLE(type.getNominalSize());

-				}

-			}

-			else if(type.isMatrix())

-			{

-				switch(type.getNominalSize())

-				{

-				case 2:

-					switch(type.getSecondarySize())

-					{

-					case 2: return GL_FLOAT_MAT2;

-					case 3: return GL_FLOAT_MAT2x3;

-					case 4: return GL_FLOAT_MAT2x4;

-					default: UNREACHABLE(type.getSecondarySize());

-					}

-				case 3:

-					switch(type.getSecondarySize())

-					{

-					case 2: return GL_FLOAT_MAT3x2;

-					case 3: return GL_FLOAT_MAT3;

-					case 4: return GL_FLOAT_MAT3x4;

-					default: UNREACHABLE(type.getSecondarySize());

-					}

-				case 4:

-					switch(type.getSecondarySize())

-					{

-					case 2: return GL_FLOAT_MAT4x2;

-					case 3: return GL_FLOAT_MAT4x3;

-					case 4: return GL_FLOAT_MAT4;

-					default: UNREACHABLE(type.getSecondarySize());

-					}

-				default: UNREACHABLE(type.getNominalSize());

-				}

-			}

-			else UNREACHABLE(0);

-			break;

-		case EbtInt:

-			if(type.isScalar())

-			{

-				return GL_INT;

-			}

-			else if(type.isVector())

-			{

-				switch(type.getNominalSize())

-				{

-				case 2: return GL_INT_VEC2;

-				case 3: return GL_INT_VEC3;

-				case 4: return GL_INT_VEC4;

-				default: UNREACHABLE(type.getNominalSize());

-				}

-			}

-			else UNREACHABLE(0);

-			break;

-		case EbtUInt:

-			if(type.isScalar())

-			{

-				return GL_UNSIGNED_INT;

-			}

-			else if(type.isVector())

-			{

-				switch(type.getNominalSize())

-				{

-				case 2: return GL_UNSIGNED_INT_VEC2;

-				case 3: return GL_UNSIGNED_INT_VEC3;

-				case 4: return GL_UNSIGNED_INT_VEC4;

-				default: UNREACHABLE(type.getNominalSize());

-				}

-			}

-			else UNREACHABLE(0);

-			break;

-		case EbtBool:

-			if(type.isScalar())

-			{

-				return GL_BOOL;

-			}

-			else if(type.isVector())

-			{

-				switch(type.getNominalSize())

-				{

-				case 2: return GL_BOOL_VEC2;

-				case 3: return GL_BOOL_VEC3;

-				case 4: return GL_BOOL_VEC4;

-				default: UNREACHABLE(type.getNominalSize());

-				}

-			}

-			else UNREACHABLE(0);

-			break;

-		case EbtSampler2D:

-			return GL_SAMPLER_2D;

-		case EbtISampler2D:

-			return GL_INT_SAMPLER_2D;

-		case EbtUSampler2D:

-			return GL_UNSIGNED_INT_SAMPLER_2D;

-		case EbtSamplerCube:

-			return GL_SAMPLER_CUBE;

-		case EbtISamplerCube:

-			return GL_INT_SAMPLER_CUBE;

-		case EbtUSamplerCube:

-			return GL_UNSIGNED_INT_SAMPLER_CUBE;

-		case EbtSamplerExternalOES:

-			return GL_SAMPLER_EXTERNAL_OES;

-		case EbtSampler3D:

-			return GL_SAMPLER_3D_OES;

-		case EbtISampler3D:

-			return GL_INT_SAMPLER_3D;

-		case EbtUSampler3D:

-			return GL_UNSIGNED_INT_SAMPLER_3D;

-		case EbtSampler2DArray:

-			return GL_SAMPLER_2D_ARRAY;

-		case EbtISampler2DArray:

-			return GL_INT_SAMPLER_2D_ARRAY;

-		case EbtUSampler2DArray:

-			return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;

-		case EbtSampler2DShadow:

-			return GL_SAMPLER_2D_SHADOW;

-		case EbtSamplerCubeShadow:

-			return GL_SAMPLER_CUBE_SHADOW;

-		case EbtSampler2DArrayShadow:

-			return GL_SAMPLER_2D_ARRAY_SHADOW;

-		default:

-			UNREACHABLE(type.getBasicType());

-			break;

-		}

-

-		return GL_NONE;

-	}

-

-	GLenum OutputASM::glVariablePrecision(const TType &type)

-	{

-		if(type.getBasicType() == EbtFloat)

-		{

-			switch(type.getPrecision())

-			{

-			case EbpHigh:   return GL_HIGH_FLOAT;

-			case EbpMedium: return GL_MEDIUM_FLOAT;

-			case EbpLow:    return GL_LOW_FLOAT;

-			case EbpUndefined:

-				// Should be defined as the default precision by the parser

-			default: UNREACHABLE(type.getPrecision());

-			}

-		}

-		else if(type.getBasicType() == EbtInt)

-		{

-			switch(type.getPrecision())

-			{

-			case EbpHigh:   return GL_HIGH_INT;

-			case EbpMedium: return GL_MEDIUM_INT;

-			case EbpLow:    return GL_LOW_INT;

-			case EbpUndefined:

-				// Should be defined as the default precision by the parser

-			default: UNREACHABLE(type.getPrecision());

-			}

-		}

-

-		// Other types (boolean, sampler) don't have a precision

-		return GL_NONE;

-	}

-

-	int OutputASM::dim(TIntermNode *v)

-	{

-		TIntermTyped *vector = v->getAsTyped();

-		ASSERT(vector && vector->isRegister());

-		return vector->getNominalSize();

-	}

-

-	int OutputASM::dim2(TIntermNode *m)

-	{

-		TIntermTyped *matrix = m->getAsTyped();

-		ASSERT(matrix && matrix->isMatrix() && !matrix->isArray());

-		return matrix->getSecondarySize();

-	}

-

-	// Returns ~0u if no loop count could be determined

-	unsigned int OutputASM::loopCount(TIntermLoop *node)

-	{

-		// Parse loops of the form:

-		// for(int index = initial; index [comparator] limit; index += increment)

-		TIntermSymbol *index = 0;

-		TOperator comparator = EOpNull;

-		int initial = 0;

-		int limit = 0;

-		int increment = 0;

-

-		// Parse index name and intial value

-		if(node->getInit())

-		{

-			TIntermAggregate *init = node->getInit()->getAsAggregate();

-

-			if(init)

-			{

-				TIntermSequence &sequence = init->getSequence();

-				TIntermTyped *variable = sequence[0]->getAsTyped();

-

-				if(variable && variable->getQualifier() == EvqTemporary)

-				{

-					TIntermBinary *assign = variable->getAsBinaryNode();

-

-					if(assign->getOp() == EOpInitialize)

-					{

-						TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode();

-						TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion();

-

-						if(symbol && constant)

-						{

-							if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)

-							{

-								index = symbol;

-								initial = constant->getUnionArrayPointer()[0].getIConst();

-							}

-						}

-					}

-				}

-			}

-		}

-

-		// Parse comparator and limit value

-		if(index && node->getCondition())

-		{

-			TIntermBinary *test = node->getCondition()->getAsBinaryNode();

-

-			if(test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())

-			{

-				TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();

-

-				if(constant)

-				{

-					if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)

-					{

-						comparator = test->getOp();

-						limit = constant->getUnionArrayPointer()[0].getIConst();

-					}

-				}

-			}

-		}

-

-		// Parse increment

-		if(index && comparator != EOpNull && node->getExpression())

-		{

-			TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();

-			TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();

-

-			if(binaryTerminal)

-			{

-				TOperator op = binaryTerminal->getOp();

-				TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion();

-

-				if(constant)

-				{

-					if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)

-					{

-						int value = constant->getUnionArrayPointer()[0].getIConst();

-

-						switch(op)

-						{

-						case EOpAddAssign: increment = value;  break;

-						case EOpSubAssign: increment = -value; break;

-						default: UNIMPLEMENTED();

-						}

-					}

-				}

-			}

-			else if(unaryTerminal)

-			{

-				TOperator op = unaryTerminal->getOp();

-

-				switch(op)

-				{

-				case EOpPostIncrement: increment = 1;  break;

-				case EOpPostDecrement: increment = -1; break;

-				case EOpPreIncrement:  increment = 1;  break;

-				case EOpPreDecrement:  increment = -1; break;

-				default: UNIMPLEMENTED();

-				}

-			}

-		}

-

-		if(index && comparator != EOpNull && increment != 0)

-		{

-			if(comparator == EOpLessThanEqual)

-			{

-				comparator = EOpLessThan;

-				limit += 1;

-			}

-

-			if(comparator == EOpLessThan)

-			{

-				int iterations = (limit - initial) / increment;

-

-				if(iterations <= 0)

-				{

-					iterations = 0;

-				}

-

-				return iterations;

-			}

-			else UNIMPLEMENTED();   // Falls through

-		}

-

-		return ~0u;

-	}

-

-	bool LoopUnrollable::traverse(TIntermNode *node)

-	{

-		loopDepth = 0;

-		loopUnrollable = true;

-

-		node->traverse(this);

-

-		return loopUnrollable;

-	}

-

-	bool LoopUnrollable::visitLoop(Visit visit, TIntermLoop *loop)

-	{

-		if(visit == PreVisit)

-		{

-			loopDepth++;

-		}

-		else if(visit == PostVisit)

-		{

-			loopDepth++;

-		}

-

-		return true;

-	}

-

-	bool LoopUnrollable::visitBranch(Visit visit, TIntermBranch *node)

-	{

-		if(!loopUnrollable)

-		{

-			return false;

-		}

-

-		if(!loopDepth)

-		{

-			return true;

-		}

-

-		switch(node->getFlowOp())

-		{

-		case EOpKill:

-		case EOpReturn:

-			break;

-		case EOpBreak:

-		case EOpContinue:

-			loopUnrollable = false;

-			break;

-		default: UNREACHABLE(node->getFlowOp());

-		}

-

-		return loopUnrollable;

-	}

-

-	bool LoopUnrollable::visitAggregate(Visit visit, TIntermAggregate *node)

-	{

-		return loopUnrollable;

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "OutputASM.h"
+#include "Common/Math.hpp"
+
+#include "common/debug.h"
+#include "InfoSink.h"
+
+#include "libGLESv2/Shader.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+
+namespace glsl
+{
+	// Integer to TString conversion
+	TString str(int i)
+	{
+		char buffer[20];
+		sprintf(buffer, "%d", i);
+		return buffer;
+	}
+
+	class Temporary : public TIntermSymbol
+	{
+	public:
+		Temporary(OutputASM *assembler) : TIntermSymbol(TSymbolTableLevel::nextUniqueId(), "tmp", TType(EbtFloat, EbpHigh, EvqTemporary, 4, 1, false)), assembler(assembler)
+		{
+		}
+
+		~Temporary()
+		{
+			assembler->freeTemporary(this);
+		}
+
+	private:
+		OutputASM *const assembler;
+	};
+
+	class Constant : public TIntermConstantUnion
+	{
+	public:
+		Constant(float x, float y, float z, float w) : TIntermConstantUnion(constants, TType(EbtFloat, EbpHigh, EvqConstExpr, 4, 1, false))
+		{
+			constants[0].setFConst(x);
+			constants[1].setFConst(y);
+			constants[2].setFConst(z);
+			constants[3].setFConst(w);
+		}
+
+		Constant(bool b) : TIntermConstantUnion(constants, TType(EbtBool, EbpHigh, EvqConstExpr, 1, 1, false))
+		{
+			constants[0].setBConst(b);
+		}
+
+		Constant(int i) : TIntermConstantUnion(constants, TType(EbtInt, EbpHigh, EvqConstExpr, 1, 1, false))
+		{
+			constants[0].setIConst(i);
+		}
+
+		~Constant()
+		{
+		}
+
+	private:
+		ConstantUnion constants[4];
+	};
+
+	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo) :
+		type(type), precision(precision), name(name), arraySize(arraySize), registerIndex(registerIndex), blockId(blockId), blockInfo(blockMemberInfo)
+	{
+	}
+
+	UniformBlock::UniformBlock(const std::string& name, unsigned int dataSize, unsigned int arraySize,
+	                           TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId) :
+		name(name), dataSize(dataSize), arraySize(arraySize), layout(layout),
+		isRowMajorLayout(isRowMajorLayout), registerIndex(registerIndex), blockId(blockId)
+	{
+	}
+
+	BlockLayoutEncoder::BlockLayoutEncoder(bool rowMajor)
+		: mCurrentOffset(0), isRowMajor(rowMajor)
+	{
+	}
+
+	BlockMemberInfo BlockLayoutEncoder::encodeType(const TType &type)
+	{
+		int arrayStride;
+		int matrixStride;
+
+		getBlockLayoutInfo(type, type.getArraySize(), isRowMajor, &arrayStride, &matrixStride);
+
+		const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * BytesPerComponent),
+		                                 static_cast<int>(arrayStride * BytesPerComponent),
+		                                 static_cast<int>(matrixStride * BytesPerComponent),
+		                                 (matrixStride > 0) && isRowMajor);
+
+		advanceOffset(type, type.getArraySize(), isRowMajor, arrayStride, matrixStride);
+
+		return memberInfo;
+	}
+
+	// static
+	size_t BlockLayoutEncoder::getBlockRegister(const BlockMemberInfo &info)
+	{
+		return (info.offset / BytesPerComponent) / ComponentsPerRegister;
+	}
+
+	// static
+	size_t BlockLayoutEncoder::getBlockRegisterElement(const BlockMemberInfo &info)
+	{
+		return (info.offset / BytesPerComponent) % ComponentsPerRegister;
+	}
+
+	void BlockLayoutEncoder::nextRegister()
+	{
+		mCurrentOffset = sw::align(mCurrentOffset, ComponentsPerRegister);
+	}
+
+	Std140BlockEncoder::Std140BlockEncoder(bool rowMajor) : BlockLayoutEncoder(rowMajor)
+	{
+	}
+
+	void Std140BlockEncoder::enterAggregateType()
+	{
+		nextRegister();
+	}
+
+	void Std140BlockEncoder::exitAggregateType()
+	{
+		nextRegister();
+	}
+
+	void Std140BlockEncoder::getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
+	{
+		size_t baseAlignment = 0;
+		int matrixStride = 0;
+		int arrayStride = 0;
+
+		if(type.isMatrix())
+		{
+			baseAlignment = ComponentsPerRegister;
+			matrixStride = ComponentsPerRegister;
+
+			if(arraySize > 0)
+			{
+				const int numRegisters = isRowMajorMatrix ? type.getSecondarySize() : type.getNominalSize();
+				arrayStride = ComponentsPerRegister * numRegisters;
+			}
+		}
+		else if(arraySize > 0)
+		{
+			baseAlignment = ComponentsPerRegister;
+			arrayStride = ComponentsPerRegister;
+		}
+		else
+		{
+			const size_t numComponents = type.getElementSize();
+			baseAlignment = (numComponents == 3 ? 4u : numComponents);
+		}
+
+		mCurrentOffset = sw::align(mCurrentOffset, baseAlignment);
+
+		*matrixStrideOut = matrixStride;
+		*arrayStrideOut = arrayStride;
+	}
+
+	void Std140BlockEncoder::advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
+	{
+		if(arraySize > 0)
+		{
+			mCurrentOffset += arrayStride * arraySize;
+		}
+		else if(type.isMatrix())
+		{
+			ASSERT(matrixStride == ComponentsPerRegister);
+			const int numRegisters = isRowMajorMatrix ? type.getSecondarySize() : type.getNominalSize();
+			mCurrentOffset += ComponentsPerRegister * numRegisters;
+		}
+		else
+		{
+			mCurrentOffset += type.getElementSize();
+		}
+	}
+
+	Attribute::Attribute()
+	{
+		type = GL_NONE;
+		arraySize = 0;
+		registerIndex = 0;
+	}
+
+	Attribute::Attribute(GLenum type, const std::string &name, int arraySize, int location, int registerIndex)
+	{
+		this->type = type;
+		this->name = name;
+		this->arraySize = arraySize;
+		this->location = location;
+		this->registerIndex = registerIndex;
+	}
+
+	sw::PixelShader *Shader::getPixelShader() const
+	{
+		return 0;
+	}
+
+	sw::VertexShader *Shader::getVertexShader() const
+	{
+		return 0;
+	}
+
+	OutputASM::TextureFunction::TextureFunction(const TString& nodeName) : method(IMPLICIT), proj(false), offset(false)
+	{
+		TString name = TFunction::unmangleName(nodeName);
+
+		if(name == "texture2D" || name == "textureCube" || name == "texture" || name == "texture3D")
+		{
+			method = IMPLICIT;
+		}
+		else if(name == "texture2DProj" || name == "textureProj")
+		{
+			method = IMPLICIT;
+			proj = true;
+		}
+		else if(name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod")
+		{
+			method = LOD;
+		}
+		else if(name == "texture2DProjLod" || name == "textureProjLod")
+		{
+			method = LOD;
+			proj = true;
+		}
+		else if(name == "textureSize")
+		{
+			method = SIZE;
+		}
+		else if(name == "textureOffset")
+		{
+			method = IMPLICIT;
+			offset = true;
+		}
+		else if(name == "textureProjOffset")
+		{
+			method = IMPLICIT;
+			offset = true;
+			proj = true;
+		}
+		else if(name == "textureLodOffset")
+		{
+			method = LOD;
+			offset = true;
+		}
+		else if(name == "textureProjLodOffset")
+		{
+			method = LOD;
+			proj = true;
+			offset = true;
+		}
+		else if(name == "texelFetch")
+		{
+			method = FETCH;
+		}
+		else if(name == "texelFetchOffset")
+		{
+			method = FETCH;
+			offset = true;
+		}
+		else if(name == "textureGrad")
+		{
+			method = GRAD;
+		}
+		else if(name == "textureGradOffset")
+		{
+			method = GRAD;
+			offset = true;
+		}
+		else if(name == "textureProjGrad")
+		{
+			method = GRAD;
+			proj = true;
+		}
+		else if(name == "textureProjGradOffset")
+		{
+			method = GRAD;
+			proj = true;
+			offset = true;
+		}
+		else UNREACHABLE(0);
+	}
+
+	OutputASM::OutputASM(TParseContext &context, Shader *shaderObject) : TIntermTraverser(true, true, true), shaderObject(shaderObject), mContext(context)
+	{
+		shader = 0;
+		pixelShader = 0;
+		vertexShader = 0;
+
+		if(shaderObject)
+		{
+			shader = shaderObject->getShader();
+			pixelShader = shaderObject->getPixelShader();
+			vertexShader = shaderObject->getVertexShader();
+		}
+
+		functionArray.push_back(Function(0, "main(", 0, 0));
+		currentFunction = 0;
+		outputQualifier = EvqOutput; // Set outputQualifier to any value other than EvqFragColor or EvqFragData
+	}
+
+	OutputASM::~OutputASM()
+	{
+	}
+
+	void OutputASM::output()
+	{
+		if(shader)
+		{
+			emitShader(GLOBAL);
+
+			if(functionArray.size() > 1)   // Only call main() when there are other functions
+			{
+				Instruction *callMain = emit(sw::Shader::OPCODE_CALL);
+				callMain->dst.type = sw::Shader::PARAMETER_LABEL;
+				callMain->dst.index = 0;   // main()
+
+				emit(sw::Shader::OPCODE_RET);
+			}
+
+			emitShader(FUNCTION);
+		}
+	}
+
+	void OutputASM::emitShader(Scope scope)
+	{
+		emitScope = scope;
+		currentScope = GLOBAL;
+		mContext.getTreeRoot()->traverse(this);
+	}
+
+	void OutputASM::freeTemporary(Temporary *temporary)
+	{
+		free(temporaries, temporary);
+	}
+
+	sw::Shader::Opcode OutputASM::getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const
+	{
+		TBasicType baseType = in->getType().getBasicType();
+
+		switch(op)
+		{
+		case sw::Shader::OPCODE_NEG:
+			switch(baseType)
+			{
+			case EbtInt:
+			case EbtUInt:
+				return sw::Shader::OPCODE_INEG;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_ABS:
+			switch(baseType)
+			{
+			case EbtInt:
+				return sw::Shader::OPCODE_IABS;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_SGN:
+			switch(baseType)
+			{
+			case EbtInt:
+				return sw::Shader::OPCODE_ISGN;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_ADD:
+			switch(baseType)
+			{
+			case EbtInt:
+			case EbtUInt:
+				return sw::Shader::OPCODE_IADD;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_SUB:
+			switch(baseType)
+			{
+			case EbtInt:
+			case EbtUInt:
+				return sw::Shader::OPCODE_ISUB;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_MUL:
+			switch(baseType)
+			{
+			case EbtInt:
+			case EbtUInt:
+				return sw::Shader::OPCODE_IMUL;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_DIV:
+			switch(baseType)
+			{
+			case EbtInt:
+				return sw::Shader::OPCODE_IDIV;
+			case EbtUInt:
+				return sw::Shader::OPCODE_UDIV;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_IMOD:
+			return baseType == EbtUInt ? sw::Shader::OPCODE_UMOD : op;
+		case sw::Shader::OPCODE_ISHR:
+			return baseType == EbtUInt ? sw::Shader::OPCODE_USHR : op;
+		case sw::Shader::OPCODE_MIN:
+			switch(baseType)
+			{
+			case EbtInt:
+				return sw::Shader::OPCODE_IMIN;
+			case EbtUInt:
+				return sw::Shader::OPCODE_UMIN;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		case sw::Shader::OPCODE_MAX:
+			switch(baseType)
+			{
+			case EbtInt:
+				return sw::Shader::OPCODE_IMAX;
+			case EbtUInt:
+				return sw::Shader::OPCODE_UMAX;
+			case EbtFloat:
+			default:
+				return op;
+			}
+		default:
+			return op;
+		}
+	}
+
+	void OutputASM::visitSymbol(TIntermSymbol *symbol)
+	{
+		// Vertex varyings don't have to be actively used to successfully link
+		// against pixel shaders that use them. So make sure they're declared.
+		if(symbol->getQualifier() == EvqVaryingOut || symbol->getQualifier() == EvqInvariantVaryingOut || symbol->getQualifier() == EvqVertexOut)
+		{
+			if(symbol->getBasicType() != EbtInvariant)   // Typeless declarations are not new varyings
+			{
+				declareVarying(symbol, -1);
+			}
+		}
+
+		TInterfaceBlock* block = symbol->getType().getInterfaceBlock();
+		// OpenGL ES 3.0.4 spec, section 2.12.6 Uniform Variables:
+		// "All members of a named uniform block declared with a shared or std140 layout qualifier
+		// are considered active, even if they are not referenced in any shader in the program.
+		// The uniform block itself is also considered active, even if no member of the block is referenced."
+		if(block && ((block->blockStorage() == EbsShared) || (block->blockStorage() == EbsStd140)))
+		{
+			uniformRegister(symbol);
+		}
+	}
+
+	bool OutputASM::visitBinary(Visit visit, TIntermBinary *node)
+	{
+		if(currentScope != emitScope)
+		{
+			return false;
+		}
+
+		TIntermTyped *result = node;
+		TIntermTyped *left = node->getLeft();
+		TIntermTyped *right = node->getRight();
+		const TType &leftType = left->getType();
+		const TType &rightType = right->getType();
+		const TType &resultType = node->getType();
+
+		if(isSamplerRegister(result))
+		{
+			return false;   // Don't traverse, the register index is determined statically
+		}
+
+		switch(node->getOp())
+		{
+		case EOpAssign:
+			if(visit == PostVisit)
+			{
+				assignLvalue(left, right);
+				copy(result, right);
+			}
+			break;
+		case EOpInitialize:
+			if(visit == PostVisit)
+			{
+				copy(left, right);
+			}
+			break;
+		case EOpMatrixTimesScalarAssign:
+			if(visit == PostVisit)
+			{
+				for(int i = 0; i < leftType.getNominalSize(); i++)
+				{
+					emit(sw::Shader::OPCODE_MUL, result, i, left, i, right);
+				}
+
+				assignLvalue(left, result);
+			}
+			break;
+		case EOpVectorTimesMatrixAssign:
+			if(visit == PostVisit)
+			{
+				int size = leftType.getNominalSize();
+
+				for(int i = 0; i < size; i++)
+				{
+					Instruction *dot = emit(sw::Shader::OPCODE_DP(size), result, 0, left, 0, right, i);
+					dot->dst.mask = 1 << i;
+				}
+
+				assignLvalue(left, result);
+			}
+			break;
+		case EOpMatrixTimesMatrixAssign:
+			if(visit == PostVisit)
+			{
+				int dim = leftType.getNominalSize();
+
+				for(int i = 0; i < dim; i++)
+				{
+					Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, i, left, 0, right, i);
+					mul->src[1].swizzle = 0x00;
+
+					for(int j = 1; j < dim; j++)
+					{
+						Instruction *mad = emit(sw::Shader::OPCODE_MAD, result, i, left, j, right, i, result, i);
+						mad->src[1].swizzle = j * 0x55;
+					}
+				}
+
+				assignLvalue(left, result);
+			}
+			break;
+		case EOpIndexDirect:
+			if(visit == PostVisit)
+			{
+				int index = right->getAsConstantUnion()->getIConst(0);
+
+				if(result->isMatrix() || result->isStruct() || result->isInterfaceBlock())
+				{
+					ASSERT(left->isArray());
+					copy(result, left, index * left->elementRegisterCount());
+				}
+				else if(result->isRegister())
+				{
+					int srcIndex = 0;
+					if(left->isRegister())
+					{
+						srcIndex = 0;
+					}
+					else if(left->isArray())
+					{
+						srcIndex = index * left->elementRegisterCount();
+					}
+					else if(left->isMatrix())
+					{
+						ASSERT(index < left->getNominalSize());   // FIXME: Report semantic error
+						srcIndex = index;
+					}
+					else UNREACHABLE(0);
+
+					Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, 0, left, srcIndex);
+
+					if(left->isRegister())
+					{
+						mov->src[0].swizzle = index;
+					}
+				}
+				else UNREACHABLE(0);
+			}
+			break;
+		case EOpIndexIndirect:
+			if(visit == PostVisit)
+			{
+				if(left->isArray() || left->isMatrix())
+				{
+					for(int index = 0; index < result->totalRegisterCount(); index++)
+					{
+						Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, index, left, index);
+						mov->dst.mask = writeMask(result, index);
+
+						if(left->totalRegisterCount() > 1)
+						{
+							sw::Shader::SourceParameter relativeRegister;
+							argument(relativeRegister, right);
+
+							mov->src[0].rel.type = relativeRegister.type;
+							mov->src[0].rel.index = relativeRegister.index;
+							mov->src[0].rel.scale =	result->totalRegisterCount();
+							mov->src[0].rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
+						}
+					}
+				}
+				else if(left->isRegister())
+				{
+					emit(sw::Shader::OPCODE_EXTRACT, result, left, right);
+				}
+				else UNREACHABLE(0);
+			}
+			break;
+		case EOpIndexDirectStruct:
+		case EOpIndexDirectInterfaceBlock:
+			if(visit == PostVisit)
+			{
+				ASSERT(leftType.isStruct() || (leftType.isInterfaceBlock()));
+
+				const TFieldList& fields = (node->getOp() == EOpIndexDirectStruct) ?
+				                           leftType.getStruct()->fields() :
+				                           leftType.getInterfaceBlock()->fields();
+				int index = right->getAsConstantUnion()->getIConst(0);
+				int fieldOffset = 0;
+
+				for(int i = 0; i < index; i++)
+				{
+					fieldOffset += fields[i]->type()->totalRegisterCount();
+				}
+
+				copy(result, left, fieldOffset);
+			}
+			break;
+		case EOpVectorSwizzle:
+			if(visit == PostVisit)
+			{
+				int swizzle = 0;
+				TIntermAggregate *components = right->getAsAggregate();
+
+				if(components)
+				{
+					TIntermSequence &sequence = components->getSequence();
+					int component = 0;
+
+					for(TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+					{
+						TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
+
+						if(element)
+						{
+							int i = element->getUnionArrayPointer()[0].getIConst();
+							swizzle |= i << (component * 2);
+							component++;
+						}
+						else UNREACHABLE(0);
+					}
+				}
+				else UNREACHABLE(0);
+
+				Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, left);
+				mov->src[0].swizzle = swizzle;
+			}
+			break;
+		case EOpAddAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_ADD, result), result, left, left, right); break;
+		case EOpAdd:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_ADD, result), result, left, right);       break;
+		case EOpSubAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_SUB, result), result, left, left, right); break;
+		case EOpSub:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_SUB, result), result, left, right);       break;
+		case EOpMulAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_MUL, result), result, left, left, right); break;
+		case EOpMul:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_MUL, result), result, left, right);       break;
+		case EOpDivAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_DIV, result), result, left, left, right); break;
+		case EOpDiv:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_DIV, result), result, left, right);       break;
+		case EOpIModAssign:          if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_IMOD, result), result, left, left, right); break;
+		case EOpIMod:                if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_IMOD, result), result, left, right);       break;
+		case EOpBitShiftLeftAssign:  if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_SHL, result, left, left, right); break;
+		case EOpBitShiftLeft:        if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_SHL, result, left, right);       break;
+		case EOpBitShiftRightAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_ISHR, result), result, left, left, right); break;
+		case EOpBitShiftRight:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_ISHR, result), result, left, right);       break;
+		case EOpBitwiseAndAssign:    if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_AND, result, left, left, right); break;
+		case EOpBitwiseAnd:          if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_AND, result, left, right);       break;
+		case EOpBitwiseXorAssign:    if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_XOR, result, left, left, right); break;
+		case EOpBitwiseXor:          if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_XOR, result, left, right);       break;
+		case EOpBitwiseOrAssign:     if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_OR, result, left, left, right);  break;
+		case EOpBitwiseOr:           if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_OR, result, left, right);        break;
+		case EOpEqual:
+			if(visit == PostVisit)
+			{
+				emitBinary(sw::Shader::OPCODE_EQ, result, left, right);
+
+				for(int index = 1; index < left->totalRegisterCount(); index++)
+				{
+					Temporary equal(this);
+					emit(sw::Shader::OPCODE_EQ, &equal, 0, left, index, right, index);
+					emit(sw::Shader::OPCODE_AND, result, result, &equal);
+				}
+			}
+			break;
+		case EOpNotEqual:
+			if(visit == PostVisit)
+			{
+				emitBinary(sw::Shader::OPCODE_NE, result, left, right);
+
+				for(int index = 1; index < left->totalRegisterCount(); index++)
+				{
+					Temporary notEqual(this);
+					emit(sw::Shader::OPCODE_NE, &notEqual, 0, left, index, right, index);
+					emit(sw::Shader::OPCODE_OR, result, result, &notEqual);
+				}
+			}
+			break;
+		case EOpLessThan:                if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LT, result, left, right); break;
+		case EOpGreaterThan:             if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GT, result, left, right); break;
+		case EOpLessThanEqual:           if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LE, result, left, right); break;
+		case EOpGreaterThanEqual:        if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GE, result, left, right); break;
+		case EOpVectorTimesScalarAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_MUL, left), result, left, left, right); break;
+		case EOpVectorTimesScalar:       if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MUL, left), result, left, right); break;
+		case EOpMatrixTimesScalar:
+			if(visit == PostVisit)
+			{
+				if(left->isMatrix())
+				{
+					for(int i = 0; i < leftType.getNominalSize(); i++)
+					{
+						emit(sw::Shader::OPCODE_MUL, result, i, left, i, right, 0);
+					}
+				}
+				else if(right->isMatrix())
+				{
+					for(int i = 0; i < rightType.getNominalSize(); i++)
+					{
+						emit(sw::Shader::OPCODE_MUL, result, i, left, 0, right, i);
+					}
+				}
+				else UNREACHABLE(0);
+			}
+			break;
+		case EOpVectorTimesMatrix:
+			if(visit == PostVisit)
+			{
+				sw::Shader::Opcode dpOpcode = sw::Shader::OPCODE_DP(leftType.getNominalSize());
+
+				int size = rightType.getNominalSize();
+				for(int i = 0; i < size; i++)
+				{
+					Instruction *dot = emit(dpOpcode, result, 0, left, 0, right, i);
+					dot->dst.mask = 1 << i;
+				}
+			}
+			break;
+		case EOpMatrixTimesVector:
+			if(visit == PostVisit)
+			{
+				Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, left, right);
+				mul->src[1].swizzle = 0x00;
+
+				int size = rightType.getNominalSize();
+				for(int i = 1; i < size; i++)
+				{
+					Instruction *mad = emit(sw::Shader::OPCODE_MAD, result, 0, left, i, right, 0, result);
+					mad->src[1].swizzle = i * 0x55;
+				}
+			}
+			break;
+		case EOpMatrixTimesMatrix:
+			if(visit == PostVisit)
+			{
+				int dim = leftType.getNominalSize();
+
+				int size = rightType.getNominalSize();
+				for(int i = 0; i < size; i++)
+				{
+					Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, i, left, 0, right, i);
+					mul->src[1].swizzle = 0x00;
+
+					for(int j = 1; j < dim; j++)
+					{
+						Instruction *mad = emit(sw::Shader::OPCODE_MAD, result, i, left, j, right, i, result, i);
+						mad->src[1].swizzle = j * 0x55;
+					}
+				}
+			}
+			break;
+		case EOpLogicalOr:
+			if(trivial(right, 6))
+			{
+				if(visit == PostVisit)
+				{
+					emit(sw::Shader::OPCODE_OR, result, left, right);
+				}
+			}
+			else   // Short-circuit evaluation
+			{
+				if(visit == InVisit)
+				{
+					emit(sw::Shader::OPCODE_MOV, result, left);
+					Instruction *ifnot = emit(sw::Shader::OPCODE_IF, 0, result);
+					ifnot->src[0].modifier = sw::Shader::MODIFIER_NOT;
+				}
+				else if(visit == PostVisit)
+				{
+					emit(sw::Shader::OPCODE_MOV, result, right);
+					emit(sw::Shader::OPCODE_ENDIF);
+				}
+			}
+			break;
+		case EOpLogicalXor:        if(visit == PostVisit) emit(sw::Shader::OPCODE_XOR, result, left, right); break;
+		case EOpLogicalAnd:
+			if(trivial(right, 6))
+			{
+				if(visit == PostVisit)
+				{
+					emit(sw::Shader::OPCODE_AND, result, left, right);
+				}
+			}
+			else   // Short-circuit evaluation
+			{
+				if(visit == InVisit)
+				{
+					emit(sw::Shader::OPCODE_MOV, result, left);
+					emit(sw::Shader::OPCODE_IF, 0, result);
+				}
+				else if(visit == PostVisit)
+				{
+					emit(sw::Shader::OPCODE_MOV, result, right);
+					emit(sw::Shader::OPCODE_ENDIF);
+				}
+			}
+			break;
+		default: UNREACHABLE(node->getOp());
+		}
+
+		return true;
+	}
+
+	void OutputASM::emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col, int row, int outCol, int outRow)
+	{
+		switch(size)
+		{
+		case 1: // Used for cofactor computation only
+			{
+				// For a 2x2 matrix, the cofactor is simply a transposed move or negate
+				bool isMov = (row == col);
+				sw::Shader::Opcode op = isMov ? sw::Shader::OPCODE_MOV : sw::Shader::OPCODE_NEG;
+				Instruction *mov = emit(op, result, outCol, arg, isMov ? 1 - row : row);
+				mov->src[0].swizzle = 0x55 * (isMov ? 1 - col : col);
+				mov->dst.mask = 1 << outRow;
+			}
+			break;
+		case 2:
+			{
+				static const unsigned int swizzle[3] = { 0x99, 0x88, 0x44 }; // xy?? : yzyz, xzxz, xyxy
+
+				bool isCofactor = (col >= 0) && (row >= 0);
+				int col0 = (isCofactor && (col <= 0)) ? 1 : 0;
+				int col1 = (isCofactor && (col <= 1)) ? 2 : 1;
+				bool negate = isCofactor && ((col & 0x01) ^ (row & 0x01));
+
+				Instruction *det = emit(sw::Shader::OPCODE_DET2, result, outCol, arg, negate ? col1 : col0, arg, negate ? col0 : col1);
+				det->src[0].swizzle = det->src[1].swizzle = swizzle[isCofactor ? row : 2];
+				det->dst.mask = 1 << outRow;
+			}
+			break;
+		case 3:
+			{
+				static const unsigned int swizzle[4] = { 0xF9, 0xF8, 0xF4, 0xE4 }; // xyz? : yzww, xzww, xyww, xyzw
+
+				bool isCofactor = (col >= 0) && (row >= 0);
+				int col0 = (isCofactor && (col <= 0)) ? 1 : 0;
+				int col1 = (isCofactor && (col <= 1)) ? 2 : 1;
+				int col2 = (isCofactor && (col <= 2)) ? 3 : 2;
+				bool negate = isCofactor && ((col & 0x01) ^ (row & 0x01));
+
+				Instruction *det = emit(sw::Shader::OPCODE_DET3, result, outCol, arg, col0, arg, negate ? col2 : col1, arg, negate ? col1 : col2);
+				det->src[0].swizzle = det->src[1].swizzle = det->src[2].swizzle = swizzle[isCofactor ? row : 3];
+				det->dst.mask = 1 << outRow;
+			}
+			break;
+		case 4:
+			{
+				Instruction *det = emit(sw::Shader::OPCODE_DET4, result, outCol, arg, 0, arg, 1, arg, 2, arg, 3);
+				det->dst.mask = 1 << outRow;
+			}
+			break;
+		default:
+			UNREACHABLE(size);
+			break;
+		}
+	}
+
+	bool OutputASM::visitUnary(Visit visit, TIntermUnary *node)
+	{
+		if(currentScope != emitScope)
+		{
+			return false;
+		}
+
+		TIntermTyped *result = node;
+		TIntermTyped *arg = node->getOperand();
+		TBasicType basicType = arg->getType().getBasicType();
+
+		union
+		{
+			float f;
+			int i;
+		} one_value;
+
+		if(basicType == EbtInt || basicType == EbtUInt)
+		{
+			one_value.i = 1;
+		}
+		else
+		{
+			one_value.f = 1.0f;
+		}
+
+		Constant one(one_value.f, one_value.f, one_value.f, one_value.f);
+		Constant rad(1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f);
+		Constant deg(5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f);
+
+		switch(node->getOp())
+		{
+		case EOpNegative:
+			if(visit == PostVisit)
+			{
+				sw::Shader::Opcode negOpcode = getOpcode(sw::Shader::OPCODE_NEG, arg);
+				for(int index = 0; index < arg->totalRegisterCount(); index++)
+				{
+					emit(negOpcode, result, index, arg, index);
+				}
+			}
+			break;
+		case EOpVectorLogicalNot: if(visit == PostVisit) emit(sw::Shader::OPCODE_NOT, result, arg); break;
+		case EOpLogicalNot:       if(visit == PostVisit) emit(sw::Shader::OPCODE_NOT, result, arg); break;
+		case EOpPostIncrement:
+			if(visit == PostVisit)
+			{
+				copy(result, arg);
+
+				sw::Shader::Opcode addOpcode = getOpcode(sw::Shader::OPCODE_ADD, arg);
+				for(int index = 0; index < arg->totalRegisterCount(); index++)
+				{
+					emit(addOpcode, arg, index, arg, index, &one);
+				}
+
+				assignLvalue(arg, arg);
+			}
+			break;
+		case EOpPostDecrement:
+			if(visit == PostVisit)
+			{
+				copy(result, arg);
+
+				sw::Shader::Opcode subOpcode = getOpcode(sw::Shader::OPCODE_SUB, arg);
+				for(int index = 0; index < arg->totalRegisterCount(); index++)
+				{
+					emit(subOpcode, arg, index, arg, index, &one);
+				}
+
+				assignLvalue(arg, arg);
+			}
+			break;
+		case EOpPreIncrement:
+			if(visit == PostVisit)
+			{
+				sw::Shader::Opcode addOpcode = getOpcode(sw::Shader::OPCODE_ADD, arg);
+				for(int index = 0; index < arg->totalRegisterCount(); index++)
+				{
+					emit(addOpcode, result, index, arg, index, &one);
+				}
+
+				assignLvalue(arg, result);
+			}
+			break;
+		case EOpPreDecrement:
+			if(visit == PostVisit)
+			{
+				sw::Shader::Opcode subOpcode = getOpcode(sw::Shader::OPCODE_SUB, arg);
+				for(int index = 0; index < arg->totalRegisterCount(); index++)
+				{
+					emit(subOpcode, result, index, arg, index, &one);
+				}
+
+				assignLvalue(arg, result);
+			}
+			break;
+		case EOpRadians:          if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, arg, &rad); break;
+		case EOpDegrees:          if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, arg, &deg); break;
+		case EOpSin:              if(visit == PostVisit) emit(sw::Shader::OPCODE_SIN, result, arg); break;
+		case EOpCos:              if(visit == PostVisit) emit(sw::Shader::OPCODE_COS, result, arg); break;
+		case EOpTan:              if(visit == PostVisit) emit(sw::Shader::OPCODE_TAN, result, arg); break;
+		case EOpAsin:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ASIN, result, arg); break;
+		case EOpAcos:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ACOS, result, arg); break;
+		case EOpAtan:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ATAN, result, arg); break;
+		case EOpSinh:             if(visit == PostVisit) emit(sw::Shader::OPCODE_SINH, result, arg); break;
+		case EOpCosh:             if(visit == PostVisit) emit(sw::Shader::OPCODE_COSH, result, arg); break;
+		case EOpTanh:             if(visit == PostVisit) emit(sw::Shader::OPCODE_TANH, result, arg); break;
+		case EOpAsinh:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ASINH, result, arg); break;
+		case EOpAcosh:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ACOSH, result, arg); break;
+		case EOpAtanh:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ATANH, result, arg); break;
+		case EOpExp:              if(visit == PostVisit) emit(sw::Shader::OPCODE_EXP, result, arg); break;
+		case EOpLog:              if(visit == PostVisit) emit(sw::Shader::OPCODE_LOG, result, arg); break;
+		case EOpExp2:             if(visit == PostVisit) emit(sw::Shader::OPCODE_EXP2, result, arg); break;
+		case EOpLog2:             if(visit == PostVisit) emit(sw::Shader::OPCODE_LOG2, result, arg); break;
+		case EOpSqrt:             if(visit == PostVisit) emit(sw::Shader::OPCODE_SQRT, result, arg); break;
+		case EOpInverseSqrt:      if(visit == PostVisit) emit(sw::Shader::OPCODE_RSQ, result, arg); break;
+		case EOpAbs:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_ABS, result), result, arg); break;
+		case EOpSign:             if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_SGN, result), result, arg); break;
+		case EOpFloor:            if(visit == PostVisit) emit(sw::Shader::OPCODE_FLOOR, result, arg); break;
+		case EOpTrunc:            if(visit == PostVisit) emit(sw::Shader::OPCODE_TRUNC, result, arg); break;
+		case EOpRound:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ROUND, result, arg); break;
+		case EOpRoundEven:        if(visit == PostVisit) emit(sw::Shader::OPCODE_ROUNDEVEN, result, arg); break;
+		case EOpCeil:             if(visit == PostVisit) emit(sw::Shader::OPCODE_CEIL, result, arg, result); break;
+		case EOpFract:            if(visit == PostVisit) emit(sw::Shader::OPCODE_FRC, result, arg); break;
+		case EOpIsNan:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ISNAN, result, arg); break;
+		case EOpIsInf:            if(visit == PostVisit) emit(sw::Shader::OPCODE_ISINF, result, arg); break;
+		case EOpLength:           if(visit == PostVisit) emit(sw::Shader::OPCODE_LEN(dim(arg)), result, arg); break;
+		case EOpNormalize:        if(visit == PostVisit) emit(sw::Shader::OPCODE_NRM(dim(arg)), result, arg); break;
+		case EOpDFdx:             if(visit == PostVisit) emit(sw::Shader::OPCODE_DFDX, result, arg); break;
+		case EOpDFdy:             if(visit == PostVisit) emit(sw::Shader::OPCODE_DFDY, result, arg); break;
+		case EOpFwidth:           if(visit == PostVisit) emit(sw::Shader::OPCODE_FWIDTH, result, arg); break;
+		case EOpAny:              if(visit == PostVisit) emit(sw::Shader::OPCODE_ANY, result, arg); break;
+		case EOpAll:              if(visit == PostVisit) emit(sw::Shader::OPCODE_ALL, result, arg); break;
+		case EOpFloatBitsToInt:   if(visit == PostVisit) emit(sw::Shader::OPCODE_FLOATBITSTOINT, result, arg); break;
+		case EOpFloatBitsToUint:  if(visit == PostVisit) emit(sw::Shader::OPCODE_FLOATBITSTOUINT, result, arg); break;
+		case EOpIntBitsToFloat:   if(visit == PostVisit) emit(sw::Shader::OPCODE_INTBITSTOFLOAT, result, arg); break;
+		case EOpUintBitsToFloat:  if(visit == PostVisit) emit(sw::Shader::OPCODE_UINTBITSTOFLOAT, result, arg); break;
+		case EOpPackSnorm2x16:    if(visit == PostVisit) emit(sw::Shader::OPCODE_PACKSNORM2x16, result, arg); break;
+		case EOpPackUnorm2x16:    if(visit == PostVisit) emit(sw::Shader::OPCODE_PACKUNORM2x16, result, arg); break;
+		case EOpPackHalf2x16:     if(visit == PostVisit) emit(sw::Shader::OPCODE_PACKHALF2x16, result, arg); break;
+		case EOpUnpackSnorm2x16:  if(visit == PostVisit) emit(sw::Shader::OPCODE_UNPACKSNORM2x16, result, arg); break;
+		case EOpUnpackUnorm2x16:  if(visit == PostVisit) emit(sw::Shader::OPCODE_UNPACKUNORM2x16, result, arg); break;
+		case EOpUnpackHalf2x16:   if(visit == PostVisit) emit(sw::Shader::OPCODE_UNPACKHALF2x16, result, arg); break;
+		case EOpTranspose:
+			if(visit == PostVisit)
+			{
+				int numCols = arg->getNominalSize();
+				int numRows = arg->getSecondarySize();
+				for(int i = 0; i < numCols; ++i)
+				{
+					for(int j = 0; j < numRows; ++j)
+					{
+						Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, j, arg, i);
+						mov->src[0].swizzle = 0x55 * j;
+						mov->dst.mask = 1 << i;
+					}
+				}
+			}
+			break;
+		case EOpDeterminant:
+			if(visit == PostVisit)
+			{
+				int size = arg->getNominalSize();
+				ASSERT(size == arg->getSecondarySize());
+
+				emitDeterminant(result, arg, size);
+			}
+			break;
+		case EOpInverse:
+			if(visit == PostVisit)
+			{
+				int size = arg->getNominalSize();
+				ASSERT(size == arg->getSecondarySize());
+
+				// Compute transposed matrix of cofactors
+				for(int i = 0; i < size; ++i)
+				{
+					for(int j = 0; j < size; ++j)
+					{
+						// For a 2x2 matrix, the cofactor is simply a transposed move or negate
+						// For a 3x3 or 4x4 matrix, the cofactor is a transposed determinant
+						emitDeterminant(result, arg, size - 1, j, i, i, j);
+					}
+				}
+
+				// Compute 1 / determinant
+				Temporary invDet(this);
+				emitDeterminant(&invDet, arg, size);
+				Constant one(1.0f, 1.0f, 1.0f, 1.0f);
+				Instruction *div = emit(sw::Shader::OPCODE_DIV, &invDet, &one, &invDet);
+				div->src[1].swizzle = 0x00; // xxxx
+
+				// Divide transposed matrix of cofactors by determinant
+				for(int i = 0; i < size; ++i)
+				{
+					emit(sw::Shader::OPCODE_MUL, result, i, result, i, &invDet);
+				}
+			}
+			break;
+		default: UNREACHABLE(node->getOp());
+		}
+
+		return true;
+	}
+
+	bool OutputASM::visitAggregate(Visit visit, TIntermAggregate *node)
+	{
+		if(currentScope != emitScope && node->getOp() != EOpFunction && node->getOp() != EOpSequence)
+		{
+			return false;
+		}
+
+		Constant zero(0.0f, 0.0f, 0.0f, 0.0f);
+
+		TIntermTyped *result = node;
+		const TType &resultType = node->getType();
+		TIntermSequence &arg = node->getSequence();
+		size_t argumentCount = arg.size();
+
+		switch(node->getOp())
+		{
+		case EOpSequence:             break;
+		case EOpDeclaration:          break;
+		case EOpInvariantDeclaration: break;
+		case EOpPrototype:            break;
+		case EOpComma:
+			if(visit == PostVisit)
+			{
+				copy(result, arg[1]);
+			}
+			break;
+		case EOpFunction:
+			if(visit == PreVisit)
+			{
+				const TString &name = node->getName();
+
+				if(emitScope == FUNCTION)
+				{
+					if(functionArray.size() > 1)   // No need for a label when there's only main()
+					{
+						Instruction *label = emit(sw::Shader::OPCODE_LABEL);
+						label->dst.type = sw::Shader::PARAMETER_LABEL;
+
+						const Function *function = findFunction(name);
+						ASSERT(function);   // Should have been added during global pass
+						label->dst.index = function->label;
+						currentFunction = function->label;
+					}
+				}
+				else if(emitScope == GLOBAL)
+				{
+					if(name != "main(")
+					{
+						TIntermSequence &arguments = node->getSequence()[0]->getAsAggregate()->getSequence();
+						functionArray.push_back(Function(functionArray.size(), name, &arguments, node));
+					}
+				}
+				else UNREACHABLE(emitScope);
+
+				currentScope = FUNCTION;
+			}
+			else if(visit == PostVisit)
+			{
+				if(emitScope == FUNCTION)
+				{
+					if(functionArray.size() > 1)   // No need to return when there's only main()
+					{
+						emit(sw::Shader::OPCODE_RET);
+					}
+				}
+
+				currentScope = GLOBAL;
+			}
+			break;
+		case EOpFunctionCall:
+			if(visit == PostVisit)
+			{
+				if(node->isUserDefined())
+				{
+					const TString &name = node->getName();
+					const Function *function = findFunction(name);
+
+					if(!function)
+					{
+						mContext.error(node->getLine(), "function definition not found", name.c_str());
+						return false;
+					}
+
+					TIntermSequence &arguments = *function->arg;
+
+					for(size_t i = 0; i < argumentCount; i++)
+					{
+						TIntermTyped *in = arguments[i]->getAsTyped();
+
+						if(in->getQualifier() == EvqIn ||
+						   in->getQualifier() == EvqInOut ||
+						   in->getQualifier() == EvqConstReadOnly)
+						{
+							copy(in, arg[i]);
+						}
+					}
+
+					Instruction *call = emit(sw::Shader::OPCODE_CALL);
+					call->dst.type = sw::Shader::PARAMETER_LABEL;
+					call->dst.index = function->label;
+
+					if(function->ret && function->ret->getType().getBasicType() != EbtVoid)
+					{
+						copy(result, function->ret);
+					}
+
+					for(size_t i = 0; i < argumentCount; i++)
+					{
+						TIntermTyped *argument = arguments[i]->getAsTyped();
+						TIntermTyped *out = arg[i]->getAsTyped();
+
+						if(argument->getQualifier() == EvqOut ||
+						   argument->getQualifier() == EvqInOut)
+						{
+							copy(out, argument);
+						}
+					}
+				}
+				else
+				{
+					const TextureFunction textureFunction(node->getName());
+					TIntermTyped *t = arg[1]->getAsTyped();
+
+					Temporary coord(this);
+
+					if(textureFunction.proj)
+					{
+						TIntermConstantUnion* constant = arg[1]->getAsConstantUnion();
+						if(constant)
+						{
+							float projFactor = 1.0f / constant->getFConst(t->getNominalSize() - 1);
+							Constant projCoord(constant->getFConst(0) * projFactor,
+							                   constant->getFConst(1) * projFactor,
+							                   constant->getFConst(2) * projFactor,
+							                   0.0f);
+							emit(sw::Shader::OPCODE_MOV, &coord, &projCoord);
+						}
+						else
+						{
+							Instruction *rcp = emit(sw::Shader::OPCODE_RCPX, &coord, arg[1]);
+							rcp->src[0].swizzle = 0x55 * (t->getNominalSize() - 1);
+							rcp->dst.mask = 0x7;
+
+							Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);
+							mul->dst.mask = 0x7;
+						}
+					}
+					else
+					{
+						emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);
+					}
+
+					switch(textureFunction.method)
+					{
+					case TextureFunction::IMPLICIT:
+						{
+							TIntermNode* offset = textureFunction.offset ? arg[2] : 0;
+
+							if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))
+							{
+								Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
+								                        result, &coord, arg[0], offset);
+							}
+							else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))   // bias
+							{
+								Instruction *bias = emit(sw::Shader::OPCODE_MOV, &coord, arg[textureFunction.offset ? 3 : 2]);
+								bias->dst.mask = 0x8;
+
+								Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
+								                        result, &coord, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction
+								tex->bias = true;
+							}
+							else UNREACHABLE(argumentCount);
+						}
+						break;
+					case TextureFunction::LOD:
+						{
+							Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);
+							lod->dst.mask = 0x8;
+
+							emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL,
+							     result, &coord, arg[0], textureFunction.offset ? arg[3] : nullptr);
+						}
+						break;
+					case TextureFunction::FETCH:
+						{
+							if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))
+							{
+								TIntermNode *offset = textureFunction.offset ? arg[3] : nullptr;
+
+								emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH,
+								     result, arg[1], arg[0], arg[2], offset);
+							}
+							else UNREACHABLE(argumentCount);
+						}
+						break;
+					case TextureFunction::GRAD:
+						{
+							if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5))
+							{
+								TIntermNode *offset = textureFunction.offset ? arg[4] : nullptr;
+
+								emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD,
+								     result, &coord, arg[0], arg[2], arg[3], offset);
+							}
+							else UNREACHABLE(argumentCount);
+						}
+						break;
+					case TextureFunction::SIZE:
+						emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], arg[0]);
+						break;
+					default:
+						UNREACHABLE(textureFunction.method);
+					}
+				}
+			}
+			break;
+		case EOpParameters:
+			break;
+		case EOpConstructFloat:
+		case EOpConstructVec2:
+		case EOpConstructVec3:
+		case EOpConstructVec4:
+		case EOpConstructBool:
+		case EOpConstructBVec2:
+		case EOpConstructBVec3:
+		case EOpConstructBVec4:
+		case EOpConstructInt:
+		case EOpConstructIVec2:
+		case EOpConstructIVec3:
+		case EOpConstructIVec4:
+		case EOpConstructUInt:
+		case EOpConstructUVec2:
+		case EOpConstructUVec3:
+		case EOpConstructUVec4:
+			if(visit == PostVisit)
+			{
+				int component = 0;
+
+				for(size_t i = 0; i < argumentCount; i++)
+				{
+					TIntermTyped *argi = arg[i]->getAsTyped();
+					int size = argi->getNominalSize();
+
+					if(!argi->isMatrix())
+					{
+						Instruction *mov = emitCast(result, argi);
+						mov->dst.mask = (0xF << component) & 0xF;
+						mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);
+
+						component += size;
+					}
+					else   // Matrix
+					{
+						int column = 0;
+
+						while(component < resultType.getNominalSize())
+						{
+							Instruction *mov = emitCast(result, 0, argi, column);
+							mov->dst.mask = (0xF << component) & 0xF;
+							mov->src[0].swizzle = readSwizzle(argi, size) << (component * 2);
+
+							column++;
+							component += size;
+						}
+					}
+				}
+			}
+			break;
+		case EOpConstructMat2:
+		case EOpConstructMat2x3:
+		case EOpConstructMat2x4:
+		case EOpConstructMat3x2:
+		case EOpConstructMat3:
+		case EOpConstructMat3x4:
+		case EOpConstructMat4x2:
+		case EOpConstructMat4x3:
+		case EOpConstructMat4:
+			if(visit == PostVisit)
+			{
+				TIntermTyped *arg0 = arg[0]->getAsTyped();
+				const int outCols = result->getNominalSize();
+				const int outRows = result->getSecondarySize();
+
+				if(arg0->isScalar() && arg.size() == 1)   // Construct scale matrix
+				{
+					for(int i = 0; i < outCols; i++)
+					{
+						Instruction *init = emit(sw::Shader::OPCODE_MOV, result, i, &zero);
+						Instruction *mov = emitCast(result, i, arg0, 0);
+						mov->dst.mask = 1 << i;
+						ASSERT(mov->src[0].swizzle == 0x00);
+					}
+				}
+				else if(arg0->isMatrix())
+				{
+					const int inCols = arg0->getNominalSize();
+					const int inRows = arg0->getSecondarySize();
+
+					for(int i = 0; i < outCols; i++)
+					{
+						if(i >= inCols || outRows > inRows)
+						{
+							// Initialize to identity matrix
+							Constant col((i == 0 ? 1.0f : 0.0f), (i == 1 ? 1.0f : 0.0f), (i == 2 ? 1.0f : 0.0f), (i == 3 ? 1.0f : 0.0f));
+							Instruction *mov = emitCast(result, i, &col, 0);
+						}
+
+						if(i < inCols)
+						{
+							Instruction *mov = emitCast(result, i, arg0, i);
+							mov->dst.mask = 0xF >> (4 - inRows);
+						}
+					}
+				}
+				else
+				{
+					int column = 0;
+					int row = 0;
+
+					for(size_t i = 0; i < argumentCount; i++)
+					{
+						TIntermTyped *argi = arg[i]->getAsTyped();
+						int size = argi->getNominalSize();
+						int element = 0;
+
+						while(element < size)
+						{
+							Instruction *mov = emitCast(result, column, argi, 0);
+							mov->dst.mask = (0xF << row) & 0xF;
+							mov->src[0].swizzle = (readSwizzle(argi, size) << (row * 2)) + 0x55 * element;
+
+							int end = row + size - element;
+							column = end >= outRows ? column + 1 : column;
+							element = element + outRows - row;
+							row = end >= outRows ? 0 : end;
+						}
+					}
+				}
+			}
+			break;
+		case EOpConstructStruct:
+			if(visit == PostVisit)
+			{
+				int offset = 0;
+				for(size_t i = 0; i < argumentCount; i++)
+				{
+					TIntermTyped *argi = arg[i]->getAsTyped();
+					int size = argi->totalRegisterCount();
+
+					for(int index = 0; index < size; index++)
+					{
+						Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, index + offset, argi, index);
+						mov->dst.mask = writeMask(result, offset + index);
+					}
+
+					offset += size;
+				}
+			}
+			break;
+		case EOpLessThan:         if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LT, result, arg[0], arg[1]); break;
+		case EOpGreaterThan:      if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GT, result, arg[0], arg[1]); break;
+		case EOpLessThanEqual:    if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LE, result, arg[0], arg[1]); break;
+		case EOpGreaterThanEqual: if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GE, result, arg[0], arg[1]); break;
+		case EOpVectorEqual:      if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_EQ, result, arg[0], arg[1]); break;
+		case EOpVectorNotEqual:   if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_NE, result, arg[0], arg[1]); break;
+		case EOpMod:              if(visit == PostVisit) emit(sw::Shader::OPCODE_MOD, result, arg[0], arg[1]); break;
+		case EOpModf:
+			if(visit == PostVisit)
+			{
+				TIntermTyped* arg1 = arg[1]->getAsTyped();
+				emit(sw::Shader::OPCODE_TRUNC, arg1, arg[0]);
+				assignLvalue(arg1, arg1);
+				emitBinary(sw::Shader::OPCODE_SUB, result, arg[0], arg1);
+			}
+			break;
+		case EOpPow:              if(visit == PostVisit) emit(sw::Shader::OPCODE_POW, result, arg[0], arg[1]); break;
+		case EOpAtan:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ATAN2, result, arg[0], arg[1]); break;
+		case EOpMin:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, arg[0], arg[1]); break;
+		case EOpMax:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MAX, result), result, arg[0], arg[1]); break;
+		case EOpClamp:
+			if(visit == PostVisit)
+			{
+				emit(getOpcode(sw::Shader::OPCODE_MAX, result), result, arg[0], arg[1]);
+				emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, result, arg[2]);
+			}
+			break;
+		case EOpMix:         if(visit == PostVisit) emit(sw::Shader::OPCODE_LRP, result, arg[2], arg[1], arg[0]); break;
+		case EOpStep:        if(visit == PostVisit) emit(sw::Shader::OPCODE_STEP, result, arg[0], arg[1]); break;
+		case EOpSmoothStep:  if(visit == PostVisit) emit(sw::Shader::OPCODE_SMOOTH, result, arg[0], arg[1], arg[2]); break;
+		case EOpDistance:    if(visit == PostVisit) emit(sw::Shader::OPCODE_DIST(dim(arg[0])), result, arg[0], arg[1]); break;
+		case EOpDot:         if(visit == PostVisit) emit(sw::Shader::OPCODE_DP(dim(arg[0])), result, arg[0], arg[1]); break;
+		case EOpCross:       if(visit == PostVisit) emit(sw::Shader::OPCODE_CRS, result, arg[0], arg[1]); break;
+		case EOpFaceForward: if(visit == PostVisit) emit(sw::Shader::OPCODE_FORWARD(dim(arg[0])), result, arg[0], arg[1], arg[2]); break;
+		case EOpReflect:     if(visit == PostVisit) emit(sw::Shader::OPCODE_REFLECT(dim(arg[0])), result, arg[0], arg[1]); break;
+		case EOpRefract:     if(visit == PostVisit) emit(sw::Shader::OPCODE_REFRACT(dim(arg[0])), result, arg[0], arg[1], arg[2]); break;
+		case EOpMul:
+			if(visit == PostVisit)
+			{
+				TIntermTyped *arg0 = arg[0]->getAsTyped();
+				TIntermTyped *arg1 = arg[1]->getAsTyped();
+				ASSERT((arg0->getNominalSize() == arg1->getNominalSize()) && (arg0->getSecondarySize() == arg1->getSecondarySize()));
+
+				int size = arg0->getNominalSize();
+				for(int i = 0; i < size; i++)
+				{
+					emit(sw::Shader::OPCODE_MUL, result, i, arg[0], i, arg[1], i);
+				}
+			}
+			break;
+		case EOpOuterProduct:
+			if(visit == PostVisit)
+			{
+				for(int i = 0; i < dim(arg[1]); i++)
+				{
+					Instruction *mul = emit(sw::Shader::OPCODE_MUL, result, i, arg[0], 0, arg[1]);
+					mul->src[1].swizzle = 0x55 * i;
+				}
+			}
+			break;
+		default: UNREACHABLE(node->getOp());
+		}
+
+		return true;
+	}
+
+	bool OutputASM::visitSelection(Visit visit, TIntermSelection *node)
+	{
+		if(currentScope != emitScope)
+		{
+			return false;
+		}
+
+		TIntermTyped *condition = node->getCondition();
+		TIntermNode *trueBlock = node->getTrueBlock();
+		TIntermNode *falseBlock = node->getFalseBlock();
+		TIntermConstantUnion *constantCondition = condition->getAsConstantUnion();
+
+		condition->traverse(this);
+
+		if(node->usesTernaryOperator())
+		{
+			if(constantCondition)
+			{
+				bool trueCondition = constantCondition->getUnionArrayPointer()->getBConst();
+
+				if(trueCondition)
+				{
+					trueBlock->traverse(this);
+					copy(node, trueBlock);
+				}
+				else
+				{
+					falseBlock->traverse(this);
+					copy(node, falseBlock);
+				}
+			}
+			else if(trivial(node, 6))   // Fast to compute both potential results and no side effects
+			{
+				trueBlock->traverse(this);
+				falseBlock->traverse(this);
+				emit(sw::Shader::OPCODE_SELECT, node, condition, trueBlock, falseBlock);
+			}
+			else
+			{
+				emit(sw::Shader::OPCODE_IF, 0, condition);
+
+				if(trueBlock)
+				{
+					trueBlock->traverse(this);
+					copy(node, trueBlock);
+				}
+
+				if(falseBlock)
+				{
+					emit(sw::Shader::OPCODE_ELSE);
+					falseBlock->traverse(this);
+					copy(node, falseBlock);
+				}
+
+				emit(sw::Shader::OPCODE_ENDIF);
+			}
+		}
+		else  // if/else statement
+		{
+			if(constantCondition)
+			{
+				bool trueCondition = constantCondition->getUnionArrayPointer()->getBConst();
+
+				if(trueCondition)
+				{
+					if(trueBlock)
+					{
+						trueBlock->traverse(this);
+					}
+				}
+				else
+				{
+					if(falseBlock)
+					{
+						falseBlock->traverse(this);
+					}
+				}
+			}
+			else
+			{
+				emit(sw::Shader::OPCODE_IF, 0, condition);
+
+				if(trueBlock)
+				{
+					trueBlock->traverse(this);
+				}
+
+				if(falseBlock)
+				{
+					emit(sw::Shader::OPCODE_ELSE);
+					falseBlock->traverse(this);
+				}
+
+				emit(sw::Shader::OPCODE_ENDIF);
+			}
+		}
+
+		return false;
+	}
+
+	bool OutputASM::visitLoop(Visit visit, TIntermLoop *node)
+	{
+		if(currentScope != emitScope)
+		{
+			return false;
+		}
+
+		unsigned int iterations = loopCount(node);
+
+		if(iterations == 0)
+		{
+			return false;
+		}
+
+		bool unroll = (iterations <= 4);
+
+		if(unroll)
+		{
+			LoopUnrollable loopUnrollable;
+			unroll = loopUnrollable.traverse(node);
+		}
+
+		TIntermNode *init = node->getInit();
+		TIntermTyped *condition = node->getCondition();
+		TIntermTyped *expression = node->getExpression();
+		TIntermNode *body = node->getBody();
+		Constant True(true);
+
+		if(node->getType() == ELoopDoWhile)
+		{
+			Temporary iterate(this);
+			emit(sw::Shader::OPCODE_MOV, &iterate, &True);
+
+			emit(sw::Shader::OPCODE_WHILE, 0, &iterate);   // FIXME: Implement real do-while
+
+			if(body)
+			{
+				body->traverse(this);
+			}
+
+			emit(sw::Shader::OPCODE_TEST);
+
+			condition->traverse(this);
+			emit(sw::Shader::OPCODE_MOV, &iterate, condition);
+
+			emit(sw::Shader::OPCODE_ENDWHILE);
+		}
+		else
+		{
+			if(init)
+			{
+				init->traverse(this);
+			}
+
+			if(unroll)
+			{
+				for(unsigned int i = 0; i < iterations; i++)
+				{
+				//	condition->traverse(this);   // Condition could contain statements, but not in an unrollable loop
+
+					if(body)
+					{
+						body->traverse(this);
+					}
+
+					if(expression)
+					{
+						expression->traverse(this);
+					}
+				}
+			}
+			else
+			{
+				if(condition)
+				{
+					condition->traverse(this);
+				}
+				else
+				{
+					condition = &True;
+				}
+
+				emit(sw::Shader::OPCODE_WHILE, 0, condition);
+
+				if(body)
+				{
+					body->traverse(this);
+				}
+
+				emit(sw::Shader::OPCODE_TEST);
+
+				if(expression)
+				{
+					expression->traverse(this);
+				}
+
+				if(condition)
+				{
+					condition->traverse(this);
+				}
+
+				emit(sw::Shader::OPCODE_ENDWHILE);
+			}
+		}
+
+		return false;
+	}
+
+	bool OutputASM::visitBranch(Visit visit, TIntermBranch *node)
+	{
+		if(currentScope != emitScope)
+		{
+			return false;
+		}
+
+		switch(node->getFlowOp())
+		{
+		case EOpKill:      if(visit == PostVisit) emit(sw::Shader::OPCODE_DISCARD);  break;
+		case EOpBreak:     if(visit == PostVisit) emit(sw::Shader::OPCODE_BREAK);    break;
+		case EOpContinue:  if(visit == PostVisit) emit(sw::Shader::OPCODE_CONTINUE); break;
+		case EOpReturn:
+			if(visit == PostVisit)
+			{
+				TIntermTyped *value = node->getExpression();
+
+				if(value)
+				{
+					copy(functionArray[currentFunction].ret, value);
+				}
+
+				emit(sw::Shader::OPCODE_LEAVE);
+			}
+			break;
+		default: UNREACHABLE(node->getFlowOp());
+		}
+
+		return true;
+	}
+
+	Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2, TIntermNode *src3, TIntermNode *src4)
+	{
+		return emit(op, dst, 0, src0, 0, src1, 0, src2, 0, src3, 0, src4, 0);
+	}
+
+	Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, int dstIndex, TIntermNode *src0, int index0, TIntermNode *src1, int index1,
+	                             TIntermNode *src2, int index2, TIntermNode *src3, int index3, TIntermNode *src4, int index4)
+	{
+		Instruction *instruction = new Instruction(op);
+
+		if(dst)
+		{
+			instruction->dst.type = registerType(dst);
+			instruction->dst.index = registerIndex(dst) + dstIndex;
+			instruction->dst.mask = writeMask(dst);
+			instruction->dst.integer = (dst->getBasicType() == EbtInt);
+		}
+
+		argument(instruction->src[0], src0, index0);
+		argument(instruction->src[1], src1, index1);
+		argument(instruction->src[2], src2, index2);
+		argument(instruction->src[3], src3, index3);
+		argument(instruction->src[4], src4, index4);
+
+		shader->append(instruction);
+
+		return instruction;
+	}
+
+	Instruction *OutputASM::emitCast(TIntermTyped *dst, TIntermTyped *src)
+	{
+		return emitCast(dst, 0, src, 0);
+	}
+
+	Instruction *OutputASM::emitCast(TIntermTyped *dst, int dstIndex, TIntermTyped *src, int srcIndex)
+	{
+		switch(src->getBasicType())
+		{
+		case EbtBool:
+			switch(dst->getBasicType())
+			{
+			case EbtInt:   return emit(sw::Shader::OPCODE_B2I, dst, dstIndex, src, srcIndex);
+			case EbtUInt:  return emit(sw::Shader::OPCODE_B2I, dst, dstIndex, src, srcIndex);
+			case EbtFloat: return emit(sw::Shader::OPCODE_B2F, dst, dstIndex, src, srcIndex);
+			default:       break;
+			}
+			break;
+		case EbtInt:
+			switch(dst->getBasicType())
+			{
+			case EbtBool:  return emit(sw::Shader::OPCODE_I2B, dst, dstIndex, src, srcIndex);
+			case EbtFloat: return emit(sw::Shader::OPCODE_I2F, dst, dstIndex, src, srcIndex);
+			default:       break;
+			}
+			break;
+		case EbtUInt:
+			switch(dst->getBasicType())
+			{
+			case EbtBool:  return emit(sw::Shader::OPCODE_I2B, dst, dstIndex, src, srcIndex);
+			case EbtFloat: return emit(sw::Shader::OPCODE_U2F, dst, dstIndex, src, srcIndex);
+			default:       break;
+			}
+			break;
+		case EbtFloat:
+			switch(dst->getBasicType())
+			{
+			case EbtBool: return emit(sw::Shader::OPCODE_F2B, dst, dstIndex, src, srcIndex);
+			case EbtInt:  return emit(sw::Shader::OPCODE_F2I, dst, dstIndex, src, srcIndex);
+			case EbtUInt: return emit(sw::Shader::OPCODE_F2U, dst, dstIndex, src, srcIndex);
+			default:      break;
+			}
+			break;
+		default:
+			break;
+		}
+
+		ASSERT((src->getBasicType() == dst->getBasicType()) ||
+		      ((src->getBasicType() == EbtInt) && (dst->getBasicType() == EbtUInt)) ||
+		      ((src->getBasicType() == EbtUInt) && (dst->getBasicType() == EbtInt)));
+
+		return emit(sw::Shader::OPCODE_MOV, dst, dstIndex, src, srcIndex);
+	}
+
+	void OutputASM::emitBinary(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2)
+	{
+		for(int index = 0; index < dst->elementRegisterCount(); index++)
+		{
+			emit(op, dst, index, src0, index, src1, index, src2, index);
+		}
+	}
+
+	void OutputASM::emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1)
+	{
+		emitBinary(op, result, src0, src1);
+		assignLvalue(lhs, result);
+	}
+
+	void OutputASM::emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index)
+	{
+		sw::Shader::Opcode opcode;
+		switch(left->getAsTyped()->getBasicType())
+		{
+		case EbtBool:
+		case EbtInt:
+			opcode = sw::Shader::OPCODE_ICMP;
+			break;
+		case EbtUInt:
+			opcode = sw::Shader::OPCODE_UCMP;
+			break;
+		default:
+			opcode = sw::Shader::OPCODE_CMP;
+			break;
+		}
+
+		Instruction *cmp = emit(opcode, dst, 0, left, index, right, index);
+		cmp->control = cmpOp;
+	}
+
+	int componentCount(const TType &type, int registers)
+	{
+		if(registers == 0)
+		{
+			return 0;
+		}
+
+		if(type.isArray() && registers >= type.elementRegisterCount())
+		{
+			int index = registers / type.elementRegisterCount();
+			registers -= index * type.elementRegisterCount();
+			return index * type.getElementSize() + componentCount(type, registers);
+		}
+
+		if(type.isStruct() || type.isInterfaceBlock())
+		{
+			const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
+			int elements = 0;
+
+			for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
+			{
+				const TType &fieldType = *((*field)->type());
+
+				if(fieldType.totalRegisterCount() <= registers)
+				{
+					registers -= fieldType.totalRegisterCount();
+					elements += fieldType.getObjectSize();
+				}
+				else   // Register within this field
+				{
+					return elements + componentCount(fieldType, registers);
+				}
+			}
+		}
+		else if(type.isMatrix())
+		{
+			return registers * type.registerSize();
+		}
+
+		UNREACHABLE(0);
+		return 0;
+	}
+
+	int registerSize(const TType &type, int registers)
+	{
+		if(registers == 0)
+		{
+			if(type.isStruct())
+			{
+				return registerSize(*((*(type.getStruct()->fields().begin()))->type()), 0);
+			}
+			else if(type.isInterfaceBlock())
+			{
+				return registerSize(*((*(type.getInterfaceBlock()->fields().begin()))->type()), 0);
+			}
+
+			return type.registerSize();
+		}
+
+		if(type.isArray() && registers >= type.elementRegisterCount())
+		{
+			int index = registers / type.elementRegisterCount();
+			registers -= index * type.elementRegisterCount();
+			return registerSize(type, registers);
+		}
+
+		if(type.isStruct() || type.isInterfaceBlock())
+		{
+			const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
+			int elements = 0;
+
+			for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
+			{
+				const TType &fieldType = *((*field)->type());
+
+				if(fieldType.totalRegisterCount() <= registers)
+				{
+					registers -= fieldType.totalRegisterCount();
+					elements += fieldType.getObjectSize();
+				}
+				else   // Register within this field
+				{
+					return registerSize(fieldType, registers);
+				}
+			}
+		}
+		else if(type.isMatrix())
+		{
+			return registerSize(type, 0);
+		}
+
+		UNREACHABLE(0);
+		return 0;
+	}
+
+	int OutputASM::getBlockId(TIntermTyped *arg)
+	{
+		if(arg)
+		{
+			const TType &type = arg->getType();
+			TInterfaceBlock* block = type.getInterfaceBlock();
+			if(block && (type.getQualifier() == EvqUniform))
+			{
+				// Make sure the uniform block is declared
+				uniformRegister(arg);
+
+				const char* blockName = block->name().c_str();
+
+				// Fetch uniform block index from array of blocks
+				for(ActiveUniformBlocks::const_iterator it = shaderObject->activeUniformBlocks.begin(); it != shaderObject->activeUniformBlocks.end(); ++it)
+				{
+					if(blockName == it->name)
+					{
+						return it->blockId;
+					}
+				}
+
+				ASSERT(false);
+			}
+		}
+
+		return -1;
+	}
+
+	OutputASM::ArgumentInfo OutputASM::getArgumentInfo(TIntermTyped *arg, int index)
+	{
+		const TType &type = arg->getType();
+		int blockId = getBlockId(arg);
+		ArgumentInfo argumentInfo(BlockMemberInfo::getDefaultBlockInfo(), type, -1, -1);
+		if(blockId != -1)
+		{
+			argumentInfo.bufferIndex = 0;
+			for(int i = 0; i < blockId; ++i)
+			{
+				int blockArraySize = shaderObject->activeUniformBlocks[i].arraySize;
+				argumentInfo.bufferIndex += blockArraySize > 0 ? blockArraySize : 1;
+			}
+
+			const BlockDefinitionIndexMap& blockDefinition = blockDefinitions[blockId];
+
+			BlockDefinitionIndexMap::const_iterator itEnd = blockDefinition.end();
+			BlockDefinitionIndexMap::const_iterator it = itEnd;
+
+			argumentInfo.clampedIndex = index;
+			if(type.isInterfaceBlock())
+			{
+				// Offset index to the beginning of the selected instance
+				int blockRegisters = type.elementRegisterCount();
+				int bufferOffset = argumentInfo.clampedIndex / blockRegisters;
+				argumentInfo.bufferIndex += bufferOffset;
+				argumentInfo.clampedIndex -= bufferOffset * blockRegisters;
+			}
+
+			int regIndex = registerIndex(arg);
+			for(int i = regIndex + argumentInfo.clampedIndex; i >= regIndex; --i)
+			{
+				it = blockDefinition.find(i);
+				if(it != itEnd)
+				{
+					argumentInfo.clampedIndex -= (i - regIndex);
+					break;
+				}
+			}
+			ASSERT(it != itEnd);
+
+			argumentInfo.typedMemberInfo = it->second;
+
+			int registerCount = argumentInfo.typedMemberInfo.type.totalRegisterCount();
+			argumentInfo.clampedIndex = (argumentInfo.clampedIndex >= registerCount) ? registerCount - 1 : argumentInfo.clampedIndex;
+		}
+		else
+		{
+			argumentInfo.clampedIndex = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;
+		}
+
+		return argumentInfo;
+	}
+
+	void OutputASM::argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index)
+	{
+		if(argument)
+		{
+			TIntermTyped *arg = argument->getAsTyped();
+			Temporary unpackedUniform(this);
+
+			const TType& srcType = arg->getType();
+			TInterfaceBlock* srcBlock = srcType.getInterfaceBlock();
+			if(srcBlock && (srcType.getQualifier() == EvqUniform))
+			{
+				const ArgumentInfo argumentInfo = getArgumentInfo(arg, index);
+				const TType &memberType = argumentInfo.typedMemberInfo.type;
+
+				if(memberType.getBasicType() == EbtBool)
+				{
+					int arraySize = (memberType.isArray() ? memberType.getArraySize() : 1);
+					ASSERT(argumentInfo.clampedIndex < arraySize);
+
+					// Convert the packed bool, which is currently an int, to a true bool
+					Instruction *instruction = new Instruction(sw::Shader::OPCODE_I2B);
+					instruction->dst.type = sw::Shader::PARAMETER_TEMP;
+					instruction->dst.index = registerIndex(&unpackedUniform);
+					instruction->src[0].type = sw::Shader::PARAMETER_CONST;
+					instruction->src[0].bufferIndex = argumentInfo.bufferIndex;
+					instruction->src[0].index = argumentInfo.typedMemberInfo.offset + argumentInfo.clampedIndex * argumentInfo.typedMemberInfo.arrayStride;
+
+					shader->append(instruction);
+
+					arg = &unpackedUniform;
+					index = 0;
+				}
+				else if((srcBlock->matrixPacking() == EmpRowMajor) && memberType.isMatrix())
+				{
+					int numCols = memberType.getNominalSize();
+					int numRows = memberType.getSecondarySize();
+					int arraySize = (memberType.isArray() ? memberType.getArraySize() : 1);
+
+					ASSERT(argumentInfo.clampedIndex < (numCols * arraySize));
+
+					unsigned int dstIndex = registerIndex(&unpackedUniform);
+					unsigned int srcSwizzle = (argumentInfo.clampedIndex % numCols) * 0x55;
+					int arrayIndex = argumentInfo.clampedIndex / numCols;
+					int matrixStartOffset = argumentInfo.typedMemberInfo.offset + arrayIndex * argumentInfo.typedMemberInfo.arrayStride;
+
+					for(int j = 0; j < numRows; ++j)
+					{
+						// Transpose the row major matrix
+						Instruction *instruction = new Instruction(sw::Shader::OPCODE_MOV);
+						instruction->dst.type = sw::Shader::PARAMETER_TEMP;
+						instruction->dst.index = dstIndex;
+						instruction->dst.mask = 1 << j;
+						instruction->src[0].type = sw::Shader::PARAMETER_CONST;
+						instruction->src[0].bufferIndex = argumentInfo.bufferIndex;
+						instruction->src[0].index = matrixStartOffset + j * argumentInfo.typedMemberInfo.matrixStride;
+						instruction->src[0].swizzle = srcSwizzle;
+
+						shader->append(instruction);
+					}
+
+					arg = &unpackedUniform;
+					index = 0;
+				}
+			}
+
+			const ArgumentInfo argumentInfo = getArgumentInfo(arg, index);
+			const TType &type = argumentInfo.typedMemberInfo.type;
+
+			int size = registerSize(type, argumentInfo.clampedIndex);
+
+			parameter.type = registerType(arg);
+			parameter.bufferIndex = argumentInfo.bufferIndex;
+
+			if(arg->getAsConstantUnion() && arg->getAsConstantUnion()->getUnionArrayPointer())
+			{
+				int component = componentCount(type, argumentInfo.clampedIndex);
+				ConstantUnion *constants = arg->getAsConstantUnion()->getUnionArrayPointer();
+
+				for(int i = 0; i < 4; i++)
+				{
+					if(size == 1)   // Replicate
+					{
+						parameter.value[i] = constants[component + 0].getAsFloat();
+					}
+					else if(i < size)
+					{
+						parameter.value[i] = constants[component + i].getAsFloat();
+					}
+					else
+					{
+						parameter.value[i] = 0.0f;
+					}
+				}
+			}
+			else
+			{
+				parameter.index = registerIndex(arg) + argumentInfo.clampedIndex;
+
+				if(parameter.bufferIndex != -1)
+				{
+					int stride = (argumentInfo.typedMemberInfo.matrixStride > 0) ? argumentInfo.typedMemberInfo.matrixStride : argumentInfo.typedMemberInfo.arrayStride;
+					parameter.index = argumentInfo.typedMemberInfo.offset + argumentInfo.clampedIndex * stride;
+				}
+			}
+
+			if(!IsSampler(arg->getBasicType()))
+			{
+				parameter.swizzle = readSwizzle(arg, size);
+			}
+		}
+	}
+
+	void OutputASM::copy(TIntermTyped *dst, TIntermNode *src, int offset)
+	{
+		for(int index = 0; index < dst->totalRegisterCount(); index++)
+		{
+			Instruction *mov = emit(sw::Shader::OPCODE_MOV, dst, index, src, offset + index);
+			mov->dst.mask = writeMask(dst, index);
+		}
+	}
+
+	int swizzleElement(int swizzle, int index)
+	{
+		return (swizzle >> (index * 2)) & 0x03;
+	}
+
+	int swizzleSwizzle(int leftSwizzle, int rightSwizzle)
+	{
+		return (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 0)) << 0) |
+		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 1)) << 2) |
+		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 2)) << 4) |
+		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 3)) << 6);
+	}
+
+	void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)
+	{
+		if(src &&
+			((src->isVector() && (!dst->isVector() || (src->getNominalSize() != dst->getNominalSize()))) ||
+			 (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize()) || (src->getSecondarySize() != dst->getSecondarySize())))))
+		{
+			return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");
+		}
+
+		TIntermBinary *binary = dst->getAsBinaryNode();
+
+		if(binary && binary->getOp() == EOpIndexIndirect && binary->getLeft()->isVector() && dst->isScalar())
+		{
+			Instruction *insert = new Instruction(sw::Shader::OPCODE_INSERT);
+
+			Temporary address(this);
+			lvalue(insert->dst, address, dst);
+
+			insert->src[0].type = insert->dst.type;
+			insert->src[0].index = insert->dst.index;
+			insert->src[0].rel = insert->dst.rel;
+			argument(insert->src[1], src);
+			argument(insert->src[2], binary->getRight());
+
+			shader->append(insert);
+		}
+		else
+		{
+			for(int offset = 0; offset < dst->totalRegisterCount(); offset++)
+			{
+				Instruction *mov = new Instruction(sw::Shader::OPCODE_MOV);
+
+				Temporary address(this);
+				int swizzle = lvalue(mov->dst, address, dst);
+				mov->dst.index += offset;
+
+				if(offset > 0)
+				{
+					mov->dst.mask = writeMask(dst, offset);
+				}
+
+				argument(mov->src[0], src, offset);
+				mov->src[0].swizzle = swizzleSwizzle(mov->src[0].swizzle, swizzle);
+
+				shader->append(mov);
+			}
+		}
+	}
+
+	int OutputASM::lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node)
+	{
+		TIntermTyped *result = node;
+		TIntermBinary *binary = node->getAsBinaryNode();
+		TIntermSymbol *symbol = node->getAsSymbolNode();
+
+		if(binary)
+		{
+			TIntermTyped *left = binary->getLeft();
+			TIntermTyped *right = binary->getRight();
+
+			int leftSwizzle = lvalue(dst, address, left);   // Resolve the l-value of the left side
+
+			switch(binary->getOp())
+			{
+			case EOpIndexDirect:
+				{
+					int rightIndex = right->getAsConstantUnion()->getIConst(0);
+
+					if(left->isRegister())
+					{
+						int leftMask = dst.mask;
+
+						dst.mask = 1;
+						while((leftMask & dst.mask) == 0)
+						{
+							dst.mask = dst.mask << 1;
+						}
+
+						int element = swizzleElement(leftSwizzle, rightIndex);
+						dst.mask = 1 << element;
+
+						return element;
+					}
+					else if(left->isArray() || left->isMatrix())
+					{
+						dst.index += rightIndex * result->totalRegisterCount();
+						return 0xE4;
+					}
+					else UNREACHABLE(0);
+				}
+				break;
+			case EOpIndexIndirect:
+				{
+					if(left->isRegister())
+					{
+						// Requires INSERT instruction (handled by calling function)
+					}
+					else if(left->isArray() || left->isMatrix())
+					{
+						int scale = result->totalRegisterCount();
+
+						if(dst.rel.type == sw::Shader::PARAMETER_VOID)   // Use the index register as the relative address directly
+						{
+							if(left->totalRegisterCount() > 1)
+							{
+								sw::Shader::SourceParameter relativeRegister;
+								argument(relativeRegister, right);
+
+								dst.rel.index = relativeRegister.index;
+								dst.rel.type = relativeRegister.type;
+								dst.rel.scale = scale;
+								dst.rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
+							}
+						}
+						else if(dst.rel.index != registerIndex(&address))   // Move the previous index register to the address register
+						{
+							if(scale == 1)
+							{
+								Constant oldScale((int)dst.rel.scale);
+								Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right);
+								mad->src[0].index = dst.rel.index;
+								mad->src[0].type = dst.rel.type;
+							}
+							else
+							{
+								Constant oldScale((int)dst.rel.scale);
+								Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale);
+								mul->src[0].index = dst.rel.index;
+								mul->src[0].type = dst.rel.type;
+
+								Constant newScale(scale);
+								emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);
+							}
+
+							dst.rel.type = sw::Shader::PARAMETER_TEMP;
+							dst.rel.index = registerIndex(&address);
+							dst.rel.scale = 1;
+						}
+						else   // Just add the new index to the address register
+						{
+							if(scale == 1)
+							{
+								emit(sw::Shader::OPCODE_IADD, &address, &address, right);
+							}
+							else
+							{
+								Constant newScale(scale);
+								emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);
+							}
+						}
+					}
+					else UNREACHABLE(0);
+				}
+				break;
+			case EOpIndexDirectStruct:
+			case EOpIndexDirectInterfaceBlock:
+				{
+					const TFieldList& fields = (binary->getOp() == EOpIndexDirectStruct) ?
+					                           left->getType().getStruct()->fields() :
+					                           left->getType().getInterfaceBlock()->fields();
+					int index = right->getAsConstantUnion()->getIConst(0);
+					int fieldOffset = 0;
+
+					for(int i = 0; i < index; i++)
+					{
+						fieldOffset += fields[i]->type()->totalRegisterCount();
+					}
+
+					dst.type = registerType(left);
+					dst.index += fieldOffset;
+					dst.mask = writeMask(right);
+
+					return 0xE4;
+				}
+				break;
+			case EOpVectorSwizzle:
+				{
+					ASSERT(left->isRegister());
+
+					int leftMask = dst.mask;
+
+					int swizzle = 0;
+					int rightMask = 0;
+
+					TIntermSequence &sequence = right->getAsAggregate()->getSequence();
+
+					for(unsigned int i = 0; i < sequence.size(); i++)
+					{
+						int index = sequence[i]->getAsConstantUnion()->getIConst(0);
+
+						int element = swizzleElement(leftSwizzle, index);
+						rightMask = rightMask | (1 << element);
+						swizzle = swizzle | swizzleElement(leftSwizzle, i) << (element * 2);
+					}
+
+					dst.mask = leftMask & rightMask;
+
+					return swizzle;
+				}
+				break;
+			default:
+				UNREACHABLE(binary->getOp());   // Not an l-value operator
+				break;
+			}
+		}
+		else if(symbol)
+		{
+			dst.type = registerType(symbol);
+			dst.index = registerIndex(symbol);
+			dst.mask = writeMask(symbol);
+			return 0xE4;
+		}
+
+		return 0xE4;
+	}
+
+	sw::Shader::ParameterType OutputASM::registerType(TIntermTyped *operand)
+	{
+		if(isSamplerRegister(operand))
+		{
+			return sw::Shader::PARAMETER_SAMPLER;
+		}
+
+		const TQualifier qualifier = operand->getQualifier();
+		if((EvqFragColor == qualifier) || (EvqFragData == qualifier))
+		{
+			if(((EvqFragData == qualifier) && (EvqFragColor == outputQualifier)) ||
+			   ((EvqFragColor == qualifier) && (EvqFragData == outputQualifier)))
+			{
+				mContext.error(operand->getLine(), "static assignment to both gl_FragData and gl_FragColor", "");
+			}
+			outputQualifier = qualifier;
+		}
+
+		if(qualifier == EvqConstExpr && (!operand->getAsConstantUnion() || !operand->getAsConstantUnion()->getUnionArrayPointer()))
+		{
+			return sw::Shader::PARAMETER_TEMP;
+		}
+
+		switch(qualifier)
+		{
+		case EvqTemporary:           return sw::Shader::PARAMETER_TEMP;
+		case EvqGlobal:              return sw::Shader::PARAMETER_TEMP;
+		case EvqConstExpr:           return sw::Shader::PARAMETER_FLOAT4LITERAL;   // All converted to float
+		case EvqAttribute:           return sw::Shader::PARAMETER_INPUT;
+		case EvqVaryingIn:           return sw::Shader::PARAMETER_INPUT;
+		case EvqVaryingOut:          return sw::Shader::PARAMETER_OUTPUT;
+		case EvqVertexIn:            return sw::Shader::PARAMETER_INPUT;
+		case EvqFragmentOut:         return sw::Shader::PARAMETER_COLOROUT;
+		case EvqVertexOut:           return sw::Shader::PARAMETER_OUTPUT;
+		case EvqFragmentIn:          return sw::Shader::PARAMETER_INPUT;
+		case EvqInvariantVaryingIn:  return sw::Shader::PARAMETER_INPUT;    // FIXME: Guarantee invariance at the backend
+		case EvqInvariantVaryingOut: return sw::Shader::PARAMETER_OUTPUT;   // FIXME: Guarantee invariance at the backend
+		case EvqSmooth:              return sw::Shader::PARAMETER_OUTPUT;
+		case EvqFlat:                return sw::Shader::PARAMETER_OUTPUT;
+		case EvqCentroidOut:         return sw::Shader::PARAMETER_OUTPUT;
+		case EvqSmoothIn:            return sw::Shader::PARAMETER_INPUT;
+		case EvqFlatIn:              return sw::Shader::PARAMETER_INPUT;
+		case EvqCentroidIn:          return sw::Shader::PARAMETER_INPUT;
+		case EvqUniform:             return sw::Shader::PARAMETER_CONST;
+		case EvqIn:                  return sw::Shader::PARAMETER_TEMP;
+		case EvqOut:                 return sw::Shader::PARAMETER_TEMP;
+		case EvqInOut:               return sw::Shader::PARAMETER_TEMP;
+		case EvqConstReadOnly:       return sw::Shader::PARAMETER_TEMP;
+		case EvqPosition:            return sw::Shader::PARAMETER_OUTPUT;
+		case EvqPointSize:           return sw::Shader::PARAMETER_OUTPUT;
+		case EvqInstanceID:          return sw::Shader::PARAMETER_MISCTYPE;
+		case EvqFragCoord:           return sw::Shader::PARAMETER_MISCTYPE;
+		case EvqFrontFacing:         return sw::Shader::PARAMETER_MISCTYPE;
+		case EvqPointCoord:          return sw::Shader::PARAMETER_INPUT;
+		case EvqFragColor:           return sw::Shader::PARAMETER_COLOROUT;
+		case EvqFragData:            return sw::Shader::PARAMETER_COLOROUT;
+		case EvqFragDepth:           return sw::Shader::PARAMETER_DEPTHOUT;
+		default: UNREACHABLE(qualifier);
+		}
+
+		return sw::Shader::PARAMETER_VOID;
+	}
+
+	unsigned int OutputASM::registerIndex(TIntermTyped *operand)
+	{
+		if(isSamplerRegister(operand))
+		{
+			return samplerRegister(operand);
+		}
+
+		switch(operand->getQualifier())
+		{
+		case EvqTemporary:           return temporaryRegister(operand);
+		case EvqGlobal:              return temporaryRegister(operand);
+		case EvqConstExpr:           return temporaryRegister(operand);   // Unevaluated constant expression
+		case EvqAttribute:           return attributeRegister(operand);
+		case EvqVaryingIn:           return varyingRegister(operand);
+		case EvqVaryingOut:          return varyingRegister(operand);
+		case EvqVertexIn:            return attributeRegister(operand);
+		case EvqFragmentOut:         return fragmentOutputRegister(operand);
+		case EvqVertexOut:           return varyingRegister(operand);
+		case EvqFragmentIn:          return varyingRegister(operand);
+		case EvqInvariantVaryingIn:  return varyingRegister(operand);
+		case EvqInvariantVaryingOut: return varyingRegister(operand);
+		case EvqSmooth:              return varyingRegister(operand);
+		case EvqFlat:                return varyingRegister(operand);
+		case EvqCentroidOut:         return varyingRegister(operand);
+		case EvqSmoothIn:            return varyingRegister(operand);
+		case EvqFlatIn:              return varyingRegister(operand);
+		case EvqCentroidIn:          return varyingRegister(operand);
+		case EvqUniform:             return uniformRegister(operand);
+		case EvqIn:                  return temporaryRegister(operand);
+		case EvqOut:                 return temporaryRegister(operand);
+		case EvqInOut:               return temporaryRegister(operand);
+		case EvqConstReadOnly:       return temporaryRegister(operand);
+		case EvqPosition:            return varyingRegister(operand);
+		case EvqPointSize:           return varyingRegister(operand);
+		case EvqInstanceID:          vertexShader->instanceIdDeclared = true; return 0;
+		case EvqFragCoord:           pixelShader->vPosDeclared = true;  return 0;
+		case EvqFrontFacing:         pixelShader->vFaceDeclared = true; return 1;
+		case EvqPointCoord:          return varyingRegister(operand);
+		case EvqFragColor:           return 0;
+		case EvqFragData:            return fragmentOutputRegister(operand);
+		case EvqFragDepth:           return 0;
+		default: UNREACHABLE(operand->getQualifier());
+		}
+
+		return 0;
+	}
+
+	int OutputASM::writeMask(TIntermTyped *destination, int index)
+	{
+		if(destination->getQualifier() == EvqPointSize)
+		{
+			return 0x2;   // Point size stored in the y component
+		}
+
+		return 0xF >> (4 - registerSize(destination->getType(), index));
+	}
+
+	int OutputASM::readSwizzle(TIntermTyped *argument, int size)
+	{
+		if(argument->getQualifier() == EvqPointSize)
+		{
+			return 0x55;   // Point size stored in the y component
+		}
+
+		static const unsigned char swizzleSize[5] = {0x00, 0x00, 0x54, 0xA4, 0xE4};   // (void), xxxx, xyyy, xyzz, xyzw
+
+		return swizzleSize[size];
+	}
+
+	// Conservatively checks whether an expression is fast to compute and has no side effects
+	bool OutputASM::trivial(TIntermTyped *expression, int budget)
+	{
+		if(!expression->isRegister())
+		{
+			return false;
+		}
+
+		return cost(expression, budget) >= 0;
+	}
+
+	// Returns the remaining computing budget (if < 0 the expression is too expensive or has side effects)
+	int OutputASM::cost(TIntermNode *expression, int budget)
+	{
+		if(budget < 0)
+		{
+			return budget;
+		}
+
+		if(expression->getAsSymbolNode())
+		{
+			return budget;
+		}
+		else if(expression->getAsConstantUnion())
+		{
+			return budget;
+		}
+		else if(expression->getAsBinaryNode())
+		{
+			TIntermBinary *binary = expression->getAsBinaryNode();
+
+			switch(binary->getOp())
+			{
+			case EOpVectorSwizzle:
+			case EOpIndexDirect:
+			case EOpIndexDirectStruct:
+			case EOpIndexDirectInterfaceBlock:
+				return cost(binary->getLeft(), budget - 0);
+			case EOpAdd:
+			case EOpSub:
+			case EOpMul:
+				return cost(binary->getLeft(), cost(binary->getRight(), budget - 1));
+			default:
+				return -1;
+			}
+		}
+		else if(expression->getAsUnaryNode())
+		{
+			TIntermUnary *unary = expression->getAsUnaryNode();
+
+			switch(unary->getOp())
+			{
+			case EOpAbs:
+			case EOpNegative:
+				return cost(unary->getOperand(), budget - 1);
+			default:
+				return -1;
+			}
+		}
+		else if(expression->getAsSelectionNode())
+		{
+			TIntermSelection *selection = expression->getAsSelectionNode();
+
+			if(selection->usesTernaryOperator())
+			{
+				TIntermTyped *condition = selection->getCondition();
+				TIntermNode *trueBlock = selection->getTrueBlock();
+				TIntermNode *falseBlock = selection->getFalseBlock();
+				TIntermConstantUnion *constantCondition = condition->getAsConstantUnion();
+
+				if(constantCondition)
+				{
+					bool trueCondition = constantCondition->getUnionArrayPointer()->getBConst();
+
+					if(trueCondition)
+					{
+						return cost(trueBlock, budget - 0);
+					}
+					else
+					{
+						return cost(falseBlock, budget - 0);
+					}
+				}
+				else
+				{
+					return cost(trueBlock, cost(falseBlock, budget - 2));
+				}
+			}
+		}
+
+		return -1;
+	}
+
+	const Function *OutputASM::findFunction(const TString &name)
+	{
+		for(unsigned int f = 0; f < functionArray.size(); f++)
+		{
+			if(functionArray[f].name == name)
+			{
+				return &functionArray[f];
+			}
+		}
+
+		return 0;
+	}
+
+	int OutputASM::temporaryRegister(TIntermTyped *temporary)
+	{
+		return allocate(temporaries, temporary);
+	}
+
+	int OutputASM::varyingRegister(TIntermTyped *varying)
+	{
+		int var = lookup(varyings, varying);
+
+		if(var == -1)
+		{
+			var = allocate(varyings, varying);
+			int componentCount = varying->registerSize();
+			int registerCount = varying->totalRegisterCount();
+
+			if(pixelShader)
+			{
+				if((var + registerCount) > sw::PixelShader::MAX_INPUT_VARYINGS)
+				{
+					mContext.error(varying->getLine(), "Varyings packing failed: Too many varyings", "fragment shader");
+					return 0;
+				}
+
+				if(varying->getQualifier() == EvqPointCoord)
+				{
+					ASSERT(varying->isRegister());
+					if(componentCount >= 1) pixelShader->semantic[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
+					if(componentCount >= 2) pixelShader->semantic[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
+					if(componentCount >= 3) pixelShader->semantic[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
+					if(componentCount >= 4) pixelShader->semantic[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var);
+				}
+				else
+				{
+					for(int i = 0; i < varying->totalRegisterCount(); i++)
+					{
+						if(componentCount >= 1) pixelShader->semantic[var + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
+						if(componentCount >= 2) pixelShader->semantic[var + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
+						if(componentCount >= 3) pixelShader->semantic[var + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
+						if(componentCount >= 4) pixelShader->semantic[var + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
+					}
+				}
+			}
+			else if(vertexShader)
+			{
+				if((var + registerCount) > sw::VertexShader::MAX_OUTPUT_VARYINGS)
+				{
+					mContext.error(varying->getLine(), "Varyings packing failed: Too many varyings", "vertex shader");
+					return 0;
+				}
+
+				if(varying->getQualifier() == EvqPosition)
+				{
+					ASSERT(varying->isRegister());
+					vertexShader->output[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
+					vertexShader->output[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
+					vertexShader->output[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
+					vertexShader->output[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_POSITION, 0);
+					vertexShader->positionRegister = var;
+				}
+				else if(varying->getQualifier() == EvqPointSize)
+				{
+					ASSERT(varying->isRegister());
+					vertexShader->output[var][0] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
+					vertexShader->output[var][1] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
+					vertexShader->output[var][2] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
+					vertexShader->output[var][3] = sw::Shader::Semantic(sw::Shader::USAGE_PSIZE, 0);
+					vertexShader->pointSizeRegister = var;
+				}
+				else
+				{
+					// Semantic indexes for user varyings will be assigned during program link to match the pixel shader
+				}
+			}
+			else UNREACHABLE(0);
+
+			declareVarying(varying, var);
+		}
+
+		return var;
+	}
+
+	void OutputASM::declareVarying(TIntermTyped *varying, int reg)
+	{
+		if(varying->getQualifier() != EvqPointCoord)   // gl_PointCoord does not need linking
+		{
+			const TType &type = varying->getType();
+			const char *name = varying->getAsSymbolNode()->getSymbol().c_str();
+			VaryingList &activeVaryings = shaderObject->varyings;
+
+			// Check if this varying has been declared before without having a register assigned
+			for(VaryingList::iterator v = activeVaryings.begin(); v != activeVaryings.end(); v++)
+			{
+				if(v->name == name)
+				{
+					if(reg >= 0)
+					{
+						ASSERT(v->reg < 0 || v->reg == reg);
+						v->reg = reg;
+					}
+
+					return;
+				}
+			}
+
+			activeVaryings.push_back(glsl::Varying(glVariableType(type), name, varying->getArraySize(), reg, 0));
+		}
+	}
+
+	int OutputASM::uniformRegister(TIntermTyped *uniform)
+	{
+		const TType &type = uniform->getType();
+		ASSERT(!IsSampler(type.getBasicType()));
+		TInterfaceBlock *block = type.getAsInterfaceBlock();
+		TIntermSymbol *symbol = uniform->getAsSymbolNode();
+		ASSERT(symbol || block);
+
+		if(symbol || block)
+		{
+			TInterfaceBlock* parentBlock = type.getInterfaceBlock();
+			bool isBlockMember = (!block && parentBlock);
+			int index = isBlockMember ? lookup(uniforms, parentBlock) : lookup(uniforms, uniform);
+
+			if(index == -1 || isBlockMember)
+			{
+				if(index == -1)
+				{
+					index = allocate(uniforms, uniform);
+				}
+
+				// Verify if the current uniform is a member of an already declared block
+				const TString &name = symbol ? symbol->getSymbol() : block->name();
+				int blockMemberIndex = blockMemberLookup(type, name, index);
+				if(blockMemberIndex == -1)
+				{
+					declareUniform(type, name, index);
+				}
+				else
+				{
+					index = blockMemberIndex;
+				}
+			}
+
+			return index;
+		}
+
+		return 0;
+	}
+
+	int OutputASM::attributeRegister(TIntermTyped *attribute)
+	{
+		ASSERT(!attribute->isArray());
+
+		int index = lookup(attributes, attribute);
+
+		if(index == -1)
+		{
+			TIntermSymbol *symbol = attribute->getAsSymbolNode();
+			ASSERT(symbol);
+
+			if(symbol)
+			{
+				index = allocate(attributes, attribute);
+				const TType &type = attribute->getType();
+				int registerCount = attribute->totalRegisterCount();
+
+				if(vertexShader && (index + registerCount) <= sw::VertexShader::MAX_INPUT_ATTRIBUTES)
+				{
+					for(int i = 0; i < registerCount; i++)
+					{
+						vertexShader->input[index + i] = sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, index + i);
+					}
+				}
+
+				ActiveAttributes &activeAttributes = shaderObject->activeAttributes;
+
+				const char *name = symbol->getSymbol().c_str();
+				activeAttributes.push_back(Attribute(glVariableType(type), name, type.getArraySize(), type.getLayoutQualifier().location, index));
+			}
+		}
+
+		return index;
+	}
+
+	int OutputASM::fragmentOutputRegister(TIntermTyped *fragmentOutput)
+	{
+		return allocate(fragmentOutputs, fragmentOutput);
+	}
+
+	int OutputASM::samplerRegister(TIntermTyped *sampler)
+	{
+		const TType &type = sampler->getType();
+		ASSERT(IsSampler(type.getBasicType()) || type.isStruct());   // Structures can contain samplers
+
+		TIntermSymbol *symbol = sampler->getAsSymbolNode();
+		TIntermBinary *binary = sampler->getAsBinaryNode();
+
+		if(symbol && type.getQualifier() == EvqUniform)
+		{
+			return samplerRegister(symbol);
+		}
+		else if(binary)
+		{
+			TIntermTyped *left = binary->getLeft();
+			TIntermTyped *right = binary->getRight();
+			const TType &leftType = left->getType();
+			int index = right->getAsConstantUnion() ? right->getAsConstantUnion()->getIConst(0) : 0;
+			int offset = 0;
+
+			switch(binary->getOp())
+			{
+			case EOpIndexDirect:
+				ASSERT(left->isArray());
+				offset = index * leftType.elementRegisterCount();
+				break;
+			case EOpIndexDirectStruct:
+				ASSERT(leftType.isStruct());
+				{
+					const TFieldList &fields = leftType.getStruct()->fields();
+
+					for(int i = 0; i < index; i++)
+					{
+						offset += fields[i]->type()->totalRegisterCount();
+					}
+				}
+				break;
+			case EOpIndexIndirect:               // Indirect indexing produces a temporary, not a sampler register
+				return -1;
+			case EOpIndexDirectInterfaceBlock:   // Interface blocks can't contain samplers
+			default:
+				UNREACHABLE(binary->getOp());
+				return -1;
+			}
+
+			int base = samplerRegister(left);
+
+			if(base < 0)
+			{
+				return -1;
+			}
+
+			return base + offset;
+		}
+
+		UNREACHABLE(0);
+		return -1;   // Not a sampler register
+	}
+
+	int OutputASM::samplerRegister(TIntermSymbol *sampler)
+	{
+		const TType &type = sampler->getType();
+		ASSERT(IsSampler(type.getBasicType()) || type.isStruct());   // Structures can contain samplers
+
+		int index = lookup(samplers, sampler);
+
+		if(index == -1)
+		{
+			index = allocate(samplers, sampler);
+
+			if(sampler->getQualifier() == EvqUniform)
+			{
+				const char *name = sampler->getSymbol().c_str();
+				declareUniform(type, name, index);
+			}
+		}
+
+		return index;
+	}
+
+	bool OutputASM::isSamplerRegister(TIntermTyped *operand)
+	{
+		return operand && IsSampler(operand->getBasicType()) && samplerRegister(operand) >= 0;
+	}
+
+	int OutputASM::lookup(VariableArray &list, TIntermTyped *variable)
+	{
+		for(unsigned int i = 0; i < list.size(); i++)
+		{
+			if(list[i] == variable)
+			{
+				return i;   // Pointer match
+			}
+		}
+
+		TIntermSymbol *varSymbol = variable->getAsSymbolNode();
+		TInterfaceBlock *varBlock = variable->getType().getAsInterfaceBlock();
+
+		if(varBlock)
+		{
+			for(unsigned int i = 0; i < list.size(); i++)
+			{
+				if(list[i])
+				{
+					TInterfaceBlock *listBlock = list[i]->getType().getAsInterfaceBlock();
+
+					if(listBlock)
+					{
+						if(listBlock->name() == varBlock->name())
+						{
+							ASSERT(listBlock->arraySize() == varBlock->arraySize());
+							ASSERT(listBlock->fields() == varBlock->fields());
+							ASSERT(listBlock->blockStorage() == varBlock->blockStorage());
+							ASSERT(listBlock->matrixPacking() == varBlock->matrixPacking());
+
+							return i;
+						}
+					}
+				}
+			}
+		}
+		else if(varSymbol)
+		{
+			for(unsigned int i = 0; i < list.size(); i++)
+			{
+				if(list[i])
+				{
+					TIntermSymbol *listSymbol = list[i]->getAsSymbolNode();
+
+					if(listSymbol)
+					{
+						if(listSymbol->getId() == varSymbol->getId())
+						{
+							ASSERT(listSymbol->getSymbol() == varSymbol->getSymbol());
+							ASSERT(listSymbol->getType() == varSymbol->getType());
+							ASSERT(listSymbol->getQualifier() == varSymbol->getQualifier());
+
+							return i;
+						}
+					}
+				}
+			}
+		}
+
+		return -1;
+	}
+
+	int OutputASM::lookup(VariableArray &list, TInterfaceBlock *block)
+	{
+		for(unsigned int i = 0; i < list.size(); i++)
+		{
+			if(list[i] && (list[i]->getType().getInterfaceBlock() == block))
+			{
+				return i;   // Pointer match
+			}
+		}
+		return -1;
+	}
+
+	int OutputASM::allocate(VariableArray &list, TIntermTyped *variable)
+	{
+		int index = lookup(list, variable);
+
+		if(index == -1)
+		{
+			unsigned int registerCount = variable->blockRegisterCount();
+
+			for(unsigned int i = 0; i < list.size(); i++)
+			{
+				if(list[i] == 0)
+				{
+					unsigned int j = 1;
+					for( ; j < registerCount && (i + j) < list.size(); j++)
+					{
+						if(list[i + j] != 0)
+						{
+							break;
+						}
+					}
+
+					if(j == registerCount)   // Found free slots
+					{
+						for(unsigned int j = 0; j < registerCount; j++)
+						{
+							list[i + j] = variable;
+						}
+
+						return i;
+					}
+				}
+			}
+
+			index = list.size();
+
+			for(unsigned int i = 0; i < registerCount; i++)
+			{
+				list.push_back(variable);
+			}
+		}
+
+		return index;
+	}
+
+	void OutputASM::free(VariableArray &list, TIntermTyped *variable)
+	{
+		int index = lookup(list, variable);
+
+		if(index >= 0)
+		{
+			list[index] = 0;
+		}
+	}
+
+	int OutputASM::blockMemberLookup(const TType &type, const TString &name, int registerIndex)
+	{
+		const TInterfaceBlock *block = type.getInterfaceBlock();
+
+		if(block)
+		{
+			ActiveUniformBlocks &activeUniformBlocks = shaderObject->activeUniformBlocks;
+			const TFieldList& fields = block->fields();
+			const TString &blockName = block->name();
+			int fieldRegisterIndex = registerIndex;
+
+			if(!type.isInterfaceBlock())
+			{
+				// This is a uniform that's part of a block, let's see if the block is already defined
+				for(size_t i = 0; i < activeUniformBlocks.size(); ++i)
+				{
+					if(activeUniformBlocks[i].name == blockName.c_str())
+					{
+						// The block is already defined, find the register for the current uniform and return it
+						for(size_t j = 0; j < fields.size(); j++)
+						{
+							const TString &fieldName = fields[j]->name();
+							if(fieldName == name)
+							{
+								return fieldRegisterIndex;
+							}
+
+							fieldRegisterIndex += fields[j]->type()->totalRegisterCount();
+						}
+
+						ASSERT(false);
+						return fieldRegisterIndex;
+					}
+				}
+			}
+		}
+
+		return -1;
+	}
+
+	void OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, int blockId, BlockLayoutEncoder* encoder)
+	{
+		const TStructure *structure = type.getStruct();
+		const TInterfaceBlock *block = (type.isInterfaceBlock() || (blockId == -1)) ? type.getInterfaceBlock() : nullptr;
+
+		if(!structure && !block)
+		{
+			ActiveUniforms &activeUniforms = shaderObject->activeUniforms;
+			const BlockMemberInfo blockInfo = encoder ? encoder->encodeType(type) : BlockMemberInfo::getDefaultBlockInfo();
+			if(blockId >= 0)
+			{
+				blockDefinitions[blockId][registerIndex] = TypedMemberInfo(blockInfo, type);
+				shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size());
+			}
+			int fieldRegisterIndex = encoder ? shaderObject->activeUniformBlocks[blockId].registerIndex + BlockLayoutEncoder::getBlockRegister(blockInfo) : registerIndex;
+			activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(),
+			                                 fieldRegisterIndex, blockId, blockInfo));
+			if(IsSampler(type.getBasicType()))
+			{
+				for(int i = 0; i < type.totalRegisterCount(); i++)
+				{
+					shader->declareSampler(fieldRegisterIndex + i);
+				}
+			}
+		}
+		else if(block)
+		{
+			ActiveUniformBlocks &activeUniformBlocks = shaderObject->activeUniformBlocks;
+			const TFieldList& fields = block->fields();
+			const TString &blockName = block->name();
+			int fieldRegisterIndex = registerIndex;
+			bool isUniformBlockMember = !type.isInterfaceBlock() && (blockId == -1);
+
+			blockId = activeUniformBlocks.size();
+			bool isRowMajor = block->matrixPacking() == EmpRowMajor;
+			activeUniformBlocks.push_back(UniformBlock(blockName.c_str(), 0, block->arraySize(),
+			                                           block->blockStorage(), isRowMajor, registerIndex, blockId));
+			blockDefinitions.push_back(BlockDefinitionIndexMap());
+
+			Std140BlockEncoder currentBlockEncoder(isRowMajor);
+			currentBlockEncoder.enterAggregateType();
+			for(size_t i = 0; i < fields.size(); i++)
+			{
+				const TType &fieldType = *(fields[i]->type());
+				const TString &fieldName = fields[i]->name();
+				if(isUniformBlockMember && (fieldName == name))
+				{
+					registerIndex = fieldRegisterIndex;
+				}
+
+				const TString uniformName = block->hasInstanceName() ? blockName + "." + fieldName : fieldName;
+
+				declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, &currentBlockEncoder);
+				fieldRegisterIndex += fieldType.totalRegisterCount();
+			}
+			currentBlockEncoder.exitAggregateType();
+			activeUniformBlocks[blockId].dataSize = currentBlockEncoder.getBlockSize();
+		}
+		else
+		{
+			int fieldRegisterIndex = registerIndex;
+
+			const TFieldList& fields = structure->fields();
+			if(type.isArray() && (structure || type.isInterfaceBlock()))
+			{
+				for(int i = 0; i < type.getArraySize(); i++)
+				{
+					if(encoder)
+					{
+						encoder->enterAggregateType();
+					}
+					for(size_t j = 0; j < fields.size(); j++)
+					{
+						const TType &fieldType = *(fields[j]->type());
+						const TString &fieldName = fields[j]->name();
+						const TString uniformName = name + "[" + str(i) + "]." + fieldName;
+
+						declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);
+						fieldRegisterIndex += fieldType.totalRegisterCount();
+					}
+					if(encoder)
+					{
+						encoder->exitAggregateType();
+					}
+				}
+			}
+			else
+			{
+				if(encoder)
+				{
+					encoder->enterAggregateType();
+				}
+				for(size_t i = 0; i < fields.size(); i++)
+				{
+					const TType &fieldType = *(fields[i]->type());
+					const TString &fieldName = fields[i]->name();
+					const TString uniformName = name + "." + fieldName;
+
+					declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);
+					fieldRegisterIndex += fieldType.totalRegisterCount();
+				}
+				if(encoder)
+				{
+					encoder->exitAggregateType();
+				}
+			}
+		}
+	}
+
+	GLenum OutputASM::glVariableType(const TType &type)
+	{
+		switch(type.getBasicType())
+		{
+		case EbtFloat:
+			if(type.isScalar())
+			{
+				return GL_FLOAT;
+			}
+			else if(type.isVector())
+			{
+				switch(type.getNominalSize())
+				{
+				case 2: return GL_FLOAT_VEC2;
+				case 3: return GL_FLOAT_VEC3;
+				case 4: return GL_FLOAT_VEC4;
+				default: UNREACHABLE(type.getNominalSize());
+				}
+			}
+			else if(type.isMatrix())
+			{
+				switch(type.getNominalSize())
+				{
+				case 2:
+					switch(type.getSecondarySize())
+					{
+					case 2: return GL_FLOAT_MAT2;
+					case 3: return GL_FLOAT_MAT2x3;
+					case 4: return GL_FLOAT_MAT2x4;
+					default: UNREACHABLE(type.getSecondarySize());
+					}
+				case 3:
+					switch(type.getSecondarySize())
+					{
+					case 2: return GL_FLOAT_MAT3x2;
+					case 3: return GL_FLOAT_MAT3;
+					case 4: return GL_FLOAT_MAT3x4;
+					default: UNREACHABLE(type.getSecondarySize());
+					}
+				case 4:
+					switch(type.getSecondarySize())
+					{
+					case 2: return GL_FLOAT_MAT4x2;
+					case 3: return GL_FLOAT_MAT4x3;
+					case 4: return GL_FLOAT_MAT4;
+					default: UNREACHABLE(type.getSecondarySize());
+					}
+				default: UNREACHABLE(type.getNominalSize());
+				}
+			}
+			else UNREACHABLE(0);
+			break;
+		case EbtInt:
+			if(type.isScalar())
+			{
+				return GL_INT;
+			}
+			else if(type.isVector())
+			{
+				switch(type.getNominalSize())
+				{
+				case 2: return GL_INT_VEC2;
+				case 3: return GL_INT_VEC3;
+				case 4: return GL_INT_VEC4;
+				default: UNREACHABLE(type.getNominalSize());
+				}
+			}
+			else UNREACHABLE(0);
+			break;
+		case EbtUInt:
+			if(type.isScalar())
+			{
+				return GL_UNSIGNED_INT;
+			}
+			else if(type.isVector())
+			{
+				switch(type.getNominalSize())
+				{
+				case 2: return GL_UNSIGNED_INT_VEC2;
+				case 3: return GL_UNSIGNED_INT_VEC3;
+				case 4: return GL_UNSIGNED_INT_VEC4;
+				default: UNREACHABLE(type.getNominalSize());
+				}
+			}
+			else UNREACHABLE(0);
+			break;
+		case EbtBool:
+			if(type.isScalar())
+			{
+				return GL_BOOL;
+			}
+			else if(type.isVector())
+			{
+				switch(type.getNominalSize())
+				{
+				case 2: return GL_BOOL_VEC2;
+				case 3: return GL_BOOL_VEC3;
+				case 4: return GL_BOOL_VEC4;
+				default: UNREACHABLE(type.getNominalSize());
+				}
+			}
+			else UNREACHABLE(0);
+			break;
+		case EbtSampler2D:
+			return GL_SAMPLER_2D;
+		case EbtISampler2D:
+			return GL_INT_SAMPLER_2D;
+		case EbtUSampler2D:
+			return GL_UNSIGNED_INT_SAMPLER_2D;
+		case EbtSamplerCube:
+			return GL_SAMPLER_CUBE;
+		case EbtISamplerCube:
+			return GL_INT_SAMPLER_CUBE;
+		case EbtUSamplerCube:
+			return GL_UNSIGNED_INT_SAMPLER_CUBE;
+		case EbtSamplerExternalOES:
+			return GL_SAMPLER_EXTERNAL_OES;
+		case EbtSampler3D:
+			return GL_SAMPLER_3D_OES;
+		case EbtISampler3D:
+			return GL_INT_SAMPLER_3D;
+		case EbtUSampler3D:
+			return GL_UNSIGNED_INT_SAMPLER_3D;
+		case EbtSampler2DArray:
+			return GL_SAMPLER_2D_ARRAY;
+		case EbtISampler2DArray:
+			return GL_INT_SAMPLER_2D_ARRAY;
+		case EbtUSampler2DArray:
+			return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
+		case EbtSampler2DShadow:
+			return GL_SAMPLER_2D_SHADOW;
+		case EbtSamplerCubeShadow:
+			return GL_SAMPLER_CUBE_SHADOW;
+		case EbtSampler2DArrayShadow:
+			return GL_SAMPLER_2D_ARRAY_SHADOW;
+		default:
+			UNREACHABLE(type.getBasicType());
+			break;
+		}
+
+		return GL_NONE;
+	}
+
+	GLenum OutputASM::glVariablePrecision(const TType &type)
+	{
+		if(type.getBasicType() == EbtFloat)
+		{
+			switch(type.getPrecision())
+			{
+			case EbpHigh:   return GL_HIGH_FLOAT;
+			case EbpMedium: return GL_MEDIUM_FLOAT;
+			case EbpLow:    return GL_LOW_FLOAT;
+			case EbpUndefined:
+				// Should be defined as the default precision by the parser
+			default: UNREACHABLE(type.getPrecision());
+			}
+		}
+		else if(type.getBasicType() == EbtInt)
+		{
+			switch(type.getPrecision())
+			{
+			case EbpHigh:   return GL_HIGH_INT;
+			case EbpMedium: return GL_MEDIUM_INT;
+			case EbpLow:    return GL_LOW_INT;
+			case EbpUndefined:
+				// Should be defined as the default precision by the parser
+			default: UNREACHABLE(type.getPrecision());
+			}
+		}
+
+		// Other types (boolean, sampler) don't have a precision
+		return GL_NONE;
+	}
+
+	int OutputASM::dim(TIntermNode *v)
+	{
+		TIntermTyped *vector = v->getAsTyped();
+		ASSERT(vector && vector->isRegister());
+		return vector->getNominalSize();
+	}
+
+	int OutputASM::dim2(TIntermNode *m)
+	{
+		TIntermTyped *matrix = m->getAsTyped();
+		ASSERT(matrix && matrix->isMatrix() && !matrix->isArray());
+		return matrix->getSecondarySize();
+	}
+
+	// Returns ~0u if no loop count could be determined
+	unsigned int OutputASM::loopCount(TIntermLoop *node)
+	{
+		// Parse loops of the form:
+		// for(int index = initial; index [comparator] limit; index += increment)
+		TIntermSymbol *index = 0;
+		TOperator comparator = EOpNull;
+		int initial = 0;
+		int limit = 0;
+		int increment = 0;
+
+		// Parse index name and intial value
+		if(node->getInit())
+		{
+			TIntermAggregate *init = node->getInit()->getAsAggregate();
+
+			if(init)
+			{
+				TIntermSequence &sequence = init->getSequence();
+				TIntermTyped *variable = sequence[0]->getAsTyped();
+
+				if(variable && variable->getQualifier() == EvqTemporary)
+				{
+					TIntermBinary *assign = variable->getAsBinaryNode();
+
+					if(assign->getOp() == EOpInitialize)
+					{
+						TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode();
+						TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion();
+
+						if(symbol && constant)
+						{
+							if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
+							{
+								index = symbol;
+								initial = constant->getUnionArrayPointer()[0].getIConst();
+							}
+						}
+					}
+				}
+			}
+		}
+
+		// Parse comparator and limit value
+		if(index && node->getCondition())
+		{
+			TIntermBinary *test = node->getCondition()->getAsBinaryNode();
+
+			if(test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
+			{
+				TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
+
+				if(constant)
+				{
+					if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
+					{
+						comparator = test->getOp();
+						limit = constant->getUnionArrayPointer()[0].getIConst();
+					}
+				}
+			}
+		}
+
+		// Parse increment
+		if(index && comparator != EOpNull && node->getExpression())
+		{
+			TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
+			TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
+
+			if(binaryTerminal)
+			{
+				TOperator op = binaryTerminal->getOp();
+				TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion();
+
+				if(constant)
+				{
+					if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
+					{
+						int value = constant->getUnionArrayPointer()[0].getIConst();
+
+						switch(op)
+						{
+						case EOpAddAssign: increment = value;  break;
+						case EOpSubAssign: increment = -value; break;
+						default: UNIMPLEMENTED();
+						}
+					}
+				}
+			}
+			else if(unaryTerminal)
+			{
+				TOperator op = unaryTerminal->getOp();
+
+				switch(op)
+				{
+				case EOpPostIncrement: increment = 1;  break;
+				case EOpPostDecrement: increment = -1; break;
+				case EOpPreIncrement:  increment = 1;  break;
+				case EOpPreDecrement:  increment = -1; break;
+				default: UNIMPLEMENTED();
+				}
+			}
+		}
+
+		if(index && comparator != EOpNull && increment != 0)
+		{
+			if(comparator == EOpLessThanEqual)
+			{
+				comparator = EOpLessThan;
+				limit += 1;
+			}
+
+			if(comparator == EOpLessThan)
+			{
+				int iterations = (limit - initial) / increment;
+
+				if(iterations <= 0)
+				{
+					iterations = 0;
+				}
+
+				return iterations;
+			}
+			else UNIMPLEMENTED();   // Falls through
+		}
+
+		return ~0u;
+	}
+
+	bool LoopUnrollable::traverse(TIntermNode *node)
+	{
+		loopDepth = 0;
+		loopUnrollable = true;
+
+		node->traverse(this);
+
+		return loopUnrollable;
+	}
+
+	bool LoopUnrollable::visitLoop(Visit visit, TIntermLoop *loop)
+	{
+		if(visit == PreVisit)
+		{
+			loopDepth++;
+		}
+		else if(visit == PostVisit)
+		{
+			loopDepth++;
+		}
+
+		return true;
+	}
+
+	bool LoopUnrollable::visitBranch(Visit visit, TIntermBranch *node)
+	{
+		if(!loopUnrollable)
+		{
+			return false;
+		}
+
+		if(!loopDepth)
+		{
+			return true;
+		}
+
+		switch(node->getFlowOp())
+		{
+		case EOpKill:
+		case EOpReturn:
+			break;
+		case EOpBreak:
+		case EOpContinue:
+			loopUnrollable = false;
+			break;
+		default: UNREACHABLE(node->getFlowOp());
+		}
+
+		return loopUnrollable;
+	}
+
+	bool LoopUnrollable::visitAggregate(Visit visit, TIntermAggregate *node)
+	{
+		return loopUnrollable;
+	}
+}
diff --git a/src/OpenGL/compiler/OutputASM.h b/src/OpenGL/compiler/OutputASM.h
index 854c262..eff3c78 100644
--- a/src/OpenGL/compiler/OutputASM.h
+++ b/src/OpenGL/compiler/OutputASM.h
@@ -1,365 +1,368 @@
-// 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.

-//

-

-#ifndef COMPILER_OUTPUTASM_H_

-#define COMPILER_OUTPUTASM_H_

-

-#include "intermediate.h"

-#include "ParseHelper.h"

-#include "Shader/PixelShader.hpp"

-#include "Shader/VertexShader.hpp"

-

-#include <list>

-#include <set>

-#include <map>

-

-namespace es2

-{

-	class Shader;

-}

-

-typedef unsigned int GLenum;

-

-namespace glsl

-{

-	struct BlockMemberInfo

-	{

-		BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}

-

-		BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)

-			: offset(offset),

-			arrayStride(arrayStride),

-			matrixStride(matrixStride),

-			isRowMajorMatrix(isRowMajorMatrix)

-		{}

-

-		static BlockMemberInfo getDefaultBlockInfo()

-		{

-			return BlockMemberInfo(-1, -1, -1, false);

-		}

-

-		int offset;

-		int arrayStride;

-		int matrixStride;

-		bool isRowMajorMatrix;

-	};

-

-	struct Uniform

-	{

-		Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo);

-

-		GLenum type;

-		GLenum precision;

-		std::string name;

-		int arraySize;

-

-		int registerIndex;

-

-		int blockId;

-		BlockMemberInfo blockInfo;

-	};

-

-	typedef std::vector<Uniform> ActiveUniforms;

-

-	struct UniformBlock

-	{

-		UniformBlock(const std::string& name, unsigned int dataSize, unsigned int arraySize,

-		             TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId);

-

-		std::string name;

-		unsigned int dataSize;

-		unsigned int arraySize;

-		TLayoutBlockStorage layout;

-		bool isRowMajorLayout;

-		std::vector<int> fields;

-

-		int registerIndex;

-

-		int blockId;

-	};

-

-	class BlockLayoutEncoder

-	{

-	public:

-		BlockLayoutEncoder(bool rowMajor);

-		virtual ~BlockLayoutEncoder() {}

-

-		BlockMemberInfo encodeType(const TType &type);

-

-		size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }

-

-		virtual void enterAggregateType() = 0;

-		virtual void exitAggregateType() = 0;

-

-		static const size_t BytesPerComponent = 4u;

-		static const unsigned int ComponentsPerRegister = 4u;

-

-		static size_t getBlockRegister(const BlockMemberInfo &info);

-		static size_t getBlockRegisterElement(const BlockMemberInfo &info);

-

-	protected:

-		size_t mCurrentOffset;

-		bool isRowMajor;

-

-		void nextRegister();

-

-		virtual void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;

-		virtual void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;

-	};

-

-	// Block layout according to the std140 block layout

-	// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification

-	class Std140BlockEncoder : public BlockLayoutEncoder

-	{

-	public:

-		Std140BlockEncoder(bool rowMajor);

-

-		void enterAggregateType() override;

-		void exitAggregateType() override;

-

-	protected:

-		void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) override;

-		void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) override;

-	};

-

-	typedef std::vector<UniformBlock> ActiveUniformBlocks;

-

-	struct Attribute

-	{

-		Attribute();

-		Attribute(GLenum type, const std::string &name, int arraySize, int location, int registerIndex);

-

-		GLenum type;

-		std::string name;

-		int arraySize;

-		int location;

-

-		int registerIndex;

-	};

-

-	typedef std::vector<Attribute> ActiveAttributes;

-

-	struct Varying

-	{

-		Varying(GLenum type, const std::string &name, int arraySize, int reg = -1, int col = -1)

-			: type(type), name(name), arraySize(arraySize), reg(reg), col(col)

-		{

-		}

-

-		bool isArray() const

-		{

-			return arraySize >= 1;

-		}

-

-		int size() const   // Unify with es2::Uniform?

-		{

-			return arraySize > 0 ? arraySize : 1;

-		}

-

-		GLenum type;

-		std::string name;

-		int arraySize;

-

-		int reg;    // First varying register, assigned during link

-		int col;    // First register element, assigned during link

-	};

-

-	typedef std::list<Varying> VaryingList;

-

-	class Shader

-	{

-		friend class OutputASM;

-	public:

-		virtual ~Shader() {};

-		virtual sw::Shader *getShader() const = 0;

-		virtual sw::PixelShader *getPixelShader() const;

-		virtual sw::VertexShader *getVertexShader() const;

-

-	protected:

-		VaryingList varyings;

-		ActiveUniforms activeUniforms;

-		ActiveAttributes activeAttributes;

-		ActiveUniformBlocks activeUniformBlocks;

-	};

-

-	struct Function

-	{

-		Function(int label, const char *name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)

-		{

-		}

-

-		Function(int label, const TString &name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)

-		{

-		}

-

-		int label;

-		TString name;

-		TIntermSequence *arg;

-		TIntermTyped *ret;

-	};

-

-	typedef sw::Shader::Instruction Instruction;

-

-	class Temporary;

-

-	class OutputASM : public TIntermTraverser

-	{

-	public:

-		explicit OutputASM(TParseContext &context, Shader *shaderObject);

-		~OutputASM();

-

-		void output();

-

-		void freeTemporary(Temporary *temporary);

-

-	private:

-		enum Scope

-		{

-			GLOBAL,

-			FUNCTION

-		};

-

-		struct TextureFunction

-		{

-			TextureFunction(const TString& name);

-

-			enum Method

-			{

-				IMPLICIT,   // Mipmap LOD determined implicitly (standard lookup)

-				LOD,

-				SIZE,   // textureSize()

-				FETCH,

-				GRAD

-			};

-

-			Method method;

-			bool proj;

-			bool offset;

-		};

-

-		void emitShader(Scope scope);

-

-		// Visit AST nodes and output their code to the body stream

-		virtual void visitSymbol(TIntermSymbol*);

-		virtual bool visitBinary(Visit visit, TIntermBinary*);

-		virtual bool visitUnary(Visit visit, TIntermUnary*);

-		virtual bool visitSelection(Visit visit, TIntermSelection*);

-		virtual bool visitAggregate(Visit visit, TIntermAggregate*);

-		virtual bool visitLoop(Visit visit, TIntermLoop*);

-		virtual bool visitBranch(Visit visit, TIntermBranch*);

-

-		sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;

-		Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0);

-		Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst, int dstIndex, TIntermNode *src0 = 0, int index0 = 0, TIntermNode *src1 = 0, int index1 = 0,

-		                  TIntermNode *src2 = 0, int index2 = 0, TIntermNode *src3 = 0, int index3 = 0, TIntermNode *src4 = 0, int index4 = 0);

-		Instruction *emitCast(TIntermTyped *dst, TIntermTyped *src);

-		Instruction *emitCast(TIntermTyped *dst, int dstIndex, TIntermTyped *src, int srcIndex);

-		void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0);

-		void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);

-		void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);

-		void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);

-		void argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);

-		void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);

-		void assignLvalue(TIntermTyped *dst, TIntermTyped *src);

-		int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);

-		sw::Shader::ParameterType registerType(TIntermTyped *operand);

-		unsigned int registerIndex(TIntermTyped *operand);

-		int writeMask(TIntermTyped *destination, int index = 0);

-		int readSwizzle(TIntermTyped *argument, int size);

-		bool trivial(TIntermTyped *expression, int budget);   // Fast to compute and no side effects

-		int cost(TIntermNode *expression, int budget);

-		const Function *findFunction(const TString &name);

-

-		int temporaryRegister(TIntermTyped *temporary);

-		int varyingRegister(TIntermTyped *varying);

-		void declareVarying(TIntermTyped *varying, int reg);

-		int uniformRegister(TIntermTyped *uniform);

-		int attributeRegister(TIntermTyped *attribute);

-		int fragmentOutputRegister(TIntermTyped *fragmentOutput);

-		int samplerRegister(TIntermTyped *sampler);

-		int samplerRegister(TIntermSymbol *sampler);

-		bool isSamplerRegister(TIntermTyped *operand);

-

-		typedef std::vector<TIntermTyped*> VariableArray;

-

-		int lookup(VariableArray &list, TIntermTyped *variable);

-		int lookup(VariableArray &list, TInterfaceBlock *block);

-		int blockMemberLookup(const TType &type, const TString &name, int registerIndex);

-		int allocate(VariableArray &list, TIntermTyped *variable);

-		void free(VariableArray &list, TIntermTyped *variable);

-

-		void declareUniform(const TType &type, const TString &name, int registerIndex, int blockId = -1, BlockLayoutEncoder* encoder = nullptr);

-		GLenum glVariableType(const TType &type);

-		GLenum glVariablePrecision(const TType &type);

-

-		static int dim(TIntermNode *v);

-		static int dim2(TIntermNode *m);

-		static unsigned int loopCount(TIntermLoop *node);

-

-		Shader *const shaderObject;

-		sw::Shader *shader;

-		sw::PixelShader *pixelShader;

-		sw::VertexShader *vertexShader;

-

-		VariableArray temporaries;

-		VariableArray uniforms;

-		VariableArray varyings;

-		VariableArray attributes;

-		VariableArray samplers;

-		VariableArray fragmentOutputs;

-

-		struct TypedMemberInfo : public BlockMemberInfo

-		{

-			TypedMemberInfo() {}

-			TypedMemberInfo(const BlockMemberInfo& b, const TType& t) : BlockMemberInfo(b), type(t) {}

-			TType type;

-		};

-		struct ArgumentInfo

-		{

-			ArgumentInfo(const BlockMemberInfo& b, const TType& t, int clampedIndex, int bufferIndex) :

-			    typedMemberInfo(b, t), clampedIndex(clampedIndex), bufferIndex(bufferIndex) {}

-			TypedMemberInfo typedMemberInfo;

-			int clampedIndex;

-			int bufferIndex;

-		};

-		int getBlockId(TIntermTyped *argument);

-		ArgumentInfo getArgumentInfo(TIntermTyped *argument, int index);

-

-		typedef std::map<int, TypedMemberInfo> BlockDefinitionIndexMap;

-		std::vector<BlockDefinitionIndexMap> blockDefinitions;

-

-		Scope emitScope;

-		Scope currentScope;

-

-		int currentFunction;

-		std::vector<Function> functionArray;

-

-		TQualifier outputQualifier;

-

-		TParseContext &mContext;

-	};

-

-	class LoopUnrollable : public TIntermTraverser

-	{

-	public:

-		bool traverse(TIntermNode *node);

-

-	private:

-		bool visitBranch(Visit visit, TIntermBranch *node);

-		bool visitLoop(Visit visit, TIntermLoop *loop);

-		bool visitAggregate(Visit visit, TIntermAggregate *node);

-

-		int loopDepth;

-		bool loopUnrollable;

-	};

-}

-

-#endif   // COMPILER_OUTPUTASM_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_OUTPUTASM_H_
+#define COMPILER_OUTPUTASM_H_
+
+#include "intermediate.h"
+#include "ParseHelper.h"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+
+#include <list>
+#include <set>
+#include <map>
+
+namespace es2
+{
+	class Shader;
+}
+
+typedef unsigned int GLenum;
+
+namespace glsl
+{
+	struct BlockMemberInfo
+	{
+		BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
+
+		BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
+			: offset(offset),
+			arrayStride(arrayStride),
+			matrixStride(matrixStride),
+			isRowMajorMatrix(isRowMajorMatrix)
+		{}
+
+		static BlockMemberInfo getDefaultBlockInfo()
+		{
+			return BlockMemberInfo(-1, -1, -1, false);
+		}
+
+		int offset;
+		int arrayStride;
+		int matrixStride;
+		bool isRowMajorMatrix;
+	};
+
+	struct Uniform
+	{
+		Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo);
+
+		GLenum type;
+		GLenum precision;
+		std::string name;
+		int arraySize;
+
+		int registerIndex;
+
+		int blockId;
+		BlockMemberInfo blockInfo;
+	};
+
+	typedef std::vector<Uniform> ActiveUniforms;
+
+	struct UniformBlock
+	{
+		UniformBlock(const std::string& name, unsigned int dataSize, unsigned int arraySize,
+		             TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId);
+
+		std::string name;
+		unsigned int dataSize;
+		unsigned int arraySize;
+		TLayoutBlockStorage layout;
+		bool isRowMajorLayout;
+		std::vector<int> fields;
+
+		int registerIndex;
+
+		int blockId;
+	};
+
+	class BlockLayoutEncoder
+	{
+	public:
+		BlockLayoutEncoder(bool rowMajor);
+		virtual ~BlockLayoutEncoder() {}
+
+		BlockMemberInfo encodeType(const TType &type);
+
+		size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
+
+		virtual void enterAggregateType() = 0;
+		virtual void exitAggregateType() = 0;
+
+		static const size_t BytesPerComponent = 4u;
+		static const unsigned int ComponentsPerRegister = 4u;
+
+		static size_t getBlockRegister(const BlockMemberInfo &info);
+		static size_t getBlockRegisterElement(const BlockMemberInfo &info);
+
+	protected:
+		size_t mCurrentOffset;
+		bool isRowMajor;
+
+		void nextRegister();
+
+		virtual void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
+		virtual void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
+	};
+
+	// Block layout according to the std140 block layout
+	// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
+	class Std140BlockEncoder : public BlockLayoutEncoder
+	{
+	public:
+		Std140BlockEncoder(bool rowMajor);
+
+		void enterAggregateType() override;
+		void exitAggregateType() override;
+
+	protected:
+		void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) override;
+		void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) override;
+	};
+
+	typedef std::vector<UniformBlock> ActiveUniformBlocks;
+
+	struct Attribute
+	{
+		Attribute();
+		Attribute(GLenum type, const std::string &name, int arraySize, int location, int registerIndex);
+
+		GLenum type;
+		std::string name;
+		int arraySize;
+		int location;
+
+		int registerIndex;
+	};
+
+	typedef std::vector<Attribute> ActiveAttributes;
+
+	struct Varying
+	{
+		Varying(GLenum type, const std::string &name, int arraySize, int reg = -1, int col = -1)
+			: type(type), name(name), arraySize(arraySize), reg(reg), col(col)
+		{
+		}
+
+		bool isArray() const
+		{
+			return arraySize >= 1;
+		}
+
+		int size() const   // Unify with es2::Uniform?
+		{
+			return arraySize > 0 ? arraySize : 1;
+		}
+
+		GLenum type;
+		std::string name;
+		int arraySize;
+
+		int reg;    // First varying register, assigned during link
+		int col;    // First register element, assigned during link
+	};
+
+	typedef std::list<Varying> VaryingList;
+
+	class Shader
+	{
+		friend class OutputASM;
+	public:
+		virtual ~Shader() {};
+		virtual sw::Shader *getShader() const = 0;
+		virtual sw::PixelShader *getPixelShader() const;
+		virtual sw::VertexShader *getVertexShader() const;
+
+	protected:
+		VaryingList varyings;
+		ActiveUniforms activeUniforms;
+		ActiveAttributes activeAttributes;
+		ActiveUniformBlocks activeUniformBlocks;
+	};
+
+	struct Function
+	{
+		Function(int label, const char *name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)
+		{
+		}
+
+		Function(int label, const TString &name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)
+		{
+		}
+
+		int label;
+		TString name;
+		TIntermSequence *arg;
+		TIntermTyped *ret;
+	};
+
+	typedef sw::Shader::Instruction Instruction;
+
+	class Temporary;
+
+	class OutputASM : public TIntermTraverser
+	{
+	public:
+		explicit OutputASM(TParseContext &context, Shader *shaderObject);
+		~OutputASM();
+
+		void output();
+
+		void freeTemporary(Temporary *temporary);
+
+	private:
+		enum Scope
+		{
+			GLOBAL,
+			FUNCTION
+		};
+
+		struct TextureFunction
+		{
+			TextureFunction(const TString& name);
+
+			enum Method
+			{
+				IMPLICIT,   // Mipmap LOD determined implicitly (standard lookup)
+				LOD,
+				SIZE,   // textureSize()
+				FETCH,
+				GRAD
+			};
+
+			Method method;
+			bool proj;
+			bool offset;
+		};
+
+		void emitShader(Scope scope);
+
+		// Visit AST nodes and output their code to the body stream
+		virtual void visitSymbol(TIntermSymbol*);
+		virtual bool visitBinary(Visit visit, TIntermBinary*);
+		virtual bool visitUnary(Visit visit, TIntermUnary*);
+		virtual bool visitSelection(Visit visit, TIntermSelection*);
+		virtual bool visitAggregate(Visit visit, TIntermAggregate*);
+		virtual bool visitLoop(Visit visit, TIntermLoop*);
+		virtual bool visitBranch(Visit visit, TIntermBranch*);
+
+		sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;
+		Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0);
+		Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst, int dstIndex, TIntermNode *src0 = 0, int index0 = 0, TIntermNode *src1 = 0, int index1 = 0,
+		                  TIntermNode *src2 = 0, int index2 = 0, TIntermNode *src3 = 0, int index3 = 0, TIntermNode *src4 = 0, int index4 = 0);
+		Instruction *emitCast(TIntermTyped *dst, TIntermTyped *src);
+		Instruction *emitCast(TIntermTyped *dst, int dstIndex, TIntermTyped *src, int srcIndex);
+		void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0);
+		void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);
+		void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
+		void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);
+		void argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);
+		void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
+		void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
+		int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
+		sw::Shader::ParameterType registerType(TIntermTyped *operand);
+		unsigned int registerIndex(TIntermTyped *operand);
+		int writeMask(TIntermTyped *destination, int index = 0);
+		int readSwizzle(TIntermTyped *argument, int size);
+		bool trivial(TIntermTyped *expression, int budget);   // Fast to compute and no side effects
+		int cost(TIntermNode *expression, int budget);
+		const Function *findFunction(const TString &name);
+
+		int temporaryRegister(TIntermTyped *temporary);
+		int varyingRegister(TIntermTyped *varying);
+		void declareVarying(TIntermTyped *varying, int reg);
+		int uniformRegister(TIntermTyped *uniform);
+		int attributeRegister(TIntermTyped *attribute);
+		int fragmentOutputRegister(TIntermTyped *fragmentOutput);
+		int samplerRegister(TIntermTyped *sampler);
+		int samplerRegister(TIntermSymbol *sampler);
+		bool isSamplerRegister(TIntermTyped *operand);
+
+		typedef std::vector<TIntermTyped*> VariableArray;
+
+		int lookup(VariableArray &list, TIntermTyped *variable);
+		int lookup(VariableArray &list, TInterfaceBlock *block);
+		int blockMemberLookup(const TType &type, const TString &name, int registerIndex);
+		int allocate(VariableArray &list, TIntermTyped *variable);
+		void free(VariableArray &list, TIntermTyped *variable);
+
+		void declareUniform(const TType &type, const TString &name, int registerIndex, int blockId = -1, BlockLayoutEncoder* encoder = nullptr);
+		GLenum glVariableType(const TType &type);
+		GLenum glVariablePrecision(const TType &type);
+
+		static int dim(TIntermNode *v);
+		static int dim2(TIntermNode *m);
+		static unsigned int loopCount(TIntermLoop *node);
+
+		Shader *const shaderObject;
+		sw::Shader *shader;
+		sw::PixelShader *pixelShader;
+		sw::VertexShader *vertexShader;
+
+		VariableArray temporaries;
+		VariableArray uniforms;
+		VariableArray varyings;
+		VariableArray attributes;
+		VariableArray samplers;
+		VariableArray fragmentOutputs;
+
+		struct TypedMemberInfo : public BlockMemberInfo
+		{
+			TypedMemberInfo() {}
+			TypedMemberInfo(const BlockMemberInfo& b, const TType& t) : BlockMemberInfo(b), type(t) {}
+			TType type;
+		};
+		struct ArgumentInfo
+		{
+			ArgumentInfo(const BlockMemberInfo& b, const TType& t, int clampedIndex, int bufferIndex) :
+			    typedMemberInfo(b, t), clampedIndex(clampedIndex), bufferIndex(bufferIndex) {}
+			TypedMemberInfo typedMemberInfo;
+			int clampedIndex;
+			int bufferIndex;
+		};
+		int getBlockId(TIntermTyped *argument);
+		ArgumentInfo getArgumentInfo(TIntermTyped *argument, int index);
+
+		typedef std::map<int, TypedMemberInfo> BlockDefinitionIndexMap;
+		std::vector<BlockDefinitionIndexMap> blockDefinitions;
+
+		Scope emitScope;
+		Scope currentScope;
+
+		int currentFunction;
+		std::vector<Function> functionArray;
+
+		TQualifier outputQualifier;
+
+		TParseContext &mContext;
+	};
+
+	class LoopUnrollable : public TIntermTraverser
+	{
+	public:
+		bool traverse(TIntermNode *node);
+
+	private:
+		bool visitBranch(Visit visit, TIntermBranch *node);
+		bool visitLoop(Visit visit, TIntermLoop *loop);
+		bool visitAggregate(Visit visit, TIntermAggregate *node);
+
+		int loopDepth;
+		bool loopUnrollable;
+	};
+}
+
+#endif   // COMPILER_OUTPUTASM_H_
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index 87f1e2d..9d8d6a2 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "ParseHelper.h"
 
@@ -26,89 +34,89 @@
 //
 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc &line)
 {
-    fields.num = (int) compString.size();
-    if (fields.num > 4) {
-        error(line, "illegal vector field selection", compString.c_str());
-        return false;
-    }
+	fields.num = (int) compString.size();
+	if (fields.num > 4) {
+		error(line, "illegal vector field selection", compString.c_str());
+		return false;
+	}
 
-    enum {
-        exyzw,
-        ergba,
-        estpq
-    } fieldSet[4];
+	enum {
+		exyzw,
+		ergba,
+		estpq
+	} fieldSet[4];
 
-    for (int i = 0; i < fields.num; ++i) {
-        switch (compString[i])  {
-        case 'x':
-            fields.offsets[i] = 0;
-            fieldSet[i] = exyzw;
-            break;
-        case 'r':
-            fields.offsets[i] = 0;
-            fieldSet[i] = ergba;
-            break;
-        case 's':
-            fields.offsets[i] = 0;
-            fieldSet[i] = estpq;
-            break;
-        case 'y':
-            fields.offsets[i] = 1;
-            fieldSet[i] = exyzw;
-            break;
-        case 'g':
-            fields.offsets[i] = 1;
-            fieldSet[i] = ergba;
-            break;
-        case 't':
-            fields.offsets[i] = 1;
-            fieldSet[i] = estpq;
-            break;
-        case 'z':
-            fields.offsets[i] = 2;
-            fieldSet[i] = exyzw;
-            break;
-        case 'b':
-            fields.offsets[i] = 2;
-            fieldSet[i] = ergba;
-            break;
-        case 'p':
-            fields.offsets[i] = 2;
-            fieldSet[i] = estpq;
-            break;
-        case 'w':
-            fields.offsets[i] = 3;
-            fieldSet[i] = exyzw;
-            break;
-        case 'a':
-            fields.offsets[i] = 3;
-            fieldSet[i] = ergba;
-            break;
-        case 'q':
-            fields.offsets[i] = 3;
-            fieldSet[i] = estpq;
-            break;
-        default:
-            error(line, "illegal vector field selection", compString.c_str());
-            return false;
-        }
-    }
+	for (int i = 0; i < fields.num; ++i) {
+		switch (compString[i])  {
+		case 'x':
+			fields.offsets[i] = 0;
+			fieldSet[i] = exyzw;
+			break;
+		case 'r':
+			fields.offsets[i] = 0;
+			fieldSet[i] = ergba;
+			break;
+		case 's':
+			fields.offsets[i] = 0;
+			fieldSet[i] = estpq;
+			break;
+		case 'y':
+			fields.offsets[i] = 1;
+			fieldSet[i] = exyzw;
+			break;
+		case 'g':
+			fields.offsets[i] = 1;
+			fieldSet[i] = ergba;
+			break;
+		case 't':
+			fields.offsets[i] = 1;
+			fieldSet[i] = estpq;
+			break;
+		case 'z':
+			fields.offsets[i] = 2;
+			fieldSet[i] = exyzw;
+			break;
+		case 'b':
+			fields.offsets[i] = 2;
+			fieldSet[i] = ergba;
+			break;
+		case 'p':
+			fields.offsets[i] = 2;
+			fieldSet[i] = estpq;
+			break;
+		case 'w':
+			fields.offsets[i] = 3;
+			fieldSet[i] = exyzw;
+			break;
+		case 'a':
+			fields.offsets[i] = 3;
+			fieldSet[i] = ergba;
+			break;
+		case 'q':
+			fields.offsets[i] = 3;
+			fieldSet[i] = estpq;
+			break;
+		default:
+			error(line, "illegal vector field selection", compString.c_str());
+			return false;
+		}
+	}
 
-    for (int i = 0; i < fields.num; ++i) {
-        if (fields.offsets[i] >= vecSize) {
-            error(line, "vector field selection out of range",  compString.c_str());
-            return false;
-        }
+	for (int i = 0; i < fields.num; ++i) {
+		if (fields.offsets[i] >= vecSize) {
+			error(line, "vector field selection out of range",  compString.c_str());
+			return false;
+		}
 
-        if (i > 0) {
-            if (fieldSet[i] != fieldSet[i-1]) {
-                error(line, "illegal - vector component fields not from the same set", compString.c_str());
-                return false;
-            }
-        }
-    }
+		if (i > 0) {
+			if (fieldSet[i] != fieldSet[i-1]) {
+				error(line, "illegal - vector component fields not from the same set", compString.c_str());
+				return false;
+			}
+		}
+	}
 
-    return true;
+	return true;
 }
 
 
@@ -118,46 +126,46 @@
 //
 bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc &line)
 {
-    fields.wholeRow = false;
-    fields.wholeCol = false;
-    fields.row = -1;
-    fields.col = -1;
+	fields.wholeRow = false;
+	fields.wholeCol = false;
+	fields.row = -1;
+	fields.col = -1;
 
-    if (compString.size() != 2) {
-        error(line, "illegal length of matrix field selection", compString.c_str());
-        return false;
-    }
+	if (compString.size() != 2) {
+		error(line, "illegal length of matrix field selection", compString.c_str());
+		return false;
+	}
 
-    if (compString[0] == '_') {
-        if (compString[1] < '0' || compString[1] > '3') {
-            error(line, "illegal matrix field selection", compString.c_str());
-            return false;
-        }
-        fields.wholeCol = true;
-        fields.col = compString[1] - '0';
-    } else if (compString[1] == '_') {
-        if (compString[0] < '0' || compString[0] > '3') {
-            error(line, "illegal matrix field selection", compString.c_str());
-            return false;
-        }
-        fields.wholeRow = true;
-        fields.row = compString[0] - '0';
-    } else {
-        if (compString[0] < '0' || compString[0] > '3' ||
-            compString[1] < '0' || compString[1] > '3') {
-            error(line, "illegal matrix field selection", compString.c_str());
-            return false;
-        }
-        fields.row = compString[0] - '0';
-        fields.col = compString[1] - '0';
-    }
+	if (compString[0] == '_') {
+		if (compString[1] < '0' || compString[1] > '3') {
+			error(line, "illegal matrix field selection", compString.c_str());
+			return false;
+		}
+		fields.wholeCol = true;
+		fields.col = compString[1] - '0';
+	} else if (compString[1] == '_') {
+		if (compString[0] < '0' || compString[0] > '3') {
+			error(line, "illegal matrix field selection", compString.c_str());
+			return false;
+		}
+		fields.wholeRow = true;
+		fields.row = compString[0] - '0';
+	} else {
+		if (compString[0] < '0' || compString[0] > '3' ||
+			compString[1] < '0' || compString[1] > '3') {
+			error(line, "illegal matrix field selection", compString.c_str());
+			return false;
+		}
+		fields.row = compString[0] - '0';
+		fields.col = compString[1] - '0';
+	}
 
-    if (fields.row >= matRows || fields.col >= matCols) {
-        error(line, "matrix field selection out of range", compString.c_str());
-        return false;
-    }
+	if (fields.row >= matRows || fields.col >= matCols) {
+		error(line, "matrix field selection out of range", compString.c_str());
+		return false;
+	}
 
-    return true;
+	return true;
 }
 
 ///////////////////////////////////////////////////////////////////////
@@ -177,26 +185,26 @@
 // Used by flex/bison to output all syntax and parsing errors.
 //
 void TParseContext::error(const TSourceLoc& loc,
-                          const char* reason, const char* token,
-                          const char* extraInfo)
+						  const char* reason, const char* token,
+						  const char* extraInfo)
 {
-    pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
-    mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
-                           srcLoc, reason, token, extraInfo);
+	pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
+	mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
+						   srcLoc, reason, token, extraInfo);
 
 }
 
 void TParseContext::warning(const TSourceLoc& loc,
-                            const char* reason, const char* token,
-                            const char* extraInfo) {
-    pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
-    mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
-                           srcLoc, reason, token, extraInfo);
+							const char* reason, const char* token,
+							const char* extraInfo) {
+	pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
+	mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
+						   srcLoc, reason, token, extraInfo);
 }
 
 void TParseContext::trace(const char* str)
 {
-    mDiagnostics.writeDebug(str);
+	mDiagnostics.writeDebug(str);
 }
 
 //
@@ -204,10 +212,10 @@
 //
 void TParseContext::assignError(const TSourceLoc &line, const char* op, TString left, TString right)
 {
-    std::stringstream extraInfoStream;
-    extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
-    std::string extraInfo = extraInfoStream.str();
-    error(line, "", op, extraInfo.c_str());
+	std::stringstream extraInfoStream;
+	extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
+	std::string extraInfo = extraInfoStream.str();
+	error(line, "", op, extraInfo.c_str());
 }
 
 //
@@ -215,11 +223,11 @@
 //
 void TParseContext::unaryOpError(const TSourceLoc &line, const char* op, TString operand)
 {
-    std::stringstream extraInfoStream;
-    extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
-                    << " (or there is no acceptable conversion)";
-    std::string extraInfo = extraInfoStream.str();
-    error(line, " wrong operand type", op, extraInfo.c_str());
+	std::stringstream extraInfoStream;
+	extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
+					<< " (or there is no acceptable conversion)";
+	std::string extraInfo = extraInfoStream.str();
+	error(line, " wrong operand type", op, extraInfo.c_str());
 }
 
 //
@@ -227,33 +235,33 @@
 //
 void TParseContext::binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right)
 {
-    std::stringstream extraInfoStream;
-    extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
-                    << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
-    std::string extraInfo = extraInfoStream.str();
-    error(line, " wrong operand types ", op, extraInfo.c_str());
+	std::stringstream extraInfoStream;
+	extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
+					<< "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
+	std::string extraInfo = extraInfoStream.str();
+	error(line, " wrong operand types ", op, extraInfo.c_str());
 }
 
 bool TParseContext::precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type){
-    if (!mChecksPrecisionErrors)
-        return false;
-    switch( type ){
-    case EbtFloat:
-        if( precision == EbpUndefined ){
-            error( line, "No precision specified for (float)", "" );
-            return true;
-        }
-        break;
-    case EbtInt:
-        if( precision == EbpUndefined ){
-            error( line, "No precision specified (int)", "" );
-            return true;
-        }
-        break;
-    default:
-        return false;
-    }
-    return false;
+	if (!mChecksPrecisionErrors)
+		return false;
+	switch( type ){
+	case EbtFloat:
+		if( precision == EbpUndefined ){
+			error( line, "No precision specified for (float)", "" );
+			return true;
+		}
+		break;
+	case EbtInt:
+		if( precision == EbpUndefined ){
+			error( line, "No precision specified (int)", "" );
+			return true;
+		}
+		break;
+	default:
+		return false;
+	}
+	return false;
 }
 
 //
@@ -264,113 +272,113 @@
 //
 bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped* node)
 {
-    TIntermSymbol* symNode = node->getAsSymbolNode();
-    TIntermBinary* binaryNode = node->getAsBinaryNode();
+	TIntermSymbol* symNode = node->getAsSymbolNode();
+	TIntermBinary* binaryNode = node->getAsBinaryNode();
 
-    if (binaryNode) {
-        bool errorReturn;
+	if (binaryNode) {
+		bool errorReturn;
 
-        switch(binaryNode->getOp()) {
-        case EOpIndexDirect:
-        case EOpIndexIndirect:
-        case EOpIndexDirectStruct:
-            return lValueErrorCheck(line, op, binaryNode->getLeft());
-        case EOpVectorSwizzle:
-            errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
-            if (!errorReturn) {
-                int offset[4] = {0,0,0,0};
+		switch(binaryNode->getOp()) {
+		case EOpIndexDirect:
+		case EOpIndexIndirect:
+		case EOpIndexDirectStruct:
+			return lValueErrorCheck(line, op, binaryNode->getLeft());
+		case EOpVectorSwizzle:
+			errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
+			if (!errorReturn) {
+				int offset[4] = {0,0,0,0};
 
-                TIntermTyped* rightNode = binaryNode->getRight();
-                TIntermAggregate *aggrNode = rightNode->getAsAggregate();
+				TIntermTyped* rightNode = binaryNode->getRight();
+				TIntermAggregate *aggrNode = rightNode->getAsAggregate();
 
-                for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
-                                               p != aggrNode->getSequence().end(); p++) {
-                    int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
-                    offset[value]++;
-                    if (offset[value] > 1) {
-                        error(line, " l-value of swizzle cannot have duplicate components", op);
+				for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
+											   p != aggrNode->getSequence().end(); p++) {
+					int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
+					offset[value]++;
+					if (offset[value] > 1) {
+						error(line, " l-value of swizzle cannot have duplicate components", op);
 
-                        return true;
-                    }
-                }
-            }
+						return true;
+					}
+				}
+			}
 
-            return errorReturn;
-        default:
-            break;
-        }
-        error(line, " l-value required", op);
+			return errorReturn;
+		default:
+			break;
+		}
+		error(line, " l-value required", op);
 
-        return true;
-    }
+		return true;
+	}
 
 
-    const char* symbol = 0;
-    if (symNode != 0)
-        symbol = symNode->getSymbol().c_str();
+	const char* symbol = 0;
+	if (symNode != 0)
+		symbol = symNode->getSymbol().c_str();
 
-    const char* message = 0;
-    switch (node->getQualifier()) {
-    case EvqConstExpr:      message = "can't modify a const";        break;
-    case EvqConstReadOnly:  message = "can't modify a const";        break;
-    case EvqAttribute:      message = "can't modify an attribute";   break;
-    case EvqFragmentIn:     message = "can't modify an input";       break;
-    case EvqVertexIn:       message = "can't modify an input";       break;
-    case EvqUniform:        message = "can't modify a uniform";      break;
-    case EvqSmoothIn:
-    case EvqFlatIn:
-    case EvqCentroidIn:
-    case EvqVaryingIn:      message = "can't modify a varying";      break;
-    case EvqInput:          message = "can't modify an input";       break;
-    case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
-    case EvqFrontFacing:    message = "can't modify gl_FrontFacing"; break;
-    case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
-    case EvqInstanceID:     message = "can't modify gl_InstanceID";  break;
-    default:
+	const char* message = 0;
+	switch (node->getQualifier()) {
+	case EvqConstExpr:      message = "can't modify a const";        break;
+	case EvqConstReadOnly:  message = "can't modify a const";        break;
+	case EvqAttribute:      message = "can't modify an attribute";   break;
+	case EvqFragmentIn:     message = "can't modify an input";       break;
+	case EvqVertexIn:       message = "can't modify an input";       break;
+	case EvqUniform:        message = "can't modify a uniform";      break;
+	case EvqSmoothIn:
+	case EvqFlatIn:
+	case EvqCentroidIn:
+	case EvqVaryingIn:      message = "can't modify a varying";      break;
+	case EvqInput:          message = "can't modify an input";       break;
+	case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
+	case EvqFrontFacing:    message = "can't modify gl_FrontFacing"; break;
+	case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
+	case EvqInstanceID:     message = "can't modify gl_InstanceID";  break;
+	default:
 
-        //
-        // Type that can't be written to?
-        //
-        if(IsSampler(node->getBasicType()))
-        {
-            message = "can't modify a sampler";
-        }
-        else if(node->getBasicType() == EbtVoid)
-        {
-            message = "can't modify void";
-        }
-    }
+		//
+		// Type that can't be written to?
+		//
+		if(IsSampler(node->getBasicType()))
+		{
+			message = "can't modify a sampler";
+		}
+		else if(node->getBasicType() == EbtVoid)
+		{
+			message = "can't modify void";
+		}
+	}
 
-    if (message == 0 && binaryNode == 0 && symNode == 0) {
-        error(line, " l-value required", op);
+	if (message == 0 && binaryNode == 0 && symNode == 0) {
+		error(line, " l-value required", op);
 
-        return true;
-    }
+		return true;
+	}
 
 
-    //
-    // Everything else is okay, no error.
-    //
-    if (message == 0)
-        return false;
+	//
+	// Everything else is okay, no error.
+	//
+	if (message == 0)
+		return false;
 
-    //
-    // If we get here, we have an error and a message.
-    //
-    if (symNode) {
-        std::stringstream extraInfoStream;
-        extraInfoStream << "\"" << symbol << "\" (" << message << ")";
-        std::string extraInfo = extraInfoStream.str();
-        error(line, " l-value required", op, extraInfo.c_str());
-    }
-    else {
-        std::stringstream extraInfoStream;
-        extraInfoStream << "(" << message << ")";
-        std::string extraInfo = extraInfoStream.str();
-        error(line, " l-value required", op, extraInfo.c_str());
-    }
+	//
+	// If we get here, we have an error and a message.
+	//
+	if (symNode) {
+		std::stringstream extraInfoStream;
+		extraInfoStream << "\"" << symbol << "\" (" << message << ")";
+		std::string extraInfo = extraInfoStream.str();
+		error(line, " l-value required", op, extraInfo.c_str());
+	}
+	else {
+		std::stringstream extraInfoStream;
+		extraInfoStream << "(" << message << ")";
+		std::string extraInfo = extraInfoStream.str();
+		error(line, " l-value required", op, extraInfo.c_str());
+	}
 
-    return true;
+	return true;
 }
 
 //
@@ -381,12 +389,12 @@
 //
 bool TParseContext::constErrorCheck(TIntermTyped* node)
 {
-    if (node->getQualifier() == EvqConstExpr)
-        return false;
+	if (node->getQualifier() == EvqConstExpr)
+		return false;
 
-    error(node->getLine(), "constant expression required", "");
+	error(node->getLine(), "constant expression required", "");
 
-    return true;
+	return true;
 }
 
 //
@@ -397,12 +405,12 @@
 //
 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
 {
-    if (node->isScalarInt())
-        return false;
+	if (node->isScalarInt())
+		return false;
 
-    error(node->getLine(), "integer expression required", token);
+	error(node->getLine(), "integer expression required", token);
 
-    return true;
+	return true;
 }
 
 //
@@ -413,12 +421,12 @@
 //
 bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char* token)
 {
-    if (global)
-        return false;
+	if (global)
+		return false;
 
-    error(line, "only allowed at global scope", token);
+	error(line, "only allowed at global scope", token);
 
-    return true;
+	return true;
 }
 
 //
@@ -432,19 +440,19 @@
 //
 bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString& identifier)
 {
-    static const char* reservedErrMsg = "reserved built-in name";
-    if (!symbolTable.atBuiltInLevel()) {
-        if (identifier.compare(0, 3, "gl_") == 0) {
-            error(line, reservedErrMsg, "gl_");
-            return true;
-        }
-        if (identifier.find("__") != TString::npos) {
-            error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
-            return true;
-        }
-    }
+	static const char* reservedErrMsg = "reserved built-in name";
+	if (!symbolTable.atBuiltInLevel()) {
+		if (identifier.compare(0, 3, "gl_") == 0) {
+			error(line, reservedErrMsg, "gl_");
+			return true;
+		}
+		if (identifier.find("__") != TString::npos) {
+			error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
+			return true;
+		}
+	}
 
-    return false;
+	return false;
 }
 
 //
@@ -456,104 +464,104 @@
 //
 bool TParseContext::constructorErrorCheck(const TSourceLoc &line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
 {
-    *type = function.getReturnType();
+	*type = function.getReturnType();
 
-    bool constructingMatrix = false;
-    switch(op) {
-    case EOpConstructMat2:
-    case EOpConstructMat2x3:
-    case EOpConstructMat2x4:
-    case EOpConstructMat3x2:
-    case EOpConstructMat3:
-    case EOpConstructMat3x4:
-    case EOpConstructMat4x2:
-    case EOpConstructMat4x3:
-    case EOpConstructMat4:
-        constructingMatrix = true;
-        break;
-    default:
-        break;
-    }
+	bool constructingMatrix = false;
+	switch(op) {
+	case EOpConstructMat2:
+	case EOpConstructMat2x3:
+	case EOpConstructMat2x4:
+	case EOpConstructMat3x2:
+	case EOpConstructMat3:
+	case EOpConstructMat3x4:
+	case EOpConstructMat4x2:
+	case EOpConstructMat4x3:
+	case EOpConstructMat4:
+		constructingMatrix = true;
+		break;
+	default:
+		break;
+	}
 
-    //
-    // Note: It's okay to have too many components available, but not okay to have unused
-    // arguments.  'full' will go to true when enough args have been seen.  If we loop
-    // again, there is an extra argument, so 'overfull' will become true.
-    //
+	//
+	// Note: It's okay to have too many components available, but not okay to have unused
+	// arguments.  'full' will go to true when enough args have been seen.  If we loop
+	// again, there is an extra argument, so 'overfull' will become true.
+	//
 
-    size_t size = 0;
-    bool full = false;
-    bool overFull = false;
-    bool matrixInMatrix = false;
-    bool arrayArg = false;
-    for (size_t i = 0; i < function.getParamCount(); ++i) {
-        const TParameter& param = function.getParam(i);
-        size += param.type->getObjectSize();
+	size_t size = 0;
+	bool full = false;
+	bool overFull = false;
+	bool matrixInMatrix = false;
+	bool arrayArg = false;
+	for (size_t i = 0; i < function.getParamCount(); ++i) {
+		const TParameter& param = function.getParam(i);
+		size += param.type->getObjectSize();
 
-        if (constructingMatrix && param.type->isMatrix())
-            matrixInMatrix = true;
-        if (full)
-            overFull = true;
-        if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
-            full = true;
-        if (param.type->isArray())
-            arrayArg = true;
-    }
+		if (constructingMatrix && param.type->isMatrix())
+			matrixInMatrix = true;
+		if (full)
+			overFull = true;
+		if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
+			full = true;
+		if (param.type->isArray())
+			arrayArg = true;
+	}
 
-    if(type->isArray()) {
-        if(type->getArraySize() == 0) {
-            type->setArraySize(function.getParamCount());
-        } else if(type->getArraySize() != (int)function.getParamCount()) {
-            error(line, "array constructor needs one argument per array element", "constructor");
-            return true;
-        }
-    }
+	if(type->isArray()) {
+		if(type->getArraySize() == 0) {
+			type->setArraySize(function.getParamCount());
+		} else if(type->getArraySize() != (int)function.getParamCount()) {
+			error(line, "array constructor needs one argument per array element", "constructor");
+			return true;
+		}
+	}
 
-    if (arrayArg && op != EOpConstructStruct) {
-        error(line, "constructing from a non-dereferenced array", "constructor");
-        return true;
-    }
+	if (arrayArg && op != EOpConstructStruct) {
+		error(line, "constructing from a non-dereferenced array", "constructor");
+		return true;
+	}
 
-    if (matrixInMatrix && !type->isArray()) {
-        if (function.getParamCount() != 1) {
-          error(line, "constructing matrix from matrix can only take one argument", "constructor");
-          return true;
-        }
-    }
+	if (matrixInMatrix && !type->isArray()) {
+		if (function.getParamCount() != 1) {
+		  error(line, "constructing matrix from matrix can only take one argument", "constructor");
+		  return true;
+		}
+	}
 
-    if (overFull) {
-        error(line, "too many arguments", "constructor");
-        return true;
-    }
+	if (overFull) {
+		error(line, "too many arguments", "constructor");
+		return true;
+	}
 
-    if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) {
-        error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
-        return true;
-    }
+	if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) {
+		error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
+		return true;
+	}
 
-    if (!type->isMatrix() || !matrixInMatrix) {
-        if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
-            (op == EOpConstructStruct && size < type->getObjectSize())) {
-            error(line, "not enough data provided for construction", "constructor");
-            return true;
-        }
-    }
+	if (!type->isMatrix() || !matrixInMatrix) {
+		if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
+			(op == EOpConstructStruct && size < type->getObjectSize())) {
+			error(line, "not enough data provided for construction", "constructor");
+			return true;
+		}
+	}
 
-    TIntermTyped *typed = node ? node->getAsTyped() : 0;
-    if (typed == 0) {
-        error(line, "constructor argument does not have a type", "constructor");
-        return true;
-    }
-    if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
-        error(line, "cannot convert a sampler", "constructor");
-        return true;
-    }
-    if (typed->getBasicType() == EbtVoid) {
-        error(line, "cannot convert a void", "constructor");
-        return true;
-    }
+	TIntermTyped *typed = node ? node->getAsTyped() : 0;
+	if (typed == 0) {
+		error(line, "constructor argument does not have a type", "constructor");
+		return true;
+	}
+	if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
+		error(line, "cannot convert a sampler", "constructor");
+		return true;
+	}
+	if (typed->getBasicType() == EbtVoid) {
+		error(line, "cannot convert a void", "constructor");
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 // This function checks to see if a void variable has been declared and raise an error message for such a case
@@ -562,12 +570,12 @@
 //
 bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString& identifier, const TBasicType& type)
 {
-    if(type == EbtVoid) {
-        error(line, "illegal use of type 'void'", identifier.c_str());
-        return true;
-    }
+	if(type == EbtVoid) {
+		error(line, "illegal use of type 'void'", identifier.c_str());
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
@@ -576,12 +584,12 @@
 //
 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped* type)
 {
-    if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
-        error(line, "boolean expression expected", "");
-        return true;
-    }
+	if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
+		error(line, "boolean expression expected", "");
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
@@ -590,31 +598,31 @@
 //
 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType& pType)
 {
-    if (pType.type != EbtBool || pType.array || (pType.primarySize > 1) || (pType.secondarySize > 1)) {
-        error(line, "boolean expression expected", "");
-        return true;
-    }
+	if (pType.type != EbtBool || pType.array || (pType.primarySize > 1) || (pType.secondarySize > 1)) {
+		error(line, "boolean expression expected", "");
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 bool TParseContext::samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason)
 {
-    if (pType.type == EbtStruct) {
-        if (containsSampler(*pType.userDef)) {
-            error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
+	if (pType.type == EbtStruct) {
+		if (containsSampler(*pType.userDef)) {
+			error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
 
-            return true;
-        }
+			return true;
+		}
 
-        return false;
-    } else if (IsSampler(pType.type)) {
-        error(line, reason, getBasicString(pType.type));
+		return false;
+	} else if (IsSampler(pType.type)) {
+		error(line, reason, getBasicString(pType.type));
 
-        return true;
-    }
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 bool TParseContext::structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType)
@@ -643,19 +651,19 @@
 		break;
 	}
 
-    if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
-        return true;
+	if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
+		return true;
 
 	// check for layout qualifier issues
 	const TLayoutQualifier layoutQualifier = pType.layoutQualifier;
 
 	if (pType.qualifier != EvqVertexIn && pType.qualifier != EvqFragmentOut &&
-	    layoutLocationErrorCheck(line, pType.layoutQualifier))
+		layoutLocationErrorCheck(line, pType.layoutQualifier))
 	{
 		return true;
 	}
 
-    return false;
+	return false;
 }
 
 // These checks are common for all declarations starting a declarator list, and declarators that follow an empty
@@ -736,29 +744,29 @@
 
 bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type)
 {
-    if ((qualifier == EvqOut || qualifier == EvqInOut) &&
-             type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
-        error(line, "samplers cannot be output parameters", type.getBasicString());
-        return true;
-    }
+	if ((qualifier == EvqOut || qualifier == EvqInOut) &&
+			 type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
+		error(line, "samplers cannot be output parameters", type.getBasicString());
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 bool TParseContext::containsSampler(TType& type)
 {
-    if (IsSampler(type.getBasicType()))
-        return true;
+	if (IsSampler(type.getBasicType()))
+		return true;
 
-    if (type.getBasicType() == EbtStruct) {
-        const TFieldList& fields = type.getStruct()->fields();
-        for(unsigned int i = 0; i < fields.size(); ++i) {
-            if (containsSampler(*fields[i]->type()))
-                return true;
-        }
-    }
+	if (type.getBasicType() == EbtStruct) {
+		const TFieldList& fields = type.getStruct()->fields();
+		for(unsigned int i = 0; i < fields.size(); ++i) {
+			if (containsSampler(*fields[i]->type()))
+				return true;
+		}
+	}
 
-    return false;
+	return false;
 }
 
 //
@@ -768,39 +776,39 @@
 //
 bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size)
 {
-    TIntermConstantUnion* constant = expr->getAsConstantUnion();
+	TIntermConstantUnion* constant = expr->getAsConstantUnion();
 
-    if (constant == 0 || !constant->isScalarInt())
-    {
-        error(line, "array size must be a constant integer expression", "");
-        return true;
-    }
+	if (constant == 0 || !constant->isScalarInt())
+	{
+		error(line, "array size must be a constant integer expression", "");
+		return true;
+	}
 
-    if (constant->getBasicType() == EbtUInt)
-    {
-        unsigned int uintSize = constant->getUConst(0);
-        if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
-        {
-            error(line, "array size too large", "");
-            size = 1;
-            return true;
-        }
+	if (constant->getBasicType() == EbtUInt)
+	{
+		unsigned int uintSize = constant->getUConst(0);
+		if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
+		{
+			error(line, "array size too large", "");
+			size = 1;
+			return true;
+		}
 
-        size = static_cast<int>(uintSize);
-    }
-    else
-    {
-        size = constant->getIConst(0);
+		size = static_cast<int>(uintSize);
+	}
+	else
+	{
+		size = constant->getIConst(0);
 
-        if (size <= 0)
-        {
-            error(line, "array size must be a positive integer", "");
-            size = 1;
-            return true;
-        }
-    }
+		if (size <= 0)
+		{
+			error(line, "array size must be a positive integer", "");
+			size = 1;
+			return true;
+		}
+	}
 
-    return false;
+	return false;
 }
 
 //
@@ -810,12 +818,12 @@
 //
 bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type)
 {
-    if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConstExpr)) {
-        error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
-        return true;
-    }
+	if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConstExpr)) {
+		error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 //
@@ -825,59 +833,59 @@
 //
 bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type)
 {
-    //
-    // Can the type be an array?
-    //
-    if (type.array) {
-        error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
-        return true;
-    }
+	//
+	// Can the type be an array?
+	//
+	if (type.array) {
+		error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, const TSourceLoc &line)
 {
-    bool builtIn = false;
-    TSymbol* symbol = symbolTable.find(node->getSymbol(), mShaderVersion, &builtIn);
-    if (symbol == 0) {
-        error(line, " undeclared identifier", node->getSymbol().c_str());
-        return true;
-    }
-    TVariable* variable = static_cast<TVariable*>(symbol);
+	bool builtIn = false;
+	TSymbol* symbol = symbolTable.find(node->getSymbol(), mShaderVersion, &builtIn);
+	if (symbol == 0) {
+		error(line, " undeclared identifier", node->getSymbol().c_str());
+		return true;
+	}
+	TVariable* variable = static_cast<TVariable*>(symbol);
 
-    type->setArrayInformationType(variable->getArrayInformationType());
-    variable->updateArrayInformationType(type);
+	type->setArrayInformationType(variable->getArrayInformationType());
+	variable->updateArrayInformationType(type);
 
-    // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
-    // its an error
-    if (node->getSymbol() == "gl_FragData") {
-        TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", mShaderVersion, &builtIn);
-        ASSERT(fragData);
+	// special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
+	// its an error
+	if (node->getSymbol() == "gl_FragData") {
+		TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", mShaderVersion, &builtIn);
+		ASSERT(fragData);
 
-        int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
-        if (fragDataValue <= size) {
-            error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
-            return true;
-        }
-    }
+		int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
+		if (fragDataValue <= size) {
+			error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
+			return true;
+		}
+	}
 
-    // we dont want to update the maxArraySize when this flag is not set, we just want to include this
-    // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
-    if (!updateFlag)
-        return false;
+	// we dont want to update the maxArraySize when this flag is not set, we just want to include this
+	// node type in the chain of node types so that its updated when a higher maxArraySize comes in.
+	if (!updateFlag)
+		return false;
 
-    size++;
-    variable->getType().setMaxArraySize(size);
-    type->setMaxArraySize(size);
-    TType* tt = type;
+	size++;
+	variable->getType().setMaxArraySize(size);
+	type->setMaxArraySize(size);
+	TType* tt = type;
 
-    while(tt->getArrayInformationType() != 0) {
-        tt = tt->getArrayInformationType();
-        tt->setMaxArraySize(size);
-    }
+	while(tt->getArrayInformationType() != 0) {
+		tt = tt->getArrayInformationType();
+		tt->setMaxArraySize(size);
+	}
 
-    return false;
+	return false;
 }
 
 //
@@ -887,28 +895,28 @@
 //
 bool TParseContext::nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array)
 {
-    if (type.qualifier == EvqConstExpr)
-    {
-        // Make the qualifier make sense.
-        type.qualifier = EvqTemporary;
+	if (type.qualifier == EvqConstExpr)
+	{
+		// Make the qualifier make sense.
+		type.qualifier = EvqTemporary;
 
-        if (array)
-        {
-            error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
-        }
-        else if (type.isStructureContainingArrays())
-        {
-            error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
-        }
-        else
-        {
-            error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
-        }
+		if (array)
+		{
+			error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
+		}
+		else if (type.isStructureContainingArrays())
+		{
+			error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
+		}
+		else
+		{
+			error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
+		}
 
-        return true;
-    }
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 //
@@ -989,42 +997,42 @@
 
 bool TParseContext::paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
 {
-    if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) {
-        error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
-        return true;
-    }
-    if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) {
-        error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
-        return true;
-    }
+	if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) {
+		error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
+		return true;
+	}
+	if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) {
+		error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
+		return true;
+	}
 
-    if (qualifier == EvqConstReadOnly)
-        type->setQualifier(EvqConstReadOnly);
-    else
-        type->setQualifier(paramQualifier);
+	if (qualifier == EvqConstReadOnly)
+		type->setQualifier(EvqConstReadOnly);
+	else
+		type->setQualifier(paramQualifier);
 
-    return false;
+	return false;
 }
 
 bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString& extension)
 {
-    const TExtensionBehavior& extBehavior = extensionBehavior();
-    TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
-    if (iter == extBehavior.end()) {
-        error(line, "extension", extension.c_str(), "is not supported");
-        return true;
-    }
-    // In GLSL ES, an extension's default behavior is "disable".
-    if (iter->second == EBhDisable || iter->second == EBhUndefined) {
-        error(line, "extension", extension.c_str(), "is disabled");
-        return true;
-    }
-    if (iter->second == EBhWarn) {
-        warning(line, "extension", extension.c_str(), "is being used");
-        return false;
-    }
+	const TExtensionBehavior& extBehavior = extensionBehavior();
+	TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
+	if (iter == extBehavior.end()) {
+		error(line, "extension", extension.c_str(), "is not supported");
+		return true;
+	}
+	// In GLSL ES, an extension's default behavior is "disable".
+	if (iter->second == EBhDisable || iter->second == EBhUndefined) {
+		error(line, "extension", extension.c_str(), "is disabled");
+		return true;
+	}
+	if (iter->second == EBhWarn) {
+		warning(line, "extension", extension.c_str(), "is being used");
+		return false;
+	}
 
-    return false;
+	return false;
 }
 
 bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
@@ -1067,21 +1075,21 @@
 
 bool TParseContext::supportsExtension(const char* extension)
 {
-    const TExtensionBehavior& extbehavior = extensionBehavior();
-    TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
-    return (iter != extbehavior.end());
+	const TExtensionBehavior& extbehavior = extensionBehavior();
+	TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
+	return (iter != extbehavior.end());
 }
 
 void TParseContext::handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior)
 {
-    pp::SourceLocation loc(line.first_file, line.first_line);
-    mDirectiveHandler.handleExtension(loc, extName, behavior);
+	pp::SourceLocation loc(line.first_file, line.first_line);
+	mDirectiveHandler.handleExtension(loc, extName, behavior);
 }
 
 void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value)
 {
-    pp::SourceLocation loc(line.first_file, line.first_line);
-    mDirectiveHandler.handlePragma(loc, name, value);
+	pp::SourceLocation loc(line.first_file, line.first_line);
+	mDirectiveHandler.handlePragma(loc, name, value);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -1094,7 +1102,7 @@
 	const TString *name,
 	const TSymbol *symbol)
 {
-	const TVariable *variable = NULL;
+	const TVariable *variable = nullptr;
 
 	if(!symbol)
 	{
@@ -1155,24 +1163,24 @@
 //
 const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction* call, bool *builtIn)
 {
-    // First find by unmangled name to check whether the function name has been
-    // hidden by a variable name or struct typename.
-    const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn);
-    if (symbol == 0) {
-        symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
-    }
+	// First find by unmangled name to check whether the function name has been
+	// hidden by a variable name or struct typename.
+	const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn);
+	if (symbol == 0) {
+		symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
+	}
 
-    if (symbol == 0) {
-        error(line, "no matching overloaded function found", call->getName().c_str());
-        return 0;
-    }
+	if (symbol == 0) {
+		error(line, "no matching overloaded function found", call->getName().c_str());
+		return 0;
+	}
 
-    if (!symbol->isFunction()) {
-        error(line, "function name expected", call->getName().c_str());
-        return 0;
-    }
+	if (!symbol->isFunction()) {
+		error(line, "function name expected", call->getName().c_str());
+		return 0;
+	}
 
-    return static_cast<const TFunction*>(symbol);
+	return static_cast<const TFunction*>(symbol);
 }
 
 //
@@ -1180,7 +1188,7 @@
 // code to handle them here.
 //
 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, const TPublicType& pType,
-                                       TIntermTyped *initializer, TIntermNode **intermNode)
+									   TIntermTyped *initializer, TIntermNode **intermNode)
 {
 	ASSERT(intermNode != nullptr);
 	TType type = TType(pType);
@@ -1208,59 +1216,59 @@
 	{
 		warning(line, "global variable initializers should be constant expressions "
 			"(uniforms and globals are allowed in global initializers for legacy compatibility)", "=");
-    }
+	}
 
-    //
-    // identifier must be of type constant, a global, or a temporary
-    //
-    TQualifier qualifier = type.getQualifier();
-    if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) {
-        error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
-        return true;
-    }
-    //
-    // test for and propagate constant
-    //
+	//
+	// identifier must be of type constant, a global, or a temporary
+	//
+	TQualifier qualifier = type.getQualifier();
+	if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) {
+		error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
+		return true;
+	}
+	//
+	// test for and propagate constant
+	//
 
-    if (qualifier == EvqConstExpr) {
-        if (qualifier != initializer->getQualifier()) {
-            std::stringstream extraInfoStream;
-            extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
-            std::string extraInfo = extraInfoStream.str();
-            error(line, " assigning non-constant to", "=", extraInfo.c_str());
-            variable->getType().setQualifier(EvqTemporary);
-            return true;
-        }
+	if (qualifier == EvqConstExpr) {
+		if (qualifier != initializer->getQualifier()) {
+			std::stringstream extraInfoStream;
+			extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
+			std::string extraInfo = extraInfoStream.str();
+			error(line, " assigning non-constant to", "=", extraInfo.c_str());
+			variable->getType().setQualifier(EvqTemporary);
+			return true;
+		}
 
-        if (type != initializer->getType()) {
-            error(line, " non-matching types for const initializer ",
-                variable->getType().getQualifierString());
-            variable->getType().setQualifier(EvqTemporary);
-            return true;
-        }
+		if (type != initializer->getType()) {
+			error(line, " non-matching types for const initializer ",
+				variable->getType().getQualifierString());
+			variable->getType().setQualifier(EvqTemporary);
+			return true;
+		}
 
-        if (initializer->getAsConstantUnion()) {
-            variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
-        } else if (initializer->getAsSymbolNode()) {
-            const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
-            const TVariable* tVar = static_cast<const TVariable*>(symbol);
+		if (initializer->getAsConstantUnion()) {
+			variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
+		} else if (initializer->getAsSymbolNode()) {
+			const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
+			const TVariable* tVar = static_cast<const TVariable*>(symbol);
 
-            ConstantUnion* constArray = tVar->getConstPointer();
-            variable->shareConstPointer(constArray);
-        }
-    }
+			ConstantUnion* constArray = tVar->getConstPointer();
+			variable->shareConstPointer(constArray);
+		}
+	}
 
-    if (!variable->isConstant()) {
-        TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
-        *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
-        if(*intermNode == nullptr) {
-            assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
-            return true;
-        }
-    } else
-        *intermNode = nullptr;
+	if (!variable->isConstant()) {
+		TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
+		*intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
+		if(*intermNode == nullptr) {
+			assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
+			return true;
+		}
+	} else
+		*intermNode = nullptr;
 
-    return false;
+	return false;
 }
 
 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier)
@@ -2062,61 +2070,61 @@
 //
 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc &line)
 {
-    TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
+	TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
 
-    if(!aggregateArguments)
-    {
-        aggregateArguments = new TIntermAggregate;
-        aggregateArguments->getSequence().push_back(arguments);
-    }
+	if(!aggregateArguments)
+	{
+		aggregateArguments = new TIntermAggregate;
+		aggregateArguments->getSequence().push_back(arguments);
+	}
 
-    if(op == EOpConstructStruct)
-    {
-        const TFieldList &fields = type->getStruct()->fields();
-        TIntermSequence &args = aggregateArguments->getSequence();
+	if(op == EOpConstructStruct)
+	{
+		const TFieldList &fields = type->getStruct()->fields();
+		TIntermSequence &args = aggregateArguments->getSequence();
 
-        for(size_t i = 0; i < fields.size(); i++)
-        {
-            if(args[i]->getAsTyped()->getType() != *fields[i]->type())
-            {
-                error(line, "Structure constructor arguments do not match structure fields", "Error");
-                recover();
+		for(size_t i = 0; i < fields.size(); i++)
+		{
+			if(args[i]->getAsTyped()->getType() != *fields[i]->type())
+			{
+				error(line, "Structure constructor arguments do not match structure fields", "Error");
+				recover();
 
-                return 0;
-            }
-        }
-    }
+				return 0;
+			}
+		}
+	}
 
-    // Turn the argument list itself into a constructor
-    TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
-    TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
-    if(constConstructor)
-    {
-        return constConstructor;
-    }
+	// Turn the argument list itself into a constructor
+	TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
+	TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
+	if(constConstructor)
+	{
+		return constConstructor;
+	}
 
-    return constructor;
+	return constructor;
 }
 
 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
 {
-    aggrNode->setType(type);
-    if (aggrNode->isConstantFoldable()) {
-        bool returnVal = false;
-        ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
-        if (aggrNode->getSequence().size() == 1)  {
-            returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
-        }
-        else {
-            returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
-        }
-        if (returnVal)
-            return 0;
+	aggrNode->setType(type);
+	if (aggrNode->isConstantFoldable()) {
+		bool returnVal = false;
+		ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
+		if (aggrNode->getSequence().size() == 1)  {
+			returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
+		}
+		else {
+			returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
+		}
+		if (returnVal)
+			return 0;
 
-        return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
-    }
+		return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
+	}
 
-    return 0;
+	return 0;
 }
 
 //
@@ -2128,40 +2136,40 @@
 //
 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc &line)
 {
-    TIntermTyped* typedNode;
-    TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
+	TIntermTyped* typedNode;
+	TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
 
-    ConstantUnion *unionArray;
-    if (tempConstantNode) {
-        unionArray = tempConstantNode->getUnionArrayPointer();
+	ConstantUnion *unionArray;
+	if (tempConstantNode) {
+		unionArray = tempConstantNode->getUnionArrayPointer();
 
-        if (!unionArray) {
-            return node;
-        }
-    } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
-        error(line, "Cannot offset into the vector", "Error");
-        recover();
+		if (!unionArray) {
+			return node;
+		}
+	} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
+		error(line, "Cannot offset into the vector", "Error");
+		recover();
 
-        return 0;
-    }
+		return 0;
+	}
 
-    ConstantUnion* constArray = new ConstantUnion[fields.num];
+	ConstantUnion* constArray = new ConstantUnion[fields.num];
 
-    for (int i = 0; i < fields.num; i++) {
-        if (fields.offsets[i] >= node->getType().getObjectSize()) {
-            std::stringstream extraInfoStream;
-            extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
-            std::string extraInfo = extraInfoStream.str();
-            error(line, "", "[", extraInfo.c_str());
-            recover();
-            fields.offsets[i] = 0;
-        }
+	for (int i = 0; i < fields.num; i++) {
+		if (fields.offsets[i] >= node->getType().getObjectSize()) {
+			std::stringstream extraInfoStream;
+			extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
+			std::string extraInfo = extraInfoStream.str();
+			error(line, "", "[", extraInfo.c_str());
+			recover();
+			fields.offsets[i] = 0;
+		}
 
-        constArray[i] = unionArray[fields.offsets[i]];
+		constArray[i] = unionArray[fields.offsets[i]];
 
-    }
-    typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
-    return typedNode;
+	}
+	typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
+	return typedNode;
 }
 
 //
@@ -2172,30 +2180,30 @@
 //
 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc &line)
 {
-    TIntermTyped* typedNode;
-    TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
+	TIntermTyped* typedNode;
+	TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
 
-    if (index >= node->getType().getNominalSize()) {
-        std::stringstream extraInfoStream;
-        extraInfoStream << "matrix field selection out of range '" << index << "'";
-        std::string extraInfo = extraInfoStream.str();
-        error(line, "", "[", extraInfo.c_str());
-        recover();
-        index = 0;
-    }
+	if (index >= node->getType().getNominalSize()) {
+		std::stringstream extraInfoStream;
+		extraInfoStream << "matrix field selection out of range '" << index << "'";
+		std::string extraInfo = extraInfoStream.str();
+		error(line, "", "[", extraInfo.c_str());
+		recover();
+		index = 0;
+	}
 
-    if (tempConstantNode) {
-         ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
-         int size = tempConstantNode->getType().getNominalSize();
-         typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
-    } else {
-        error(line, "Cannot offset into the matrix", "Error");
-        recover();
+	if (tempConstantNode) {
+		 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
+		 int size = tempConstantNode->getType().getNominalSize();
+		 typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
+	} else {
+		error(line, "Cannot offset into the matrix", "Error");
+		recover();
 
-        return 0;
-    }
+		return 0;
+	}
 
-    return typedNode;
+	return typedNode;
 }
 
 
@@ -2207,33 +2215,33 @@
 //
 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line)
 {
-    TIntermTyped* typedNode;
-    TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
-    TType arrayElementType = node->getType();
-    arrayElementType.clearArrayness();
+	TIntermTyped* typedNode;
+	TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
+	TType arrayElementType = node->getType();
+	arrayElementType.clearArrayness();
 
-    if (index >= node->getType().getArraySize()) {
-        std::stringstream extraInfoStream;
-        extraInfoStream << "array field selection out of range '" << index << "'";
-        std::string extraInfo = extraInfoStream.str();
-        error(line, "", "[", extraInfo.c_str());
-        recover();
-        index = 0;
-    }
+	if (index >= node->getType().getArraySize()) {
+		std::stringstream extraInfoStream;
+		extraInfoStream << "array field selection out of range '" << index << "'";
+		std::string extraInfo = extraInfoStream.str();
+		error(line, "", "[", extraInfo.c_str());
+		recover();
+		index = 0;
+	}
 
-    size_t arrayElementSize = arrayElementType.getObjectSize();
+	size_t arrayElementSize = arrayElementType.getObjectSize();
 
-    if (tempConstantNode) {
-         ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
-         typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
-    } else {
-        error(line, "Cannot offset into the array", "Error");
-        recover();
+	if (tempConstantNode) {
+		 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
+		 typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
+	} else {
+		error(line, "Cannot offset into the array", "Error");
+		recover();
 
-        return 0;
-    }
+		return 0;
+	}
 
-    return typedNode;
+	return typedNode;
 }
 
 
@@ -2244,38 +2252,38 @@
 //
 TIntermTyped* TParseContext::addConstStruct(const TString& identifier, TIntermTyped* node, const TSourceLoc &line)
 {
-    const TFieldList &fields = node->getType().getStruct()->fields();
-    TIntermTyped *typedNode;
-    size_t instanceSize = 0;
-    TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
+	const TFieldList &fields = node->getType().getStruct()->fields();
+	TIntermTyped *typedNode;
+	size_t instanceSize = 0;
+	TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
 
-    for(size_t index = 0; index < fields.size(); ++index) {
-        if (fields[index]->name() == identifier) {
-            break;
-        } else {
-            instanceSize += fields[index]->type()->getObjectSize();
-        }
-    }
+	for(size_t index = 0; index < fields.size(); ++index) {
+		if (fields[index]->name() == identifier) {
+			break;
+		} else {
+			instanceSize += fields[index]->type()->getObjectSize();
+		}
+	}
 
-    if (tempConstantNode) {
-         ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
+	if (tempConstantNode) {
+		 ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
 
-         typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
-    } else {
-        error(line, "Cannot offset into the structure", "Error");
-        recover();
+		 typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
+	} else {
+		error(line, "Cannot offset into the structure", "Error");
+		recover();
 
-        return 0;
-    }
+		return 0;
+	}
 
-    return typedNode;
+	return typedNode;
 }
 
 //
 // Interface/uniform blocks
 //
 TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
-                                                   const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
+												   const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
 {
 	if(reservedErrorCheck(nameLine, blockName))
 		recover();
@@ -2357,7 +2365,7 @@
 
 	// add array index
 	int arraySize = 0;
-	if(arrayIndex != NULL)
+	if(arrayIndex)
 	{
 		if(arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
 			recover();
@@ -2416,7 +2424,7 @@
 //
 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression)
 {
-	TIntermTyped *indexedExpression = NULL;
+	TIntermTyped *indexedExpression = nullptr;
 
 	if(!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
 	{
@@ -2576,7 +2584,7 @@
 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation,
 	const TString &fieldString, const TSourceLoc &fieldLocation)
 {
-	TIntermTyped *indexedExpression = NULL;
+	TIntermTyped *indexedExpression = nullptr;
 
 	if(baseExpression->isArray())
 	{
@@ -2769,9 +2777,9 @@
 
 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
 {
-    TLayoutQualifier qualifier;
+	TLayoutQualifier qualifier;
 
-    qualifier.location = -1;
+	qualifier.location = -1;
 	qualifier.matrixPacking = EmpUnspecified;
 	qualifier.blockStorage = EbsUnspecified;
 
@@ -2796,57 +2804,57 @@
 		qualifier.matrixPacking = EmpColumnMajor;
 	}
 	else if(qualifierType == "location")
-    {
-        error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
-        recover();
-    }
-    else
-    {
-        error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
-        recover();
-    }
+	{
+		error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
+		recover();
+	}
+	else
+	{
+		error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
+		recover();
+	}
 
-    return qualifier;
+	return qualifier;
 }
 
 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
 {
-    TLayoutQualifier qualifier;
+	TLayoutQualifier qualifier;
 
-    qualifier.location = -1;
-    qualifier.matrixPacking = EmpUnspecified;
-    qualifier.blockStorage = EbsUnspecified;
+	qualifier.location = -1;
+	qualifier.matrixPacking = EmpUnspecified;
+	qualifier.blockStorage = EbsUnspecified;
 
-    if (qualifierType != "location")
-    {
-        error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
-        recover();
-    }
-    else
-    {
-        // must check that location is non-negative
-        if (intValue < 0)
-        {
-            error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
-            recover();
-        }
-        else
-        {
-            qualifier.location = intValue;
-        }
-    }
+	if (qualifierType != "location")
+	{
+		error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
+		recover();
+	}
+	else
+	{
+		// must check that location is non-negative
+		if (intValue < 0)
+		{
+			error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
+			recover();
+		}
+		else
+		{
+			qualifier.location = intValue;
+		}
+	}
 
-    return qualifier;
+	return qualifier;
 }
 
 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
 {
-    TLayoutQualifier joinedQualifier = leftQualifier;
+	TLayoutQualifier joinedQualifier = leftQualifier;
 
-    if (rightQualifier.location != -1)
-    {
-        joinedQualifier.location = rightQualifier.location;
-    }
+	if (rightQualifier.location != -1)
+	{
+		joinedQualifier.location = rightQualifier.location;
+	}
 	if(rightQualifier.matrixPacking != EmpUnspecified)
 	{
 		joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
@@ -2856,7 +2864,7 @@
 		joinedQualifier.blockStorage = rightQualifier.blockStorage;
 	}
 
-    return joinedQualifier;
+	return joinedQualifier;
 }
 
 
@@ -2999,22 +3007,22 @@
 
 bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString& identifier)
 {
-    ++mStructNestingLevel;
+	++mStructNestingLevel;
 
-    // Embedded structure definitions are not supported per GLSL ES spec.
-    // They aren't allowed in GLSL either, but we need to detect this here
-    // so we don't rely on the GLSL compiler to catch it.
-    if (mStructNestingLevel > 1) {
-        error(line, "", "Embedded struct definitions are not allowed");
-        return true;
-    }
+	// Embedded structure definitions are not supported per GLSL ES spec.
+	// They aren't allowed in GLSL either, but we need to detect this here
+	// so we don't rely on the GLSL compiler to catch it.
+	if (mStructNestingLevel > 1) {
+		error(line, "", "Embedded struct definitions are not allowed");
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 void TParseContext::exitStructDeclaration()
 {
-    --mStructNestingLevel;
+	--mStructNestingLevel;
 }
 
 bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field)
@@ -3663,20 +3671,20 @@
 // Returns 0 for success.
 //
 int PaParseStrings(int count, const char* const string[], const int length[],
-                   TParseContext* context) {
-    if ((count == 0) || (string == NULL))
-        return 1;
+				   TParseContext* context) {
+	if ((count == 0) || !string)
+		return 1;
 
-    if (glslang_initialize(context))
-        return 1;
+	if (glslang_initialize(context))
+		return 1;
 
-    int error = glslang_scan(count, string, length, context);
-    if (!error)
-        error = glslang_parse(context);
+	int error = glslang_scan(count, string, length, context);
+	if (!error)
+		error = glslang_parse(context);
 
-    glslang_finalize(context);
+	glslang_finalize(context);
 
-    return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
+	return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
 }
 
 
diff --git a/src/OpenGL/compiler/ParseHelper.h b/src/OpenGL/compiler/ParseHelper.h
index d6b08b3..8733ef5 100644
--- a/src/OpenGL/compiler/ParseHelper.h
+++ b/src/OpenGL/compiler/ParseHelper.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 #ifndef _PARSER_HELPER_INCLUDED_
 #define _PARSER_HELPER_INCLUDED_
 
@@ -14,10 +22,10 @@
 #include "SymbolTable.h"
 
 struct TMatrixFields {
-    bool wholeRow;
-    bool wholeCol;
-    int row;
-    int col;
+	bool wholeRow;
+	bool wholeCol;
+	int row;
+	int col;
 };
 
 //
@@ -26,129 +34,129 @@
 //
 class TParseContext {
 public:
-    TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, GLenum type, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
-            intermediate(interm),
-            symbolTable(symt),
-            compileOptions(options),
-            sourcePath(sourcePath),
-            lexAfterType(false),
-            inTypeParen(false),
-            AfterEOF(false),
-            mDeferredSingleDeclarationErrorCheck(false),
-            mShaderType(type),
-            mShaderVersion(100),
-            mTreeRoot(0),
-            mLoopNestingLevel(0),
-            mSwitchNestingLevel(0),
-            mStructNestingLevel(0),
-            mCurrentFunctionType(NULL),
-            mFunctionReturnsValue(false),
-            mChecksPrecisionErrors(checksPrecErrors),
-            mDefaultMatrixPacking(EmpColumnMajor),
-            mDefaultBlockStorage(EbsShared),
-            mDiagnostics(is),
-            mDirectiveHandler(ext, mDiagnostics, mShaderVersion),
-            mPreprocessor(&mDiagnostics, &mDirectiveHandler),
-            mScanner(NULL),
-            mUsesFragData(false),
-            mUsesFragColor(false) {  }
-    TIntermediate& intermediate; // to hold and build a parse tree
-    TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
-    int compileOptions;
-    const char* sourcePath;      // Path of source file or NULL.
-    bool lexAfterType;           // true if we've recognized a type, so can only be looking for an identifier
-    bool inTypeParen;            // true if in parentheses, looking only for an identifier
-    bool AfterEOF;
+	TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, GLenum type, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
+			intermediate(interm),
+			symbolTable(symt),
+			compileOptions(options),
+			sourcePath(sourcePath),
+			lexAfterType(false),
+			inTypeParen(false),
+			AfterEOF(false),
+			mDeferredSingleDeclarationErrorCheck(false),
+			mShaderType(type),
+			mShaderVersion(100),
+			mTreeRoot(0),
+			mLoopNestingLevel(0),
+			mSwitchNestingLevel(0),
+			mStructNestingLevel(0),
+			mCurrentFunctionType(nullptr),
+			mFunctionReturnsValue(false),
+			mChecksPrecisionErrors(checksPrecErrors),
+			mDefaultMatrixPacking(EmpColumnMajor),
+			mDefaultBlockStorage(EbsShared),
+			mDiagnostics(is),
+			mDirectiveHandler(ext, mDiagnostics, mShaderVersion),
+			mPreprocessor(&mDiagnostics, &mDirectiveHandler),
+			mScanner(nullptr),
+			mUsesFragData(false),
+			mUsesFragColor(false) {  }
+	TIntermediate& intermediate; // to hold and build a parse tree
+	TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
+	int compileOptions;
+	const char* sourcePath;      // Path of source file or null.
+	bool lexAfterType;           // true if we've recognized a type, so can only be looking for an identifier
+	bool inTypeParen;            // true if in parentheses, looking only for an identifier
+	bool AfterEOF;
 
-    const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
-    pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
-    void *getScanner() const { return mScanner; }
-    void setScanner(void *scanner) { mScanner = scanner; }
-    int getShaderVersion() const { return mShaderVersion; }
-    GLenum getShaderType() const { return mShaderType; }
-    int numErrors() const { return mDiagnostics.numErrors(); }
-    TInfoSink &infoSink() { return mDiagnostics.infoSink(); }
-    void error(const TSourceLoc &loc, const char *reason, const char* token,
-               const char* extraInfo="");
-    void warning(const TSourceLoc &loc, const char* reason, const char* token,
-                 const char* extraInfo="");
-    void trace(const char* str);
-    void recover();
-    TIntermNode *getTreeRoot() const { return mTreeRoot; }
-    void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
+	const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
+	pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
+	void *getScanner() const { return mScanner; }
+	void setScanner(void *scanner) { mScanner = scanner; }
+	int getShaderVersion() const { return mShaderVersion; }
+	GLenum getShaderType() const { return mShaderType; }
+	int numErrors() const { return mDiagnostics.numErrors(); }
+	TInfoSink &infoSink() { return mDiagnostics.infoSink(); }
+	void error(const TSourceLoc &loc, const char *reason, const char* token,
+	           const char* extraInfo="");
+	void warning(const TSourceLoc &loc, const char* reason, const char* token,
+	             const char* extraInfo="");
+	void trace(const char* str);
+	void recover();
+	TIntermNode *getTreeRoot() const { return mTreeRoot; }
+	void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
 
-    bool getFunctionReturnsValue() const { return mFunctionReturnsValue; }
-    void setFunctionReturnsValue(bool functionReturnsValue)
-    {
-        mFunctionReturnsValue = functionReturnsValue;
-    }
+	bool getFunctionReturnsValue() const { return mFunctionReturnsValue; }
+	void setFunctionReturnsValue(bool functionReturnsValue)
+	{
+		mFunctionReturnsValue = functionReturnsValue;
+	}
 
-    void setLoopNestingLevel(int loopNestintLevel)
-    {
-        mLoopNestingLevel = loopNestintLevel;
-    }
+	void setLoopNestingLevel(int loopNestintLevel)
+	{
+		mLoopNestingLevel = loopNestintLevel;
+	}
 
-    const TType *getCurrentFunctionType() const { return mCurrentFunctionType; }
-    void setCurrentFunctionType(const TType *currentFunctionType)
-    {
-        mCurrentFunctionType = currentFunctionType;
-    }
+	const TType *getCurrentFunctionType() const { return mCurrentFunctionType; }
+	void setCurrentFunctionType(const TType *currentFunctionType)
+	{
+		mCurrentFunctionType = currentFunctionType;
+	}
 
-    void incrLoopNestingLevel() { ++mLoopNestingLevel; }
-    void decrLoopNestingLevel() { --mLoopNestingLevel; }
+	void incrLoopNestingLevel() { ++mLoopNestingLevel; }
+	void decrLoopNestingLevel() { --mLoopNestingLevel; }
 
-    void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
-    void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
+	void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
+	void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
 
 	// This method is guaranteed to succeed, even if no variable with 'name' exists.
 	const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
 
-    bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
-    bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc &line);
+	bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
+	bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc &line);
 
-    bool reservedErrorCheck(const TSourceLoc &line, const TString& identifier);
-    void assignError(const TSourceLoc &line, const char* op, TString left, TString right);
-    void unaryOpError(const TSourceLoc &line, const char* op, TString operand);
-    void binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right);
-    bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
-    bool lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped*);
-    bool constErrorCheck(TIntermTyped* node);
-    bool integerErrorCheck(TIntermTyped* node, const char* token);
-    bool globalErrorCheck(const TSourceLoc &line, bool global, const char* token);
-    bool constructorErrorCheck(const TSourceLoc &line, TIntermNode*, TFunction&, TOperator, TType*);
-    bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size);
-    bool arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type);
-    bool arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type);
-    bool voidErrorCheck(const TSourceLoc&, const TString&, const TBasicType&);
-    bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
-    bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
-    bool samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason);
+	bool reservedErrorCheck(const TSourceLoc &line, const TString& identifier);
+	void assignError(const TSourceLoc &line, const char* op, TString left, TString right);
+	void unaryOpError(const TSourceLoc &line, const char* op, TString operand);
+	void binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right);
+	bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
+	bool lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped*);
+	bool constErrorCheck(TIntermTyped* node);
+	bool integerErrorCheck(TIntermTyped* node, const char* token);
+	bool globalErrorCheck(const TSourceLoc &line, bool global, const char* token);
+	bool constructorErrorCheck(const TSourceLoc &line, TIntermNode*, TFunction&, TOperator, TType*);
+	bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size);
+	bool arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type);
+	bool arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type);
+	bool voidErrorCheck(const TSourceLoc&, const TString&, const TBasicType&);
+	bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
+	bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
+	bool samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason);
 	bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
-    bool structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType);
-    bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type);
-    bool nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array);
-    bool nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type);
-    bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
-    bool extensionErrorCheck(const TSourceLoc &line, const TString&);
+	bool structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType);
+	bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type);
+	bool nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array);
+	bool nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type);
+	bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
+	bool extensionErrorCheck(const TSourceLoc &line, const TString&);
 	bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
-    bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
-    bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
+	bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
+	bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
 	void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
 
-    const TExtensionBehavior& extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
-    bool supportsExtension(const char* extension);
-    void handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior);
+	const TExtensionBehavior& extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
+	bool supportsExtension(const char* extension);
+	void handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior);
 
-    const TPragma& pragma() const { return mDirectiveHandler.pragma(); }
-    void handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value);
+	const TPragma& pragma() const { return mDirectiveHandler.pragma(); }
+	void handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value);
 
-    bool containsSampler(TType& type);
-    const TFunction* findFunction(const TSourceLoc &line, TFunction* pfnCall, bool *builtIn = 0);
-    bool executeInitializer(const TSourceLoc &line, const TString &identifier, const TPublicType &pType,
-                            TIntermTyped *initializer, TIntermNode **intermNode);
+	bool containsSampler(TType& type);
+	const TFunction* findFunction(const TSourceLoc &line, TFunction* pfnCall, bool *builtIn = 0);
+	bool executeInitializer(const TSourceLoc &line, const TString &identifier, const TPublicType &pType,
+	                        TIntermTyped *initializer, TIntermNode **intermNode);
 
-    TPublicType addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier);
-    bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, const TSourceLoc&);
+	TPublicType addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier);
+	bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, const TSourceLoc&);
 
 	TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, const TSourceLoc &identifierOrTypeLocation, const TString &identifier);
 	TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
@@ -177,37 +185,37 @@
 	                                           const TString &identifier, const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
                                                const TSourceLoc &initLocation, TIntermTyped *initializer);
 
-    void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
+	void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
 	TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function, const TSourceLoc &location);
 	TIntermAggregate *addFunctionDefinition(const TFunction &function, TIntermAggregate *functionPrototype, TIntermAggregate *functionBody, const TSourceLoc &location);
 	void parseFunctionPrototype(const TSourceLoc &location, TFunction *function, TIntermAggregate **aggregateOut);
 	TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
 	TFunction *addConstructorFunc(const TPublicType &publicType);
-    TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
-    TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
-    TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
-    TIntermTyped* addConstMatrixNode(int, TIntermTyped*, const TSourceLoc&);
-    TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line);
-    TIntermTyped* addConstStruct(const TString&, TIntermTyped*, const TSourceLoc&);
-    TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
-    TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, const TString &fieldString, const TSourceLoc &fieldLocation);
+	TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
+	TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
+	TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
+	TIntermTyped* addConstMatrixNode(int, TIntermTyped*, const TSourceLoc&);
+	TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line);
+	TIntermTyped* addConstStruct(const TString&, TIntermTyped*, const TSourceLoc&);
+	TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
+	TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, const TString &fieldString, const TSourceLoc &fieldLocation);
 
-    TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
-    TPublicType addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, const TString *structName, TFieldList *fieldList);
+	TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
+	TPublicType addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, const TString *structName, TFieldList *fieldList);
 
-    TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
-                                        const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine);
+	TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
+	                                    const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine);
 
-    TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
-    TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
-    TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
-    TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
+	TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
+	TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
+	TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
+	TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
 
-    // Performs an error check for embedded struct declarations.
-    // Returns true if an error was raised due to the declaration of
-    // this struct.
-    bool enterStructDeclaration(const TSourceLoc &line, const TString& identifier);
-    void exitStructDeclaration();
+	// Performs an error check for embedded struct declarations.
+	// Returns true if an error was raised due to the declaration of
+	// this struct.
+	bool enterStructDeclaration(const TSourceLoc &line, const TString& identifier);
+	void exitStructDeclaration();
 
 	bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
 
diff --git a/src/OpenGL/compiler/PoolAlloc.cpp b/src/OpenGL/compiler/PoolAlloc.cpp
index a8347c2..f3d19eb 100644
--- a/src/OpenGL/compiler/PoolAlloc.cpp
+++ b/src/OpenGL/compiler/PoolAlloc.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "PoolAlloc.h"
 
@@ -18,98 +26,98 @@
 
 bool InitializePoolIndex()
 {
-    assert(PoolIndex == OS_INVALID_TLS_INDEX);
+	assert(PoolIndex == OS_INVALID_TLS_INDEX);
 
-    PoolIndex = OS_AllocTLSIndex();
-    return PoolIndex != OS_INVALID_TLS_INDEX;
+	PoolIndex = OS_AllocTLSIndex();
+	return PoolIndex != OS_INVALID_TLS_INDEX;
 }
 
 void FreePoolIndex()
 {
-    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+	assert(PoolIndex != OS_INVALID_TLS_INDEX);
 
-    OS_FreeTLSIndex(PoolIndex);
-    PoolIndex = OS_INVALID_TLS_INDEX;
+	OS_FreeTLSIndex(PoolIndex);
+	PoolIndex = OS_INVALID_TLS_INDEX;
 }
 
 TPoolAllocator* GetGlobalPoolAllocator()
 {
-    assert(PoolIndex != OS_INVALID_TLS_INDEX);
-    return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
+	assert(PoolIndex != OS_INVALID_TLS_INDEX);
+	return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
 }
 
 void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
 {
-    assert(PoolIndex != OS_INVALID_TLS_INDEX);
-    OS_SetTLSValue(PoolIndex, poolAllocator);
+	assert(PoolIndex != OS_INVALID_TLS_INDEX);
+	OS_SetTLSValue(PoolIndex, poolAllocator);
 }
 
 //
 // Implement the functionality of the TPoolAllocator class, which
 // is documented in PoolAlloc.h.
 //
-TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : 
-    pageSize(growthIncrement),
-    alignment(allocationAlignment),
-    freeList(0),
-    inUseList(0),
-    numCalls(0),
-    totalBytes(0)
+TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
+	pageSize(growthIncrement),
+	alignment(allocationAlignment),
+	freeList(0),
+	inUseList(0),
+	numCalls(0),
+	totalBytes(0)
 {
-    //
-    // Don't allow page sizes we know are smaller than all common
-    // OS page sizes.
-    //
-    if (pageSize < 4*1024)
-        pageSize = 4*1024;
+	//
+	// Don't allow page sizes we know are smaller than all common
+	// OS page sizes.
+	//
+	if (pageSize < 4*1024)
+		pageSize = 4*1024;
 
-    //
-    // A large currentPageOffset indicates a new page needs to
-    // be obtained to allocate memory.
-    //
-    currentPageOffset = pageSize;
+	//
+	// A large currentPageOffset indicates a new page needs to
+	// be obtained to allocate memory.
+	//
+	currentPageOffset = pageSize;
 
-    //
-    // Adjust alignment to be at least pointer aligned and
-    // power of 2.
-    //
-    size_t minAlign = sizeof(void*);
-    alignment &= ~(minAlign - 1);
-    if (alignment < minAlign)
-        alignment = minAlign;
-    size_t a = 1;
-    while (a < alignment)
-        a <<= 1;
-    alignment = a;
-    alignmentMask = a - 1;
+	//
+	// Adjust alignment to be at least pointer aligned and
+	// power of 2.
+	//
+	size_t minAlign = sizeof(void*);
+	alignment &= ~(minAlign - 1);
+	if (alignment < minAlign)
+		alignment = minAlign;
+	size_t a = 1;
+	while (a < alignment)
+		a <<= 1;
+	alignment = a;
+	alignmentMask = a - 1;
 
-    //
-    // Align header skip
-    //
-    headerSkip = minAlign;
-    if (headerSkip < sizeof(tHeader)) {
-        headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
-    }
+	//
+	// Align header skip
+	//
+	headerSkip = minAlign;
+	if (headerSkip < sizeof(tHeader)) {
+		headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
+	}
 }
 
 TPoolAllocator::~TPoolAllocator()
 {
-    while (inUseList) {
-        tHeader* next = inUseList->nextPage;
-        inUseList->~tHeader();
-        delete [] reinterpret_cast<char*>(inUseList);
-        inUseList = next;
-    }
+	while (inUseList) {
+		tHeader* next = inUseList->nextPage;
+		inUseList->~tHeader();
+		delete [] reinterpret_cast<char*>(inUseList);
+		inUseList = next;
+	}
 
-    // We should not check the guard blocks
-    // here, because we did it already when the block was
-    // placed into the free list.
-    //
-    while (freeList) {
-        tHeader* next = freeList->nextPage;
-        delete [] reinterpret_cast<char*>(freeList);
-        freeList = next;
-    }
+	// We should not check the guard blocks
+	// here, because we did it already when the block was
+	// placed into the free list.
+	//
+	while (freeList) {
+		tHeader* next = freeList->nextPage;
+		delete [] reinterpret_cast<char*>(freeList);
+		freeList = next;
+	}
 }
 
 // Support MSVC++ 6.0
@@ -118,9 +126,9 @@
 const unsigned char TAllocation::userDataFill       = 0xcd;
 
 #ifdef GUARD_BLOCKS
-    const size_t TAllocation::guardBlockSize = 16;
+	const size_t TAllocation::guardBlockSize = 16;
 #else
-    const size_t TAllocation::guardBlockSize = 0;
+	const size_t TAllocation::guardBlockSize = 0;
 #endif
 
 //
@@ -129,35 +137,35 @@
 void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const
 {
 #ifdef GUARD_BLOCKS
-    for (size_t x = 0; x < guardBlockSize; x++) {
-        if (blockMem[x] != val) {
-            char assertMsg[80];
+	for (size_t x = 0; x < guardBlockSize; x++) {
+		if (blockMem[x] != val) {
+			char assertMsg[80];
 
-            // We don't print the assert message.  It's here just to be helpful.
-            #if defined(_MSC_VER)
-                _snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n",
-                          locText, size, data());
-            #else
-                snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n",
-                         locText, size, data());
-            #endif
-            assert(0 && "PoolAlloc: Damage in guard block");
-        }
-    }
+			// We don't print the assert message.  It's here just to be helpful.
+			#if defined(_MSC_VER)
+				_snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n",
+						  locText, size, data());
+			#else
+				snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n",
+						 locText, size, data());
+			#endif
+			assert(0 && "PoolAlloc: Damage in guard block");
+		}
+	}
 #endif
 }
 
 
 void TPoolAllocator::push()
 {
-    tAllocState state = { currentPageOffset, inUseList };
+	tAllocState state = { currentPageOffset, inUseList };
 
-    stack.push_back(state);
-        
-    //
-    // Indicate there is no current page to allocate from.
-    //
-    currentPageOffset = pageSize;
+	stack.push_back(state);
+
+	//
+	// Indicate there is no current page to allocate from.
+	//
+	currentPageOffset = pageSize;
 }
 
 //
@@ -169,27 +177,27 @@
 //
 void TPoolAllocator::pop()
 {
-    if (stack.size() < 1)
-        return;
+	if (stack.size() < 1)
+		return;
 
-    tHeader* page = stack.back().page;
-    currentPageOffset = stack.back().offset;
+	tHeader* page = stack.back().page;
+	currentPageOffset = stack.back().offset;
 
-    while (inUseList != page) {
-        // invoke destructor to free allocation list
-        inUseList->~tHeader();
-        
-        tHeader* nextInUse = inUseList->nextPage;
-        if (inUseList->pageCount > 1)
-            delete [] reinterpret_cast<char*>(inUseList);
-        else {
-            inUseList->nextPage = freeList;
-            freeList = inUseList;
-        }
-        inUseList = nextInUse;
-    }
+	while (inUseList != page) {
+		// invoke destructor to free allocation list
+		inUseList->~tHeader();
 
-    stack.pop_back();
+		tHeader* nextInUse = inUseList->nextPage;
+		if (inUseList->pageCount > 1)
+			delete [] reinterpret_cast<char*>(inUseList);
+		else {
+			inUseList->nextPage = freeList;
+			freeList = inUseList;
+		}
+		inUseList = nextInUse;
+	}
+
+	stack.pop_back();
 }
 
 //
@@ -198,88 +206,88 @@
 //
 void TPoolAllocator::popAll()
 {
-    while (stack.size() > 0)
-        pop();
+	while (stack.size() > 0)
+		pop();
 }
 
 void* TPoolAllocator::allocate(size_t numBytes)
 {
-    //
-    // Just keep some interesting statistics.
-    //
-    ++numCalls;
-    totalBytes += numBytes;
+	//
+	// Just keep some interesting statistics.
+	//
+	++numCalls;
+	totalBytes += numBytes;
 
-    // If we are using guard blocks, all allocations are bracketed by
-    // them: [guardblock][allocation][guardblock].  numBytes is how
-    // much memory the caller asked for.  allocationSize is the total
-    // size including guard blocks.  In release build,
-    // guardBlockSize=0 and this all gets optimized away.
-    size_t allocationSize = TAllocation::allocationSize(numBytes);
-    // Detect integer overflow.
-    if (allocationSize < numBytes)
-        return 0;
+	// If we are using guard blocks, all allocations are bracketed by
+	// them: [guardblock][allocation][guardblock].  numBytes is how
+	// much memory the caller asked for.  allocationSize is the total
+	// size including guard blocks.  In release build,
+	// guardBlockSize=0 and this all gets optimized away.
+	size_t allocationSize = TAllocation::allocationSize(numBytes);
+	// Detect integer overflow.
+	if (allocationSize < numBytes)
+		return 0;
 
-    //
-    // Do the allocation, most likely case first, for efficiency.
-    // This step could be moved to be inline sometime.
-    //
-    if (allocationSize <= pageSize - currentPageOffset) {
-        //
-        // Safe to allocate from currentPageOffset.
-        //
-        unsigned char* memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset;
-        currentPageOffset += allocationSize;
-        currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask;
+	//
+	// Do the allocation, most likely case first, for efficiency.
+	// This step could be moved to be inline sometime.
+	//
+	if (allocationSize <= pageSize - currentPageOffset) {
+		//
+		// Safe to allocate from currentPageOffset.
+		//
+		unsigned char* memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset;
+		currentPageOffset += allocationSize;
+		currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask;
 
-        return initializeAllocation(inUseList, memory, numBytes);
-    }
+		return initializeAllocation(inUseList, memory, numBytes);
+	}
 
-    if (allocationSize > pageSize - headerSkip) {
-        //
-        // Do a multi-page allocation.  Don't mix these with the others.
-        // The OS is efficient and allocating and free-ing multiple pages.
-        //
-        size_t numBytesToAlloc = allocationSize + headerSkip;
-        // Detect integer overflow.
-        if (numBytesToAlloc < allocationSize)
-            return 0;
+	if (allocationSize > pageSize - headerSkip) {
+		//
+		// Do a multi-page allocation.  Don't mix these with the others.
+		// The OS is efficient and allocating and free-ing multiple pages.
+		//
+		size_t numBytesToAlloc = allocationSize + headerSkip;
+		// Detect integer overflow.
+		if (numBytesToAlloc < allocationSize)
+			return 0;
 
-        tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
-        if (memory == 0)
-            return 0;
+		tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
+		if (memory == 0)
+			return 0;
 
-        // Use placement-new to initialize header
-        new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize);
-        inUseList = memory;
+		// Use placement-new to initialize header
+		new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize);
+		inUseList = memory;
 
-        currentPageOffset = pageSize;  // make next allocation come from a new page
+		currentPageOffset = pageSize;  // make next allocation come from a new page
 
-        // No guard blocks for multi-page allocations (yet)
-        return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(memory) + headerSkip);
-    }
+		// No guard blocks for multi-page allocations (yet)
+		return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(memory) + headerSkip);
+	}
 
-    //
-    // Need a simple page to allocate from.
-    //
-    tHeader* memory;
-    if (freeList) {
-        memory = freeList;
-        freeList = freeList->nextPage;
-    } else {
-        memory = reinterpret_cast<tHeader*>(::new char[pageSize]);
-        if (memory == 0)
-            return 0;
-    }
+	//
+	// Need a simple page to allocate from.
+	//
+	tHeader* memory;
+	if (freeList) {
+		memory = freeList;
+		freeList = freeList->nextPage;
+	} else {
+		memory = reinterpret_cast<tHeader*>(::new char[pageSize]);
+		if (memory == 0)
+			return 0;
+	}
 
-    // Use placement-new to initialize header
-    new(memory) tHeader(inUseList, 1);
-    inUseList = memory;
-    
-    unsigned char* ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip;
-    currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
+	// Use placement-new to initialize header
+	new(memory) tHeader(inUseList, 1);
+	inUseList = memory;
 
-    return initializeAllocation(inUseList, ret, numBytes);
+	unsigned char* ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip;
+	currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
+
+	return initializeAllocation(inUseList, ret, numBytes);
 }
 
 
@@ -288,6 +296,6 @@
 //
 void TAllocation::checkAllocList() const
 {
-    for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
-        alloc->check();
+	for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
+		alloc->check();
 }
diff --git a/src/OpenGL/compiler/PoolAlloc.h b/src/OpenGL/compiler/PoolAlloc.h
index b032c47..1aca1c9 100644
--- a/src/OpenGL/compiler/PoolAlloc.h
+++ b/src/OpenGL/compiler/PoolAlloc.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _POOLALLOC_INCLUDED_
 #define _POOLALLOC_INCLUDED_
@@ -13,8 +21,8 @@
 
 //
 // This header defines an allocator that can be used to efficiently
-// allocate a large number of small requests for heap memory, with the 
-// intention that they are not individually deallocated, but rather 
+// allocate a large number of small requests for heap memory, with the
+// intention that they are not individually deallocated, but rather
 // collectively deallocated at one time.
 //
 // This simultaneously
@@ -38,70 +46,70 @@
 // If we are using guard blocks, we must track each indivual
 // allocation.  If we aren't using guard blocks, these
 // never get instantiated, so won't have any impact.
-// 
+//
 
 class TAllocation {
 public:
-    TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) :
-        size(size), mem(mem), prevAlloc(prev) {
-        // Allocations are bracketed:
-        //    [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
-        // This would be cleaner with if (guardBlockSize)..., but that
-        // makes the compiler print warnings about 0 length memsets,
-        // even with the if() protecting them.
+	TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) :
+		size(size), mem(mem), prevAlloc(prev) {
+		// Allocations are bracketed:
+		//    [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
+		// This would be cleaner with if (guardBlockSize)..., but that
+		// makes the compiler print warnings about 0 length memsets,
+		// even with the if() protecting them.
 #ifdef GUARD_BLOCKS
-        memset(preGuard(), guardBlockBeginVal, guardBlockSize);
-        memset(data(),      userDataFill,       size);
-        memset(postGuard(), guardBlockEndVal,   guardBlockSize);
+		memset(preGuard(), guardBlockBeginVal, guardBlockSize);
+		memset(data(),      userDataFill,       size);
+		memset(postGuard(), guardBlockEndVal,   guardBlockSize);
 #endif
-    }
+	}
 
-    void check() const {
-        checkGuardBlock(preGuard(),  guardBlockBeginVal, "before");
-        checkGuardBlock(postGuard(), guardBlockEndVal,   "after");
-    }
+	void check() const {
+		checkGuardBlock(preGuard(),  guardBlockBeginVal, "before");
+		checkGuardBlock(postGuard(), guardBlockEndVal,   "after");
+	}
 
-    void checkAllocList() const;
+	void checkAllocList() const;
 
-    // Return total size needed to accomodate user buffer of 'size',
-    // plus our tracking data.
-    inline static size_t allocationSize(size_t size) {
-        return size + 2 * guardBlockSize + headerSize();
-    }
+	// Return total size needed to accomodate user buffer of 'size',
+	// plus our tracking data.
+	inline static size_t allocationSize(size_t size) {
+		return size + 2 * guardBlockSize + headerSize();
+	}
 
-    // Offset from surrounding buffer to get to user data buffer.
-    inline static unsigned char* offsetAllocation(unsigned char* m) {
-        return m + guardBlockSize + headerSize();
-    }
+	// Offset from surrounding buffer to get to user data buffer.
+	inline static unsigned char* offsetAllocation(unsigned char* m) {
+		return m + guardBlockSize + headerSize();
+	}
 
 private:
-    void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const;
+	void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const;
 
-    // Find offsets to pre and post guard blocks, and user data buffer
-    unsigned char* preGuard()  const { return mem + headerSize(); }
-    unsigned char* data()      const { return preGuard() + guardBlockSize; }
-    unsigned char* postGuard() const { return data() + size; }
+	// Find offsets to pre and post guard blocks, and user data buffer
+	unsigned char* preGuard()  const { return mem + headerSize(); }
+	unsigned char* data()      const { return preGuard() + guardBlockSize; }
+	unsigned char* postGuard() const { return data() + size; }
 
-    size_t size;                  // size of the user data area
-    unsigned char* mem;           // beginning of our allocation (pts to header)
-    TAllocation* prevAlloc;       // prior allocation in the chain
+	size_t size;                  // size of the user data area
+	unsigned char* mem;           // beginning of our allocation (pts to header)
+	TAllocation* prevAlloc;       // prior allocation in the chain
 
-    // Support MSVC++ 6.0
-    const static unsigned char guardBlockBeginVal;
-    const static unsigned char guardBlockEndVal;
-    const static unsigned char userDataFill;
+	// Support MSVC++ 6.0
+	const static unsigned char guardBlockBeginVal;
+	const static unsigned char guardBlockEndVal;
+	const static unsigned char userDataFill;
 
-    const static size_t guardBlockSize;
+	const static size_t guardBlockSize;
 #ifdef GUARD_BLOCKS
-    inline static size_t headerSize() { return sizeof(TAllocation); }
+	inline static size_t headerSize() { return sizeof(TAllocation); }
 #else
-    inline static size_t headerSize() { return 0; }
+	inline static size_t headerSize() { return 0; }
 #endif
 };
 
 //
 // There are several stacks.  One is to track the pushing and popping
-// of the user, and not yet implemented.  The others are simply a 
+// of the user, and not yet implemented.  The others are simply a
 // repositories of free pages or used pages.
 //
 // Page stacks are linked together with a simple header at the beginning
@@ -110,107 +118,107 @@
 // re-use.
 //
 // The "page size" used is not, nor must it match, the underlying OS
-// page size.  But, having it be about that size or equal to a set of 
+// page size.  But, having it be about that size or equal to a set of
 // pages is likely most optimal.
 //
 class TPoolAllocator {
 public:
-    TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
+	TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
 
-    //
-    // Don't call the destructor just to free up the memory, call pop()
-    //
-    ~TPoolAllocator();
+	//
+	// Don't call the destructor just to free up the memory, call pop()
+	//
+	~TPoolAllocator();
 
-    //
-    // Call push() to establish a new place to pop memory too.  Does not
-    // have to be called to get things started.
-    //
-    void push();
+	//
+	// Call push() to establish a new place to pop memory too.  Does not
+	// have to be called to get things started.
+	//
+	void push();
 
-    //
-    // Call pop() to free all memory allocated since the last call to push(),
-    // or if no last call to push, frees all memory since first allocation.
-    //
-    void pop();
+	//
+	// Call pop() to free all memory allocated since the last call to push(),
+	// or if no last call to push, frees all memory since first allocation.
+	//
+	void pop();
 
-    //
-    // Call popAll() to free all memory allocated.
-    //
-    void popAll();
+	//
+	// Call popAll() to free all memory allocated.
+	//
+	void popAll();
 
-    //
-    // Call allocate() to actually acquire memory.  Returns 0 if no memory
-    // available, otherwise a properly aligned pointer to 'numBytes' of memory.
-    //
-    void* allocate(size_t numBytes);
+	//
+	// Call allocate() to actually acquire memory.  Returns 0 if no memory
+	// available, otherwise a properly aligned pointer to 'numBytes' of memory.
+	//
+	void* allocate(size_t numBytes);
 
-    //
-    // There is no deallocate.  The point of this class is that
-    // deallocation can be skipped by the user of it, as the model
-    // of use is to simultaneously deallocate everything at once
-    // by calling pop(), and to not have to solve memory leak problems.
-    //
+	//
+	// There is no deallocate.  The point of this class is that
+	// deallocation can be skipped by the user of it, as the model
+	// of use is to simultaneously deallocate everything at once
+	// by calling pop(), and to not have to solve memory leak problems.
+	//
 
 protected:
-    friend struct tHeader;
-    
-    struct tHeader {
-        tHeader(tHeader* nextPage, size_t pageCount) :
-            nextPage(nextPage),
-            pageCount(pageCount)
+	friend struct tHeader;
+
+	struct tHeader {
+		tHeader(tHeader* nextPage, size_t pageCount) :
+			nextPage(nextPage),
+			pageCount(pageCount)
 #ifdef GUARD_BLOCKS
-          , lastAllocation(0)
+		  , lastAllocation(0)
 #endif
-            { }
+			{ }
 
-        ~tHeader() {
+		~tHeader() {
 #ifdef GUARD_BLOCKS
-            if (lastAllocation)
-                lastAllocation->checkAllocList();
+			if (lastAllocation)
+				lastAllocation->checkAllocList();
 #endif
-        }
+		}
 
-        tHeader* nextPage;
-        size_t pageCount;
+		tHeader* nextPage;
+		size_t pageCount;
 #ifdef GUARD_BLOCKS
-        TAllocation* lastAllocation;
+		TAllocation* lastAllocation;
 #endif
-    };
+	};
 
-    struct tAllocState {
-        size_t offset;
-        tHeader* page;
-    };
-    typedef std::vector<tAllocState> tAllocStack;
+	struct tAllocState {
+		size_t offset;
+		tHeader* page;
+	};
+	typedef std::vector<tAllocState> tAllocStack;
 
-    // Track allocations if and only if we're using guard blocks
-    void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) {
+	// Track allocations if and only if we're using guard blocks
+	void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) {
 #ifdef GUARD_BLOCKS
-        new(memory) TAllocation(numBytes, memory, block->lastAllocation);
-        block->lastAllocation = reinterpret_cast<TAllocation*>(memory);
+		new(memory) TAllocation(numBytes, memory, block->lastAllocation);
+		block->lastAllocation = reinterpret_cast<TAllocation*>(memory);
 #endif
-        // This is optimized entirely away if GUARD_BLOCKS is not defined.
-        return TAllocation::offsetAllocation(memory);
-    }
+		// This is optimized entirely away if GUARD_BLOCKS is not defined.
+		return TAllocation::offsetAllocation(memory);
+	}
 
-    size_t pageSize;        // granularity of allocation from the OS
-    size_t alignment;       // all returned allocations will be aligned at 
-                            // this granularity, which will be a power of 2
-    size_t alignmentMask;
-    size_t headerSkip;      // amount of memory to skip to make room for the
-                            //      header (basically, size of header, rounded
-                            //      up to make it aligned
-    size_t currentPageOffset;  // next offset in top of inUseList to allocate from
-    tHeader* freeList;      // list of popped memory
-    tHeader* inUseList;     // list of all memory currently being used
-    tAllocStack stack;      // stack of where to allocate from, to partition pool
+	size_t pageSize;        // granularity of allocation from the OS
+	size_t alignment;       // all returned allocations will be aligned at
+							// this granularity, which will be a power of 2
+	size_t alignmentMask;
+	size_t headerSkip;      // amount of memory to skip to make room for the
+							//      header (basically, size of header, rounded
+							//      up to make it aligned
+	size_t currentPageOffset;  // next offset in top of inUseList to allocate from
+	tHeader* freeList;      // list of popped memory
+	tHeader* inUseList;     // list of all memory currently being used
+	tAllocStack stack;      // stack of where to allocate from, to partition pool
 
-    int numCalls;           // just an interesting statistic
-    size_t totalBytes;      // just an interesting statistic
+	int numCalls;           // just an interesting statistic
+	size_t totalBytes;      // just an interesting statistic
 private:
-    TPoolAllocator& operator=(const TPoolAllocator&);  // dont allow assignment operator
-    TPoolAllocator(const TPoolAllocator&);  // dont allow default copy constructor
+	TPoolAllocator& operator=(const TPoolAllocator&);  // dont allow assignment operator
+	TPoolAllocator(const TPoolAllocator&);  // dont allow default copy constructor
 };
 
 
@@ -232,69 +240,69 @@
 template<class T>
 class pool_allocator {
 public:
-    typedef size_t size_type;
-    typedef ptrdiff_t difference_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    typedef T& reference;
-    typedef const T& const_reference;
-    typedef T value_type;
+	typedef size_t size_type;
+	typedef ptrdiff_t difference_type;
+	typedef T* pointer;
+	typedef const T* const_pointer;
+	typedef T& reference;
+	typedef const T& const_reference;
+	typedef T value_type;
 
-    template<class Other> 
-    struct rebind {
-        typedef pool_allocator<Other> other;
-    };
-    pointer address(reference x) const { return &x; }
-    const_pointer address(const_reference x) const { return &x; }
+	template<class Other>
+	struct rebind {
+		typedef pool_allocator<Other> other;
+	};
+	pointer address(reference x) const { return &x; }
+	const_pointer address(const_reference x) const { return &x; }
 
-    pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
-    pool_allocator(TPoolAllocator& a) : allocator(&a) { }
-    pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
+	pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
+	pool_allocator(TPoolAllocator& a) : allocator(&a) { }
+	pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
 
-    template <class Other>
-    pool_allocator<T>& operator=(const pool_allocator<Other>& p) {
-      allocator = p.allocator;
-      return *this;
-    }
+	template <class Other>
+	pool_allocator<T>& operator=(const pool_allocator<Other>& p) {
+	  allocator = p.allocator;
+	  return *this;
+	}
 
-    template<class Other>
-    pool_allocator(const pool_allocator<Other>& p) : allocator(&p.getAllocator()) { }
+	template<class Other>
+	pool_allocator(const pool_allocator<Other>& p) : allocator(&p.getAllocator()) { }
 
 #if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR)
-    // libCStd on some platforms have a different allocate/deallocate interface.
-    // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
-    // allocated, not the number of elements.
-    void* allocate(size_type n) { 
-        return getAllocator().allocate(n);
-    }
-    void* allocate(size_type n, const void*) {
-        return getAllocator().allocate(n);
-    }
-    void deallocate(void*, size_type) {}
+	// libCStd on some platforms have a different allocate/deallocate interface.
+	// Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
+	// allocated, not the number of elements.
+	void* allocate(size_type n) {
+		return getAllocator().allocate(n);
+	}
+	void* allocate(size_type n, const void*) {
+		return getAllocator().allocate(n);
+	}
+	void deallocate(void*, size_type) {}
 #else
-    pointer allocate(size_type n) { 
-        return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
-    }
-    pointer allocate(size_type n, const void*) { 
-        return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
-    }
-    void deallocate(pointer, size_type) {}
+	pointer allocate(size_type n) {
+		return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
+	}
+	pointer allocate(size_type n, const void*) {
+		return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
+	}
+	void deallocate(pointer, size_type) {}
 #endif  // _RWSTD_ALLOCATOR
 
-    void construct(pointer p, const T& val) { new ((void *)p) T(val); }
-    void destroy(pointer p) { p->T::~T(); }
+	void construct(pointer p, const T& val) { new ((void *)p) T(val); }
+	void destroy(pointer p) { p->T::~T(); }
 
-    bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); }
-    bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); }
+	bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); }
+	bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); }
 
-    size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
-    size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
+	size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
+	size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
 
-    void setAllocator(TPoolAllocator *a) { allocator = a; }
-    TPoolAllocator& getAllocator() const { return *allocator; }
+	void setAllocator(TPoolAllocator *a) { allocator = a; }
+	TPoolAllocator& getAllocator() const { return *allocator; }
 
 protected:
-    TPoolAllocator *allocator;
+	TPoolAllocator *allocator;
 };
 
 #endif // _POOLALLOC_INCLUDED_
diff --git a/src/OpenGL/compiler/Pragma.h b/src/OpenGL/compiler/Pragma.h
index 2f74412..04df5b1 100644
--- a/src/OpenGL/compiler/Pragma.h
+++ b/src/OpenGL/compiler/Pragma.h
@@ -1,19 +1,27 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef COMPILER_PRAGMA_H_
 #define COMPILER_PRAGMA_H_
 
 struct TPragma {
-    // By default optimization is turned on and debug is turned off.
-    TPragma() : optimize(true), debug(false) { }
-    TPragma(bool o, bool d) : optimize(o), debug(d) { }
+	// By default optimization is turned on and debug is turned off.
+	TPragma() : optimize(true), debug(false) { }
+	TPragma(bool o, bool d) : optimize(o), debug(d) { }
 
-    bool optimize;
-    bool debug;
+	bool optimize;
+	bool debug;
 };
 
 #endif // COMPILER_PRAGMA_H_
diff --git a/src/OpenGL/compiler/SymbolTable.cpp b/src/OpenGL/compiler/SymbolTable.cpp
index 0d449d9..39023ae 100644
--- a/src/OpenGL/compiler/SymbolTable.cpp
+++ b/src/OpenGL/compiler/SymbolTable.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 //
 // Symbol table for parsing.  Most functionaliy and main ideas
@@ -26,15 +34,15 @@
 int TSymbolTableLevel::uniqueId = 0;
 
 TType::TType(const TPublicType &p) :
-    type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(false), layoutQualifier(TLayoutQualifier::create()),

-    primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), maxArraySize(0),

-    arrayInformationType(0), interfaceBlock(0), structure(0), deepestStructNesting(0), mangled(0)
+	type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(false), layoutQualifier(TLayoutQualifier::create()),
+	primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), maxArraySize(0),
+	arrayInformationType(0), interfaceBlock(0), structure(0), deepestStructNesting(0), mangled(0)
 {
-    if (p.userDef)
-    {
-        structure = p.userDef->getStruct();
-        computeDeepestStructNesting();
-    }
+	if (p.userDef)
+	{
+		structure = p.userDef->getStruct();
+		computeDeepestStructNesting();
+	}
 }
 
 //
@@ -42,17 +50,17 @@
 //
 void TType::buildMangledName(TString& mangledName)
 {
-    if (isMatrix())
-        mangledName += 'm';
-    else if (isVector())
-        mangledName += 'v';
+	if (isMatrix())
+		mangledName += 'm';
+	else if (isVector())
+		mangledName += 'v';
 
-    switch (type) {
-    case EbtFloat:              mangledName += 'f';      break;
-    case EbtInt:                mangledName += 'i';      break;
-    case EbtUInt:               mangledName += 'u';      break;
-    case EbtBool:               mangledName += 'b';      break;
-    case EbtSampler2D:          mangledName += "s2";     break;
+	switch (type) {
+	case EbtFloat:              mangledName += 'f';      break;
+	case EbtInt:                mangledName += 'i';      break;
+	case EbtUInt:               mangledName += 'u';      break;
+	case EbtBool:               mangledName += 'b';      break;
+	case EbtSampler2D:          mangledName += "s2";     break;
 	case EbtSampler3D:          mangledName += "s3";     break;
 	case EbtSamplerCube:        mangledName += "sC";     break;
 	case EbtSampler2DArray:		mangledName += "s2a";    break;
@@ -70,31 +78,31 @@
 	case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
 	case EbtStruct:             mangledName += structure->mangledName(); break;
 	case EbtInterfaceBlock:	    mangledName += interfaceBlock->mangledName(); break;
-    default:
-        break;
-    }
+	default:
+		break;
+	}
 
-    mangledName += static_cast<char>('0' + getNominalSize());
-    if(isMatrix()) {
-        mangledName += static_cast<char>('0' + getSecondarySize());
-    }
-    if (isArray()) {
-        char buf[20];
-        snprintf(buf, sizeof(buf), "%d", arraySize);
-        mangledName += '[';
-        mangledName += buf;
-        mangledName += ']';
-    }
+	mangledName += static_cast<char>('0' + getNominalSize());
+	if(isMatrix()) {
+		mangledName += static_cast<char>('0' + getSecondarySize());
+	}
+	if (isArray()) {
+		char buf[20];
+		snprintf(buf, sizeof(buf), "%d", arraySize);
+		mangledName += '[';
+		mangledName += buf;
+		mangledName += ']';
+	}
 }
 
 size_t TType::getStructSize() const
 {
-    if (!getStruct()) {
-        assert(false && "Not a struct");
-        return 0;
-    }
+	if (!getStruct()) {
+		assert(false && "Not a struct");
+		return 0;
+	}
 
-    return getStruct()->objectSize();
+	return getStruct()->objectSize();
 }
 
 void TType::computeDeepestStructNesting()
@@ -163,8 +171,8 @@
 //
 TFunction::~TFunction()
 {
-    for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
-        delete (*i).type;
+	for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
+		delete (*i).type;
 }
 
 //
@@ -172,62 +180,62 @@
 //
 TSymbolTableLevel::~TSymbolTableLevel()
 {
-    for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
-        delete (*it).second;
+	for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
+		delete (*it).second;
 }
 
 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
 {
-    int level = currentLevel();
-    TSymbol *symbol = nullptr;
+	int level = currentLevel();
+	TSymbol *symbol = nullptr;
 
-    do
-    {
-        while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
-              (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
-        {
-            --level;
-        }
+	do
+	{
+		while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
+		      (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
+		{
+			--level;
+		}
 
-        symbol = table[level]->find(name);
-    }
-    while(!symbol && --level >= 0);   // Doesn't decrement level when a symbol was found
+		symbol = table[level]->find(name);
+	}
+	while(!symbol && --level >= 0);   // Doesn't decrement level when a symbol was found
 
-    if(builtIn)
-    {
-        *builtIn = (level <= LAST_BUILTIN_LEVEL);
-    }
+	if(builtIn)
+	{
+		*builtIn = (level <= LAST_BUILTIN_LEVEL);
+	}
 
-    if(sameScope)
-    {
-        *sameScope = (level == currentLevel());
-    }
+	if(sameScope)
+	{
+		*sameScope = (level == currentLevel());
+	}
 
-    return symbol;
+	return symbol;
 }
 
 TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
 {
-    for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
-    {
-        while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
-              (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
-        {
-            --level;
-        }
+	for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
+	{
+		while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
+		      (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
+		{
+			--level;
+		}
 
-        TSymbol *symbol = table[level]->find(name);
+		TSymbol *symbol = table[level]->find(name);
 
-        if(symbol)
-        {
-            return symbol;
-        }
-    }
+		if(symbol)
+		{
+			return symbol;
+		}
+	}
 
-    return 0;
+	return 0;
 }
 
 TSymbol::TSymbol(const TSymbol& copyOf)
 {
-    name = NewPoolTString(copyOf.name->c_str());
+	name = NewPoolTString(copyOf.name->c_str());
 }
diff --git a/src/OpenGL/compiler/SymbolTable.h b/src/OpenGL/compiler/SymbolTable.h
index 153e814..d8c6029 100644
--- a/src/OpenGL/compiler/SymbolTable.h
+++ b/src/OpenGL/compiler/SymbolTable.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _SYMBOL_TABLE_INCLUDED_
 #define _SYMBOL_TABLE_INCLUDED_
@@ -46,21 +54,21 @@
 class TSymbol
 {
 public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TSymbol(const TString *n) :  name(n) { }
-    virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
+	POOL_ALLOCATOR_NEW_DELETE();
+	TSymbol(const TString *n) :  name(n) { }
+	virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
 
-    const TString& getName() const { return *name; }
-    virtual const TString& getMangledName() const { return getName(); }
-    virtual bool isFunction() const { return false; }
-    virtual bool isVariable() const { return false; }
-    void setUniqueId(int id) { uniqueId = id; }
-    int getUniqueId() const { return uniqueId; }
-    TSymbol(const TSymbol&);
+	const TString& getName() const { return *name; }
+	virtual const TString& getMangledName() const { return getName(); }
+	virtual bool isFunction() const { return false; }
+	virtual bool isVariable() const { return false; }
+	void setUniqueId(int id) { uniqueId = id; }
+	int getUniqueId() const { return uniqueId; }
+	TSymbol(const TSymbol&);
 
 protected:
-    const TString *name;
-    unsigned int uniqueId;      // For real comparing during code generation
+	const TString *name;
+	unsigned int uniqueId;      // For real comparing during code generation
 };
 
 //
@@ -76,43 +84,43 @@
 class TVariable : public TSymbol
 {
 public:
-    TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
-    virtual ~TVariable() { }
-    virtual bool isVariable() const { return true; }
-    TType& getType() { return type; }
-    const TType& getType() const { return type; }
-    bool isUserType() const { return userType; }
-    void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
-    void updateArrayInformationType(TType *t) { arrayInformationType = t; }
-    TType* getArrayInformationType() { return arrayInformationType; }
+	TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
+	virtual ~TVariable() { }
+	virtual bool isVariable() const { return true; }
+	TType& getType() { return type; }
+	const TType& getType() const { return type; }
+	bool isUserType() const { return userType; }
+	void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
+	void updateArrayInformationType(TType *t) { arrayInformationType = t; }
+	TType* getArrayInformationType() { return arrayInformationType; }
 
-    ConstantUnion* getConstPointer()
-    {
-        if (!unionArray)
-            unionArray = new ConstantUnion[type.getObjectSize()];
+	ConstantUnion* getConstPointer()
+	{
+		if (!unionArray)
+			unionArray = new ConstantUnion[type.getObjectSize()];
 
-        return unionArray;
-    }
+		return unionArray;
+	}
 
-    ConstantUnion* getConstPointer() const { return unionArray; }
+	ConstantUnion* getConstPointer() const { return unionArray; }
 	bool isConstant() const { return unionArray != nullptr; }
 
-    void shareConstPointer( ConstantUnion *constArray)
-    {
-        if (unionArray == constArray)
-            return;
+	void shareConstPointer( ConstantUnion *constArray)
+	{
+		if (unionArray == constArray)
+			return;
 
-        delete[] unionArray;
-        unionArray = constArray;
-    }
+		delete[] unionArray;
+		unionArray = constArray;
+	}
 
 protected:
-    TType type;
-    bool userType;
-    // we are assuming that Pool Allocator will free the memory allocated to unionArray
-    // when this object is destroyed
-    ConstantUnion *unionArray;
-    TType *arrayInformationType;  // this is used for updating maxArraySize in all the references to a given symbol
+	TType type;
+	bool userType;
+	// we are assuming that Pool Allocator will free the memory allocated to unionArray
+	// when this object is destroyed
+	ConstantUnion *unionArray;
+	TType *arrayInformationType;  // this is used for updating maxArraySize in all the references to a given symbol
 };
 
 //
@@ -121,8 +129,8 @@
 //
 struct TParameter
 {
-    TString *name;
-    TType *type;
+	TString *name;
+	TType *type;
 };
 
 //
@@ -131,57 +139,57 @@
 class TFunction : public TSymbol
 {
 public:
-    TFunction(TOperator o) :
-        TSymbol(0),
-        returnType(TType(EbtVoid, EbpUndefined)),
-        op(o),
-        defined(false),
-		prototypeDeclaration(false) { }
-    TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull, const char *ext = "") :
-        TSymbol(name),
-        returnType(retType),
-        mangledName(TFunction::mangleName(*name)),
-        op(tOp),
-        extension(ext),
+	TFunction(TOperator o) :
+		TSymbol(0),
+		returnType(TType(EbtVoid, EbpUndefined)),
+		op(o),
 		defined(false),
 		prototypeDeclaration(false) { }
-    virtual ~TFunction();
-    virtual bool isFunction() const { return true; }
+	TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull, const char *ext = "") :
+		TSymbol(name),
+		returnType(retType),
+		mangledName(TFunction::mangleName(*name)),
+		op(tOp),
+		extension(ext),
+		defined(false),
+		prototypeDeclaration(false) { }
+	virtual ~TFunction();
+	virtual bool isFunction() const { return true; }
 
-    static TString mangleName(const TString& name) { return name + '('; }
-    static TString unmangleName(const TString& mangledName)
-    {
-        return TString(mangledName.c_str(), mangledName.find_first_of('('));
-    }
+	static TString mangleName(const TString& name) { return name + '('; }
+	static TString unmangleName(const TString& mangledName)
+	{
+		return TString(mangledName.c_str(), mangledName.find_first_of('('));
+	}
 
-    void addParameter(TParameter& p)
-    {
-        parameters.push_back(p);
-        mangledName = mangledName + p.type->getMangledName();
-    }
+	void addParameter(TParameter& p)
+	{
+		parameters.push_back(p);
+		mangledName = mangledName + p.type->getMangledName();
+	}
 
-    const TString& getMangledName() const { return mangledName; }
-    const TType& getReturnType() const { return returnType; }
+	const TString& getMangledName() const { return mangledName; }
+	const TType& getReturnType() const { return returnType; }
 
-    TOperator getBuiltInOp() const { return op; }
-    const TString& getExtension() const { return extension; }
+	TOperator getBuiltInOp() const { return op; }
+	const TString& getExtension() const { return extension; }
 
-    void setDefined() { defined = true; }
-    bool isDefined() { return defined; }
+	void setDefined() { defined = true; }
+	bool isDefined() { return defined; }
 	void setHasPrototypeDeclaration() { prototypeDeclaration = true; }
 	bool hasPrototypeDeclaration() const { return prototypeDeclaration; }
 
-    size_t getParamCount() const { return parameters.size(); }
-    const TParameter& getParam(int i) const { return parameters[i]; }
+	size_t getParamCount() const { return parameters.size(); }
+	const TParameter& getParam(int i) const { return parameters[i]; }
 
 protected:
-    typedef TVector<TParameter> TParamList;
-    TParamList parameters;
-    TType returnType;
-    TString mangledName;
-    TOperator op;
-    TString extension;
-    bool defined;
+	typedef TVector<TParameter> TParamList;
+	TParamList parameters;
+	TType returnType;
+	TString mangledName;
+	TOperator op;
+	TString extension;
+	bool defined;
 	bool prototypeDeclaration;
 };
 
@@ -189,36 +197,36 @@
 class TSymbolTableLevel
 {
 public:
-    typedef TMap<TString, TSymbol*> tLevel;
-    typedef tLevel::const_iterator const_iterator;
-    typedef const tLevel::value_type tLevelPair;
-    typedef std::pair<tLevel::iterator, bool> tInsertResult;
+	typedef TMap<TString, TSymbol*> tLevel;
+	typedef tLevel::const_iterator const_iterator;
+	typedef const tLevel::value_type tLevelPair;
+	typedef std::pair<tLevel::iterator, bool> tInsertResult;
 
-    POOL_ALLOCATOR_NEW_DELETE();
-    TSymbolTableLevel() { }
-    ~TSymbolTableLevel();
+	POOL_ALLOCATOR_NEW_DELETE();
+	TSymbolTableLevel() { }
+	~TSymbolTableLevel();
 
-    bool insert(TSymbol &symbol)
-    {
+	bool insert(TSymbol &symbol)
+	{
 		symbol.setUniqueId(nextUniqueId());
 
-        //
-        // returning true means symbol was added to the table
-        //
-        tInsertResult result;
-        result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
+		//
+		// returning true means symbol was added to the table
+		//
+		tInsertResult result;
+		result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
 
-        return result.second;
-    }
+		return result.second;
+	}
 
-    TSymbol* find(const TString& name) const
-    {
-        tLevel::const_iterator it = level.find(name);
-        if (it == level.end())
-            return 0;
-        else
-            return (*it).second;
-    }
+	TSymbol* find(const TString& name) const
+	{
+		tLevel::const_iterator it = level.find(name);
+		if (it == level.end())
+			return 0;
+		else
+			return (*it).second;
+	}
 
 	static int nextUniqueId()
 	{
@@ -226,17 +234,17 @@
 	}
 
 protected:
-    tLevel level;
+	tLevel level;
 	static int uniqueId;     // for unique identification in code generation
 };
 
 enum ESymbolLevel
 {
-    COMMON_BUILTINS,
-    ESSL1_BUILTINS,
-    ESSL3_BUILTINS,
-    LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
-    GLOBAL_LEVEL
+	COMMON_BUILTINS,
+	ESSL1_BUILTINS,
+	ESSL3_BUILTINS,
+	LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
+	GLOBAL_LEVEL
 };
 
 inline bool IsGenType(const TType *type)
@@ -306,49 +314,49 @@
 class TSymbolTable
 {
 public:
-    TSymbolTable()
-        : mGlobalInvariant(false)
-    {
-        //
-        // The symbol table cannot be used until push() is called, but
-        // the lack of an initial call to push() can be used to detect
-        // that the symbol table has not been preloaded with built-ins.
-        //
-    }
+	TSymbolTable()
+		: mGlobalInvariant(false)
+	{
+		//
+		// The symbol table cannot be used until push() is called, but
+		// the lack of an initial call to push() can be used to detect
+		// that the symbol table has not been preloaded with built-ins.
+		//
+	}
 
-    ~TSymbolTable()
-    {
+	~TSymbolTable()
+	{
 		while(currentLevel() > LAST_BUILTIN_LEVEL)
 		{
 			pop();
 		}
-    }
+	}
 
-    bool isEmpty() { return table.empty(); }
-    bool atBuiltInLevel() { return currentLevel() <= LAST_BUILTIN_LEVEL; }
-    bool atGlobalLevel() { return currentLevel() <= GLOBAL_LEVEL; }
-    void push()
-    {
-        table.push_back(new TSymbolTableLevel);
-        precisionStack.push_back( PrecisionStackLevel() );
-    }
+	bool isEmpty() { return table.empty(); }
+	bool atBuiltInLevel() { return currentLevel() <= LAST_BUILTIN_LEVEL; }
+	bool atGlobalLevel() { return currentLevel() <= GLOBAL_LEVEL; }
+	void push()
+	{
+		table.push_back(new TSymbolTableLevel);
+		precisionStack.push_back( PrecisionStackLevel() );
+	}
 
-    void pop()
-    {
-        delete table[currentLevel()];
-        table.pop_back();
-        precisionStack.pop_back();
-    }
+	void pop()
+	{
+		delete table[currentLevel()];
+		table.pop_back();
+		precisionStack.pop_back();
+	}
 
-    bool declare(TSymbol &symbol)
-    {
-        return insert(currentLevel(), symbol);
-    }
+	bool declare(TSymbol &symbol)
+	{
+		return insert(currentLevel(), symbol);
+	}
 
-    bool insert(ESymbolLevel level, TSymbol &symbol)
-    {
-        return table[level]->insert(symbol);
-    }
+	bool insert(ESymbolLevel level, TSymbol &symbol)
+	{
+		return table[level]->insert(symbol);
+	}
 
 	bool insertConstInt(ESymbolLevel level, const char *name, int value)
 	{
@@ -435,61 +443,61 @@
 
 			insert(level, *function);
 		}
-    }
+	}
 
 	void insertBuiltIn(ESymbolLevel level, TOperator op, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
 	{
 		insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
-    }
+	}
 
 	void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
 	{
 		insertBuiltIn(level, EOpNull, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
-    }
+	}
 
-    TSymbol *find(const TString &name, int shaderVersion, bool *builtIn = nullptr, bool *sameScope = nullptr) const;
-    TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
+	TSymbol *find(const TString &name, int shaderVersion, bool *builtIn = nullptr, bool *sameScope = nullptr) const;
+	TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
 
-    TSymbolTableLevel *getOuterLevel() const
-    {
-        assert(currentLevel() >= 1);
-        return table[currentLevel() - 1];
-    }
+	TSymbolTableLevel *getOuterLevel() const
+	{
+		assert(currentLevel() >= 1);
+		return table[currentLevel() - 1];
+	}
 
-    bool setDefaultPrecision(const TPublicType &type, TPrecision prec)
-    {
-        if (IsSampler(type.type))
-            return true;  // Skip sampler types for the time being
-        if (type.type != EbtFloat && type.type != EbtInt)
-            return false; // Only set default precision for int/float
-        if (type.primarySize > 1 || type.secondarySize > 1 || type.array)
-            return false; // Not allowed to set for aggregate types
-        int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
-        precisionStack[indexOfLastElement][type.type] = prec; // Uses map operator [], overwrites the current value
-        return true;
-    }
+	bool setDefaultPrecision(const TPublicType &type, TPrecision prec)
+	{
+		if (IsSampler(type.type))
+			return true;  // Skip sampler types for the time being
+		if (type.type != EbtFloat && type.type != EbtInt)
+			return false; // Only set default precision for int/float
+		if (type.primarySize > 1 || type.secondarySize > 1 || type.array)
+			return false; // Not allowed to set for aggregate types
+		int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
+		precisionStack[indexOfLastElement][type.type] = prec; // Uses map operator [], overwrites the current value
+		return true;
+	}
 
-    // Searches down the precisionStack for a precision qualifier for the specified TBasicType
-    TPrecision getDefaultPrecision( TBasicType type)
-    {
-        // unsigned integers use the same precision as signed
-        if (type == EbtUInt) type = EbtInt;
+	// Searches down the precisionStack for a precision qualifier for the specified TBasicType
+	TPrecision getDefaultPrecision( TBasicType type)
+	{
+		// unsigned integers use the same precision as signed
+		if (type == EbtUInt) type = EbtInt;
 
-        if( type != EbtFloat && type != EbtInt ) return EbpUndefined;
-        int level = static_cast<int>(precisionStack.size()) - 1;
-        assert( level >= 0); // Just to be safe. Should not happen.
-        PrecisionStackLevel::iterator it;
-        TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
-        while( level >= 0 ){
-            it = precisionStack[level].find( type );
-            if( it != precisionStack[level].end() ){
-                prec = (*it).second;
-                break;
-            }
-            level--;
-        }
-        return prec;
-    }
+		if( type != EbtFloat && type != EbtInt ) return EbpUndefined;
+		int level = static_cast<int>(precisionStack.size()) - 1;
+		assert( level >= 0); // Just to be safe. Should not happen.
+		PrecisionStackLevel::iterator it;
+		TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
+		while( level >= 0 ){
+			it = precisionStack[level].find( type );
+			if( it != precisionStack[level].end() ){
+				prec = (*it).second;
+				break;
+			}
+			level--;
+		}
+		return prec;
+	}
 
 	// This records invariant varyings declared through
 	// "invariant varying_name;".
@@ -511,11 +519,11 @@
 	bool getGlobalInvariant() const { return mGlobalInvariant; }
 
 protected:
-    ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
+	ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
 
-    std::vector<TSymbolTableLevel*> table;
-    typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
-    std::vector< PrecisionStackLevel > precisionStack;
+	std::vector<TSymbolTableLevel*> table;
+	typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
+	std::vector< PrecisionStackLevel > precisionStack;
 
 	std::set<std::string> mInvariantVaryings;
 	bool mGlobalInvariant;
diff --git a/src/OpenGL/compiler/TranslatorASM.cpp b/src/OpenGL/compiler/TranslatorASM.cpp
index e1a8bda..05ea246 100644
--- a/src/OpenGL/compiler/TranslatorASM.cpp
+++ b/src/OpenGL/compiler/TranslatorASM.cpp
@@ -1,28 +1,31 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 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 "TranslatorASM.h"

-

-#include "InitializeParseContext.h"

-

-TranslatorASM::TranslatorASM(glsl::Shader *shaderObject, GLenum shaderType) : TCompiler(shaderType), shaderObject(shaderObject)

-{

-}

-

-bool TranslatorASM::translate(TIntermNode* root)

-{

-    TParseContext& parseContext = *GetGlobalParseContext();

-    glsl::OutputASM outputASM(parseContext, shaderObject);

-

-	outputASM.output();

-

-	return parseContext.numErrors() == 0;

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "TranslatorASM.h"
+
+#include "InitializeParseContext.h"
+
+TranslatorASM::TranslatorASM(glsl::Shader *shaderObject, GLenum shaderType) : TCompiler(shaderType), shaderObject(shaderObject)
+{
+}
+
+bool TranslatorASM::translate(TIntermNode* root)
+{
+    TParseContext& parseContext = *GetGlobalParseContext();
+    glsl::OutputASM outputASM(parseContext, shaderObject);
+
+	outputASM.output();
+
+	return parseContext.numErrors() == 0;
+}
diff --git a/src/OpenGL/compiler/TranslatorASM.h b/src/OpenGL/compiler/TranslatorASM.h
index 41f911e..c31df96 100644
--- a/src/OpenGL/compiler/TranslatorASM.h
+++ b/src/OpenGL/compiler/TranslatorASM.h
@@ -1,35 +1,38 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef COMPILER_TRANSLATORASM_H_

-#define COMPILER_TRANSLATORASM_H_

-

-#include "Compiler.h"

-#include "OutputASM.h"

-

-namespace glsl

-{

-	class Shader;

-}

-

-class TranslatorASM : public TCompiler

-{

-public:

-    TranslatorASM(glsl::Shader *shaderObject, GLenum type);

-

-protected:

-    virtual bool translate(TIntermNode* root);

-

-private:

-	glsl::Shader *const shaderObject;

-};

-

-#endif  // COMPILER_TRANSLATORASM_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_TRANSLATORASM_H_
+#define COMPILER_TRANSLATORASM_H_
+
+#include "Compiler.h"
+#include "OutputASM.h"
+
+namespace glsl
+{
+	class Shader;
+}
+
+class TranslatorASM : public TCompiler
+{
+public:
+    TranslatorASM(glsl::Shader *shaderObject, GLenum type);
+
+protected:
+    virtual bool translate(TIntermNode* root);
+
+private:
+	glsl::Shader *const shaderObject;
+};
+
+#endif  // COMPILER_TRANSLATORASM_H_
diff --git a/src/OpenGL/compiler/Types.h b/src/OpenGL/compiler/Types.h
index 0131343..f24f9e6 100644
--- a/src/OpenGL/compiler/Types.h
+++ b/src/OpenGL/compiler/Types.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _TYPES_INCLUDED
 #define _TYPES_INCLUDED
@@ -191,7 +199,7 @@
 	}
 	bool hasInstanceName() const
 	{
-		return mInstanceName != NULL;
+		return mInstanceName != nullptr;
 	}
 	bool isArray() const
 	{
@@ -228,27 +236,27 @@
 class TType
 {
 public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TType() {}
+	POOL_ALLOCATOR_NEW_DELETE();
+	TType() {}
 	TType(TBasicType t, int s0 = 1, int s1 = 1) :
 		type(t), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), layoutQualifier(TLayoutQualifier::create()),
 		primarySize(s0), secondarySize(s1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
 		structure(0), deepestStructNesting(0), mangled(0)
-    {
-    }
-    TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s0 = 1, int s1 = 1, bool a = false) :
+	{
+	}
+	TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s0 = 1, int s1 = 1, bool a = false) :
 		type(t), precision(p), qualifier(q), invariant(false), layoutQualifier(TLayoutQualifier::create()),
 		primarySize(s0), secondarySize(s1), array(a), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
 		structure(0), deepestStructNesting(0), mangled(0)
-    {
-    }
-    explicit TType(const TPublicType &p);
+	{
+	}
+	explicit TType(const TPublicType &p);
 	TType(TStructure* userDef, TPrecision p = EbpUndefined) :
 		type(EbtStruct), precision(p), qualifier(EvqTemporary), invariant(false), layoutQualifier(TLayoutQualifier::create()),
 		primarySize(1), secondarySize(1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
 		structure(userDef), deepestStructNesting(0), mangled(0)
-    {
-    }
+	{
+	}
 
 	TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
 		TLayoutQualifier layoutQualifierIn, int arraySizeIn)
@@ -259,24 +267,24 @@
 	{
 	}
 
-    TBasicType getBasicType() const { return type; }
-    void setBasicType(TBasicType t) { type = t; }
+	TBasicType getBasicType() const { return type; }
+	void setBasicType(TBasicType t) { type = t; }
 
-    TPrecision getPrecision() const { return precision; }
-    void setPrecision(TPrecision p) { precision = p; }
+	TPrecision getPrecision() const { return precision; }
+	void setPrecision(TPrecision p) { precision = p; }
 
-    TQualifier getQualifier() const { return qualifier; }
-    void setQualifier(TQualifier q) { qualifier = q; }
+	TQualifier getQualifier() const { return qualifier; }
+	void setQualifier(TQualifier q) { qualifier = q; }
 
 	bool isInvariant() const { return invariant; }
 
 	TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
 	void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
 
-    // One-dimensional size of single instance type
+	// One-dimensional size of single instance type
 	int getNominalSize() const { return primarySize; }
 	void setNominalSize(int s) { primarySize = s; }
-    // Full size of single instance of type
+	// Full size of single instance of type
 	size_t getObjectSize() const
 	{
 		if(isArray())
@@ -372,14 +380,14 @@
 	void setSecondarySize(int s1) { secondarySize = s1; }
 	int getSecondarySize() const { return secondarySize; }
 
-    bool isArray() const  { return array ? true : false; }
-    int getArraySize() const { return arraySize; }
-    void setArraySize(int s) { array = true; arraySize = s; }
-    int getMaxArraySize () const { return maxArraySize; }
-    void setMaxArraySize (int s) { maxArraySize = s; }
-    void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
-    void setArrayInformationType(TType* t) { arrayInformationType = t; }
-    TType* getArrayInformationType() const { return arrayInformationType; }
+	bool isArray() const  { return array ? true : false; }
+	int getArraySize() const { return arraySize; }
+	void setArraySize(int s) { array = true; arraySize = s; }
+	int getMaxArraySize () const { return maxArraySize; }
+	void setMaxArraySize (int s) { maxArraySize = s; }
+	void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
+	void setArrayInformationType(TType* t) { arrayInformationType = t; }
+	TType* getArrayInformationType() const { return arrayInformationType; }
 
 	TInterfaceBlock *getInterfaceBlock() const { return interfaceBlock; }
 	void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) { interfaceBlock = interfaceBlockIn; }
@@ -395,100 +403,100 @@
 	TStructure* getStruct() const { return structure; }
 	void setStruct(TStructure* s) { structure = s; computeDeepestStructNesting(); }
 
-    TString& getMangledName() {
-        if (!mangled) {
-            mangled = NewPoolTString("");
-            buildMangledName(*mangled);
-            *mangled += ';' ;
-        }
+	TString& getMangledName() {
+		if (!mangled) {
+			mangled = NewPoolTString("");
+			buildMangledName(*mangled);
+			*mangled += ';' ;
+		}
 
-        return *mangled;
-    }
+		return *mangled;
+	}
 
-    bool sameElementType(const TType& right) const {
-        return      type == right.type   &&
+	bool sameElementType(const TType& right) const {
+		return      type == right.type   &&
 		     primarySize == right.primarySize &&
 		   secondarySize == right.secondarySize &&
-               structure == right.structure;
-    }
-    bool operator==(const TType& right) const {
-        return      type == right.type   &&
+		       structure == right.structure;
+	}
+	bool operator==(const TType& right) const {
+		return      type == right.type   &&
 		     primarySize == right.primarySize &&
 		   secondarySize == right.secondarySize &&
 			       array == right.array && (!array || arraySize == right.arraySize) &&
-               structure == right.structure;
-        // don't check the qualifier, it's not ever what's being sought after
-    }
-    bool operator!=(const TType& right) const {
-        return !operator==(right);
-    }
-    bool operator<(const TType& right) const {
-        if (type != right.type) return type < right.type;
+		       structure == right.structure;
+		// don't check the qualifier, it's not ever what's being sought after
+	}
+	bool operator!=(const TType& right) const {
+		return !operator==(right);
+	}
+	bool operator<(const TType& right) const {
+		if (type != right.type) return type < right.type;
 		if(primarySize != right.primarySize) return (primarySize * secondarySize) < (right.primarySize * right.secondarySize);
 		if(secondarySize != right.secondarySize) return secondarySize < right.secondarySize;
-        if (array != right.array) return array < right.array;
-        if (arraySize != right.arraySize) return arraySize < right.arraySize;
-        if (structure != right.structure) return structure < right.structure;
+		if (array != right.array) return array < right.array;
+		if (arraySize != right.arraySize) return arraySize < right.arraySize;
+		if (structure != right.structure) return structure < right.structure;
 
-        return false;
-    }
+		return false;
+	}
 
-    const char* getBasicString() const { return ::getBasicString(type); }
-    const char* getPrecisionString() const { return ::getPrecisionString(precision); }
-    const char* getQualifierString() const { return ::getQualifierString(qualifier); }
-    TString getCompleteString() const;
+	const char* getBasicString() const { return ::getBasicString(type); }
+	const char* getPrecisionString() const { return ::getPrecisionString(precision); }
+	const char* getQualifierString() const { return ::getQualifierString(qualifier); }
+	TString getCompleteString() const;
 
-    // If this type is a struct, returns the deepest struct nesting of
-    // any field in the struct. For example:
-    //   struct nesting1 {
-    //     vec4 position;
-    //   };
-    //   struct nesting2 {
-    //     nesting1 field1;
-    //     vec4 field2;
-    //   };
-    // For type "nesting2", this method would return 2 -- the number
-    // of structures through which indirection must occur to reach the
-    // deepest field (nesting2.field1.position).
-    int getDeepestStructNesting() const
-    {
-        return structure ? structure->deepestNesting() : 0;
-    }
+	// If this type is a struct, returns the deepest struct nesting of
+	// any field in the struct. For example:
+	//   struct nesting1 {
+	//     vec4 position;
+	//   };
+	//   struct nesting2 {
+	//     nesting1 field1;
+	//     vec4 field2;
+	//   };
+	// For type "nesting2", this method would return 2 -- the number
+	// of structures through which indirection must occur to reach the
+	// deepest field (nesting2.field1.position).
+	int getDeepestStructNesting() const
+	{
+		return structure ? structure->deepestNesting() : 0;
+	}
 
-    bool isStructureContainingArrays() const
-    {
-        return structure ? structure->containsArrays() : false;
-    }
+	bool isStructureContainingArrays() const
+	{
+		return structure ? structure->containsArrays() : false;
+	}
 
-    bool isStructureContainingSamplers() const
-    {
-        return structure ? structure->containsSamplers() : false;
-    }
+	bool isStructureContainingSamplers() const
+	{
+		return structure ? structure->containsSamplers() : false;
+	}
 
 protected:
-    void buildMangledName(TString&);
-    size_t getStructSize() const;
-    void computeDeepestStructNesting();
+	void buildMangledName(TString&);
+	size_t getStructSize() const;
+	void computeDeepestStructNesting();
 
-    TBasicType type;
-    TPrecision precision;
-    TQualifier qualifier;
+	TBasicType type;
+	TPrecision precision;
+	TQualifier qualifier;
 	bool invariant;
 	TLayoutQualifier layoutQualifier;
-    unsigned char primarySize;   // size of vector or matrix, not size of array
+	unsigned char primarySize;   // size of vector or matrix, not size of array
 	unsigned char secondarySize; // secondarySize: 1 for vectors, >1 for matrices
-    bool array;
-    int arraySize;
-    int maxArraySize;
-    TType *arrayInformationType;
+	bool array;
+	int arraySize;
+	int maxArraySize;
+	TType *arrayInformationType;
 
 	// 0 unless this is an interface block, or interface block member variable
 	TInterfaceBlock *interfaceBlock;
 
 	TStructure *structure;      // 0 unless this is a struct
-    int deepestStructNesting;
+	int deepestStructNesting;
 
-    TString *mangled;
+	TString *mangled;
 };
 
 //
@@ -502,38 +510,38 @@
 //
 struct TPublicType
 {
-    TBasicType type;
-    TLayoutQualifier layoutQualifier;
-    TQualifier qualifier;
-    bool invariant;
-    TPrecision precision;
-    int primarySize;          // size of vector or matrix, not size of array
+	TBasicType type;
+	TLayoutQualifier layoutQualifier;
+	TQualifier qualifier;
+	bool invariant;
+	TPrecision precision;
+	int primarySize;          // size of vector or matrix, not size of array
 	int secondarySize;        // 1 for scalars/vectors, >1 for matrices
-    bool array;
-    int arraySize;
-    TType* userDef;
-    TSourceLoc line;
+	bool array;
+	int arraySize;
+	TType* userDef;
+	TSourceLoc line;
 
-    void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln)
-    {
-        type = bt;
-        layoutQualifier = TLayoutQualifier::create();
-        qualifier = q;
-        invariant = false;
-        precision = EbpUndefined;
+	void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln)
+	{
+		type = bt;
+		layoutQualifier = TLayoutQualifier::create();
+		qualifier = q;
+		invariant = false;
+		precision = EbpUndefined;
 		primarySize = 1;
 		secondarySize = 1;
-        array = false;
-        arraySize = 0;
-        userDef = 0;
-        line = ln;
-    }
+		array = false;
+		arraySize = 0;
+		userDef = 0;
+		line = ln;
+	}
 
-    void setAggregate(int s)
-    {
+	void setAggregate(int s)
+	{
 		primarySize = s;
 		secondarySize = 1;
-    }
+	}
 
 	void setMatrix(int s0, int s1)
 	{
@@ -546,11 +554,11 @@
 		return array && arraySize == 0;
 	}
 
-    void setArray(bool a, int s = 0)
-    {
-        array = a;
-        arraySize = s;
-    }
+	void setArray(bool a, int s = 0)
+	{
+		array = a;
+		arraySize = s;
+	}
 
 	void clearArrayness()
 	{
@@ -558,15 +566,15 @@
 		arraySize = 0;
 	}
 
-    bool isStructureContainingArrays() const
-    {
-        if (!userDef)
-        {
-            return false;
-        }
+	bool isStructureContainingArrays() const
+	{
+		if (!userDef)
+		{
+			return false;
+		}
 
-        return userDef->isStructureContainingArrays();
-    }
+		return userDef->isStructureContainingArrays();
+	}
 
 	bool isMatrix() const
 	{
diff --git a/src/OpenGL/compiler/ValidateGlobalInitializer.cpp b/src/OpenGL/compiler/ValidateGlobalInitializer.cpp
index af2c6d3..6c5fa86 100644
--- a/src/OpenGL/compiler/ValidateGlobalInitializer.cpp
+++ b/src/OpenGL/compiler/ValidateGlobalInitializer.cpp
@@ -1,80 +1,88 @@
-//

-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "ValidateGlobalInitializer.h"

-

-#include "ParseHelper.h"

-

-namespace

-{

-

-class ValidateGlobalInitializerTraverser : public TIntermTraverser

-{

-  public:

-    ValidateGlobalInitializerTraverser(const TParseContext *context);

-

-    void visitSymbol(TIntermSymbol *node) override;

-

-    bool isValid() const { return mIsValid; }

-    bool issueWarning() const { return mIssueWarning; }

-

-  private:

-    const TParseContext *mContext;

-    bool mIsValid;

-    bool mIssueWarning;

-};

-

-void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)

-{

-    const TSymbol *sym = mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion());

-    if (sym->isVariable())

-    {

-        // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):

-        // Global initializers must be constant expressions.

-        const TVariable *var = static_cast<const TVariable *>(sym);

-        switch (var->getType().getQualifier())

-        {

-          case EvqConstExpr:

-            break;

-          case EvqGlobal:

-          case EvqTemporary:

-          case EvqUniform:

-            // We allow these cases to be compatible with legacy ESSL 1.00 content.

-            // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal with.

-            if (mContext->getShaderVersion() >= 300)

-            {

-                mIsValid = false;

-            }

-            else

-            {

-                mIssueWarning = true;

-            }

-            break;

-          default:

-            mIsValid = false;

-        }

-    }

-}

-

-ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(const TParseContext *context)

-    : TIntermTraverser(true, false, false),

-      mContext(context),

-      mIsValid(true),

-      mIssueWarning(false)

-{

-}

-

-} // namespace

-

-bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning)

-{

-    ValidateGlobalInitializerTraverser validate(context);

-    initializer->traverse(&validate);

-    ASSERT(warning != nullptr);

-    *warning = validate.issueWarning();

-    return validate.isValid();

-}

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "ValidateGlobalInitializer.h"
+
+#include "ParseHelper.h"
+
+namespace
+{
+
+class ValidateGlobalInitializerTraverser : public TIntermTraverser
+{
+public:
+	ValidateGlobalInitializerTraverser(const TParseContext *context);
+
+	void visitSymbol(TIntermSymbol *node) override;
+
+	bool isValid() const { return mIsValid; }
+	bool issueWarning() const { return mIssueWarning; }
+
+private:
+	const TParseContext *mContext;
+	bool mIsValid;
+	bool mIssueWarning;
+};
+
+void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)
+{
+	const TSymbol *sym = mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion());
+	if (sym->isVariable())
+	{
+		// ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
+		// Global initializers must be constant expressions.
+		const TVariable *var = static_cast<const TVariable *>(sym);
+		switch (var->getType().getQualifier())
+		{
+		case EvqConstExpr:
+			break;
+		case EvqGlobal:
+		case EvqTemporary:
+		case EvqUniform:
+			// We allow these cases to be compatible with legacy ESSL 1.00 content.
+			// Implement stricter rules for ESSL 3.00 since there's no legacy content to deal with.
+			if (mContext->getShaderVersion() >= 300)
+			{
+				mIsValid = false;
+			}
+			else
+			{
+				mIssueWarning = true;
+			}
+			break;
+		default:
+			mIsValid = false;
+		}
+	}
+}
+
+ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(const TParseContext *context)
+	: TIntermTraverser(true, false, false),
+	  mContext(context),
+	  mIsValid(true),
+	  mIssueWarning(false)
+{
+}
+
+} // namespace
+
+bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning)
+{
+	ValidateGlobalInitializerTraverser validate(context);
+	initializer->traverse(&validate);
+	ASSERT(warning != nullptr);
+	*warning = validate.issueWarning();
+	return validate.isValid();
+}
+
diff --git a/src/OpenGL/compiler/ValidateGlobalInitializer.h b/src/OpenGL/compiler/ValidateGlobalInitializer.h
index debc33c..28c1293 100644
--- a/src/OpenGL/compiler/ValidateGlobalInitializer.h
+++ b/src/OpenGL/compiler/ValidateGlobalInitializer.h
@@ -1,16 +1,24 @@
-//

-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_

-#define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_

-

-class TIntermTyped;

-class TParseContext;

-

-// Returns true if the initializer is valid.

-bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning);

-

-#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
+#define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
+
+class TIntermTyped;
+class TParseContext;
+
+// Returns true if the initializer is valid.
+bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning);
+
+#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
diff --git a/src/OpenGL/compiler/ValidateLimitations.cpp b/src/OpenGL/compiler/ValidateLimitations.cpp
index 1bba3c7..a685d5b 100644
--- a/src/OpenGL/compiler/ValidateLimitations.cpp
+++ b/src/OpenGL/compiler/ValidateLimitations.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "ValidateLimitations.h"
 #include "InfoSink.h"
@@ -11,22 +19,22 @@
 
 namespace {
 bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) {
-    for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) {
-        if (i->index.id == symbol->getId())
-            return true;
-    }
-    return false;
+	for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) {
+		if (i->index.id == symbol->getId())
+			return true;
+	}
+	return false;
 }
 
 void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) {
-    for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) {
-        if (i->index.id == symbol->getId()) {
-            ASSERT(i->loop != NULL);
-            i->loop->setUnrollFlag(true);
-            return;
-        }
-    }
-    UNREACHABLE(0);
+	for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) {
+		if (i->index.id == symbol->getId()) {
+			ASSERT(i->loop);
+			i->loop->setUnrollFlag(true);
+			return;
+		}
+	}
+	UNREACHABLE(0);
 }
 
 // Traverses a node to check if it represents a constant index expression.
@@ -40,24 +48,24 @@
 // - Expressions composed of both of the above
 class ValidateConstIndexExpr : public TIntermTraverser {
 public:
-    ValidateConstIndexExpr(const TLoopStack& stack)
-        : mValid(true), mLoopStack(stack) {}
+	ValidateConstIndexExpr(const TLoopStack& stack)
+		: mValid(true), mLoopStack(stack) {}
 
-    // Returns true if the parsed node represents a constant index expression.
-    bool isValid() const { return mValid; }
+	// Returns true if the parsed node represents a constant index expression.
+	bool isValid() const { return mValid; }
 
-    virtual void visitSymbol(TIntermSymbol* symbol) {
-        // Only constants and loop indices are allowed in a
-        // constant index expression.
-        if (mValid) {
-            mValid = (symbol->getQualifier() == EvqConstExpr) ||
-                     IsLoopIndex(symbol, mLoopStack);
-        }
-    }
+	virtual void visitSymbol(TIntermSymbol* symbol) {
+		// Only constants and loop indices are allowed in a
+		// constant index expression.
+		if (mValid) {
+			mValid = (symbol->getQualifier() == EvqConstExpr) ||
+			         IsLoopIndex(symbol, mLoopStack);
+		}
+	}
 
 private:
-    bool mValid;
-    const TLoopStack& mLoopStack;
+	bool mValid;
+	const TLoopStack& mLoopStack;
 };
 
 // Traverses a node to check if it uses a loop index.
@@ -65,452 +73,433 @@
 // mark the loop for unroll.
 class ValidateLoopIndexExpr : public TIntermTraverser {
 public:
-    ValidateLoopIndexExpr(TLoopStack& stack)
-        : mUsesFloatLoopIndex(false),
-          mUsesIntLoopIndex(false),
-          mLoopStack(stack) {}
+	ValidateLoopIndexExpr(TLoopStack& stack)
+		: mUsesFloatLoopIndex(false),
+		  mUsesIntLoopIndex(false),
+		  mLoopStack(stack) {}
 
-    bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; }
-    bool usesIntLoopIndex() const { return mUsesIntLoopIndex; }
+	bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; }
+	bool usesIntLoopIndex() const { return mUsesIntLoopIndex; }
 
-    virtual void visitSymbol(TIntermSymbol* symbol) {
-        if (IsLoopIndex(symbol, mLoopStack)) {
-            switch (symbol->getBasicType()) {
-              case EbtFloat:
-                mUsesFloatLoopIndex = true;
-                break;
-              case EbtUInt:
-                mUsesIntLoopIndex = true;
-                MarkLoopForUnroll(symbol, mLoopStack);
-                break;
-              case EbtInt:
-                mUsesIntLoopIndex = true;
-                MarkLoopForUnroll(symbol, mLoopStack);
-                break;
-              default:
-                UNREACHABLE(symbol->getBasicType());
-            }
-        }
-    }
+	virtual void visitSymbol(TIntermSymbol* symbol) {
+		if (IsLoopIndex(symbol, mLoopStack)) {
+			switch (symbol->getBasicType()) {
+			case EbtFloat:
+				mUsesFloatLoopIndex = true;
+				break;
+			case EbtUInt:
+				mUsesIntLoopIndex = true;
+				MarkLoopForUnroll(symbol, mLoopStack);
+				break;
+			case EbtInt:
+				mUsesIntLoopIndex = true;
+				MarkLoopForUnroll(symbol, mLoopStack);
+				break;
+			default:
+				UNREACHABLE(symbol->getBasicType());
+			}
+		}
+	}
 
 private:
-    bool mUsesFloatLoopIndex;
-    bool mUsesIntLoopIndex;
-    TLoopStack& mLoopStack;
+	bool mUsesFloatLoopIndex;
+	bool mUsesIntLoopIndex;
+	TLoopStack& mLoopStack;
 };
 }  // namespace
 
 ValidateLimitations::ValidateLimitations(GLenum shaderType,
                                          TInfoSinkBase& sink)
-    : mShaderType(shaderType),
-      mSink(sink),
-      mNumErrors(0)
+	: mShaderType(shaderType),
+	  mSink(sink),
+	  mNumErrors(0)
 {
 }
 
 bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
 {
-    // Check if loop index is modified in the loop body.
-    validateOperation(node, node->getLeft());
+	// Check if loop index is modified in the loop body.
+	validateOperation(node, node->getLeft());
 
-    // Check indexing.
-    switch (node->getOp()) {
-      case EOpIndexDirect:
-        validateIndexing(node);
-        break;
-      case EOpIndexIndirect:
-#if defined(__APPLE__)
-        // Loop unrolling is a work-around for a Mac Cg compiler bug where it
-        // crashes when a sampler array's index is also the loop index.
-        // Once Apple fixes this bug, we should remove the code in this CL.
-        // See http://codereview.appspot.com/4331048/.
-        if ((node->getLeft() != NULL) && (node->getRight() != NULL) &&
-            (node->getLeft()->getAsSymbolNode())) {
-            TIntermSymbol* symbol = node->getLeft()->getAsSymbolNode();
-            if (IsSampler(symbol->getBasicType()) && symbol->isArray()) {
-                ValidateLoopIndexExpr validate(mLoopStack);
-                node->getRight()->traverse(&validate);
-                if (validate.usesFloatLoopIndex()) {
-                    error(node->getLine(),
-                          "sampler array index is float loop index",
-                          "for");
-                }
-            }
-        }
-#endif
-        validateIndexing(node);
-        break;
-      default: break;
-    }
-    return true;
+	// Check indexing.
+	switch (node->getOp()) {
+	case EOpIndexDirect:
+		validateIndexing(node);
+		break;
+	case EOpIndexIndirect:
+		validateIndexing(node);
+		break;
+	default: break;
+	}
+	return true;
 }
 
 bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
 {
-    // Check if loop index is modified in the loop body.
-    validateOperation(node, node->getOperand());
+	// Check if loop index is modified in the loop body.
+	validateOperation(node, node->getOperand());
 
-    return true;
+	return true;
 }
 
 bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node)
 {
-    switch (node->getOp()) {
-      case EOpFunctionCall:
-        validateFunctionCall(node);
-        break;
-      default:
-        break;
-    }
-    return true;
+	switch (node->getOp()) {
+	case EOpFunctionCall:
+		validateFunctionCall(node);
+		break;
+	default:
+		break;
+	}
+	return true;
 }
 
 bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
 {
-    if (!validateLoopType(node))
-        return false;
+	if (!validateLoopType(node))
+		return false;
 
-    TLoopInfo info;
-    memset(&info, 0, sizeof(TLoopInfo));
-    info.loop = node;
-    if (!validateForLoopHeader(node, &info))
-        return false;
+	TLoopInfo info;
+	memset(&info, 0, sizeof(TLoopInfo));
+	info.loop = node;
+	if (!validateForLoopHeader(node, &info))
+		return false;
 
-    TIntermNode* body = node->getBody();
-    if (body != NULL) {
-        mLoopStack.push_back(info);
-        body->traverse(this);
-        mLoopStack.pop_back();
-    }
+	TIntermNode* body = node->getBody();
+	if (body) {
+		mLoopStack.push_back(info);
+		body->traverse(this);
+		mLoopStack.pop_back();
+	}
 
-    // The loop is fully processed - no need to visit children.
-    return false;
+	// The loop is fully processed - no need to visit children.
+	return false;
 }
 
 void ValidateLimitations::error(TSourceLoc loc,
                                 const char *reason, const char* token)
 {
-    mSink.prefix(EPrefixError);
-    mSink.location(loc);
-    mSink << "'" << token << "' : " << reason << "\n";
-    ++mNumErrors;
+	mSink.prefix(EPrefixError);
+	mSink.location(loc);
+	mSink << "'" << token << "' : " << reason << "\n";
+	++mNumErrors;
 }
 
 bool ValidateLimitations::withinLoopBody() const
 {
-    return !mLoopStack.empty();
+	return !mLoopStack.empty();
 }
 
 bool ValidateLimitations::isLoopIndex(const TIntermSymbol* symbol) const
 {
-    return IsLoopIndex(symbol, mLoopStack);
+	return IsLoopIndex(symbol, mLoopStack);
 }
 
 bool ValidateLimitations::validateLoopType(TIntermLoop* node) {
-    TLoopType type = node->getType();
-    if (type == ELoopFor)
-        return true;
+	TLoopType type = node->getType();
+	if (type == ELoopFor)
+		return true;
 
-    // Reject while and do-while loops.
-    error(node->getLine(),
-          "This type of loop is not allowed",
-          type == ELoopWhile ? "while" : "do");
-    return false;
+	// Reject while and do-while loops.
+	error(node->getLine(),
+		  "This type of loop is not allowed",
+		  type == ELoopWhile ? "while" : "do");
+	return false;
 }
 
 bool ValidateLimitations::validateForLoopHeader(TIntermLoop* node,
                                                 TLoopInfo* info)
 {
-    ASSERT(node->getType() == ELoopFor);
+	ASSERT(node->getType() == ELoopFor);
 
-    //
-    // The for statement has the form:
-    //    for ( init-declaration ; condition ; expression ) statement
-    //
-    if (!validateForLoopInit(node, info))
-        return false;
-    if (!validateForLoopCond(node, info))
-        return false;
-    if (!validateForLoopExpr(node, info))
-        return false;
+	//
+	// The for statement has the form:
+	//    for ( init-declaration ; condition ; expression ) statement
+	//
+	if (!validateForLoopInit(node, info))
+		return false;
+	if (!validateForLoopCond(node, info))
+		return false;
+	if (!validateForLoopExpr(node, info))
+		return false;
 
-    return true;
+	return true;
 }
 
 bool ValidateLimitations::validateForLoopInit(TIntermLoop* node,
                                               TLoopInfo* info)
 {
-    TIntermNode* init = node->getInit();
-    if (init == NULL) {
-        error(node->getLine(), "Missing init declaration", "for");
-        return false;
-    }
+	TIntermNode* init = node->getInit();
+	if (!init) {
+		error(node->getLine(), "Missing init declaration", "for");
+		return false;
+	}
 
-    //
-    // init-declaration has the form:
-    //     type-specifier identifier = constant-expression
-    //
-    TIntermAggregate* decl = init->getAsAggregate();
-    if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) {
-        error(init->getLine(), "Invalid init declaration", "for");
-        return false;
-    }
-    // To keep things simple do not allow declaration list.
-    TIntermSequence& declSeq = decl->getSequence();
-    if (declSeq.size() != 1) {
-        error(decl->getLine(), "Invalid init declaration", "for");
-        return false;
-    }
-    TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
-    if ((declInit == NULL) || (declInit->getOp() != EOpInitialize)) {
-        error(decl->getLine(), "Invalid init declaration", "for");
-        return false;
-    }
-    TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
-    if (symbol == NULL) {
-        error(declInit->getLine(), "Invalid init declaration", "for");
-        return false;
-    }
-    // The loop index has type int or float.
-    TBasicType type = symbol->getBasicType();
-    if (!IsInteger(type) && (type != EbtFloat)) {
-        error(symbol->getLine(),
-              "Invalid type for loop index", getBasicString(type));
-        return false;
-    }
-    // The loop index is initialized with constant expression.
-    if (!isConstExpr(declInit->getRight())) {
-        error(declInit->getLine(),
-              "Loop index cannot be initialized with non-constant expression",
-              symbol->getSymbol().c_str());
-        return false;
-    }
+	//
+	// init-declaration has the form:
+	//     type-specifier identifier = constant-expression
+	//
+	TIntermAggregate* decl = init->getAsAggregate();
+	if (!decl || (decl->getOp() != EOpDeclaration)) {
+		error(init->getLine(), "Invalid init declaration", "for");
+		return false;
+	}
+	// To keep things simple do not allow declaration list.
+	TIntermSequence& declSeq = decl->getSequence();
+	if (declSeq.size() != 1) {
+		error(decl->getLine(), "Invalid init declaration", "for");
+		return false;
+	}
+	TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
+	if (!declInit || (declInit->getOp() != EOpInitialize)) {
+		error(decl->getLine(), "Invalid init declaration", "for");
+		return false;
+	}
+	TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
+	if (!symbol) {
+		error(declInit->getLine(), "Invalid init declaration", "for");
+		return false;
+	}
+	// The loop index has type int or float.
+	TBasicType type = symbol->getBasicType();
+	if (!IsInteger(type) && (type != EbtFloat)) {
+		error(symbol->getLine(),
+			  "Invalid type for loop index", getBasicString(type));
+		return false;
+	}
+	// The loop index is initialized with constant expression.
+	if (!isConstExpr(declInit->getRight())) {
+		error(declInit->getLine(),
+			  "Loop index cannot be initialized with non-constant expression",
+			  symbol->getSymbol().c_str());
+		return false;
+	}
 
-    info->index.id = symbol->getId();
-    return true;
+	info->index.id = symbol->getId();
+	return true;
 }
 
 bool ValidateLimitations::validateForLoopCond(TIntermLoop* node,
                                               TLoopInfo* info)
 {
-    TIntermNode* cond = node->getCondition();
-    if (cond == NULL) {
-        error(node->getLine(), "Missing condition", "for");
-        return false;
-    }
-    //
-    // condition has the form:
-    //     loop_index relational_operator constant_expression
-    //
-    TIntermBinary* binOp = cond->getAsBinaryNode();
-    if (binOp == NULL) {
-        error(node->getLine(), "Invalid condition", "for");
-        return false;
-    }
-    // Loop index should be to the left of relational operator.
-    TIntermSymbol* symbol = binOp->getLeft()->getAsSymbolNode();
-    if (symbol == NULL) {
-        error(binOp->getLine(), "Invalid condition", "for");
-        return false;
-    }
-    if (symbol->getId() != info->index.id) {
-        error(symbol->getLine(),
-              "Expected loop index", symbol->getSymbol().c_str());
-        return false;
-    }
-    // Relational operator is one of: > >= < <= == or !=.
-    switch (binOp->getOp()) {
-      case EOpEqual:
-      case EOpNotEqual:
-      case EOpLessThan:
-      case EOpGreaterThan:
-      case EOpLessThanEqual:
-      case EOpGreaterThanEqual:
-        break;
-      default:
-        error(binOp->getLine(),
-              "Invalid relational operator",
-              getOperatorString(binOp->getOp()));
-        break;
-    }
-    // Loop index must be compared with a constant.
-    if (!isConstExpr(binOp->getRight())) {
-        error(binOp->getLine(),
-              "Loop index cannot be compared with non-constant expression",
-              symbol->getSymbol().c_str());
-        return false;
-    }
+	TIntermNode* cond = node->getCondition();
+	if (!cond) {
+		error(node->getLine(), "Missing condition", "for");
+		return false;
+	}
+	//
+	// condition has the form:
+	//     loop_index relational_operator constant_expression
+	//
+	TIntermBinary* binOp = cond->getAsBinaryNode();
+	if (!binOp) {
+		error(node->getLine(), "Invalid condition", "for");
+		return false;
+	}
+	// Loop index should be to the left of relational operator.
+	TIntermSymbol* symbol = binOp->getLeft()->getAsSymbolNode();
+	if (!symbol) {
+		error(binOp->getLine(), "Invalid condition", "for");
+		return false;
+	}
+	if (symbol->getId() != info->index.id) {
+		error(symbol->getLine(),
+			  "Expected loop index", symbol->getSymbol().c_str());
+		return false;
+	}
+	// Relational operator is one of: > >= < <= == or !=.
+	switch (binOp->getOp()) {
+	case EOpEqual:
+	case EOpNotEqual:
+	case EOpLessThan:
+	case EOpGreaterThan:
+	case EOpLessThanEqual:
+	case EOpGreaterThanEqual:
+		break;
+	default:
+		error(binOp->getLine(),
+			  "Invalid relational operator",
+			  getOperatorString(binOp->getOp()));
+		break;
+	}
+	// Loop index must be compared with a constant.
+	if (!isConstExpr(binOp->getRight())) {
+		error(binOp->getLine(),
+			  "Loop index cannot be compared with non-constant expression",
+			  symbol->getSymbol().c_str());
+		return false;
+	}
 
-    return true;
+	return true;
 }
 
 bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node,
                                               TLoopInfo* info)
 {
-    TIntermNode* expr = node->getExpression();
-    if (expr == NULL) {
-        error(node->getLine(), "Missing expression", "for");
-        return false;
-    }
+	TIntermNode* expr = node->getExpression();
+	if (!expr) {
+		error(node->getLine(), "Missing expression", "for");
+		return false;
+	}
 
-    // for expression has one of the following forms:
-    //     loop_index++
-    //     loop_index--
-    //     loop_index += constant_expression
-    //     loop_index -= constant_expression
-    //     ++loop_index
-    //     --loop_index
-    // The last two forms are not specified in the spec, but I am assuming
-    // its an oversight.
-    TIntermUnary* unOp = expr->getAsUnaryNode();
-    TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
+	// for expression has one of the following forms:
+	//     loop_index++
+	//     loop_index--
+	//     loop_index += constant_expression
+	//     loop_index -= constant_expression
+	//     ++loop_index
+	//     --loop_index
+	// The last two forms are not specified in the spec, but I am assuming
+	// its an oversight.
+	TIntermUnary* unOp = expr->getAsUnaryNode();
+	TIntermBinary* binOp = unOp ? nullptr : expr->getAsBinaryNode();
 
-    TOperator op = EOpNull;
-    TIntermSymbol* symbol = NULL;
-    if (unOp != NULL) {
-        op = unOp->getOp();
-        symbol = unOp->getOperand()->getAsSymbolNode();
-    } else if (binOp != NULL) {
-        op = binOp->getOp();
-        symbol = binOp->getLeft()->getAsSymbolNode();
-    }
+	TOperator op = EOpNull;
+	TIntermSymbol* symbol = nullptr;
+	if (unOp) {
+		op = unOp->getOp();
+		symbol = unOp->getOperand()->getAsSymbolNode();
+	} else if (binOp) {
+		op = binOp->getOp();
+		symbol = binOp->getLeft()->getAsSymbolNode();
+	}
 
-    // The operand must be loop index.
-    if (symbol == NULL) {
-        error(expr->getLine(), "Invalid expression", "for");
-        return false;
-    }
-    if (symbol->getId() != info->index.id) {
-        error(symbol->getLine(),
-              "Expected loop index", symbol->getSymbol().c_str());
-        return false;
-    }
+	// The operand must be loop index.
+	if (!symbol) {
+		error(expr->getLine(), "Invalid expression", "for");
+		return false;
+	}
+	if (symbol->getId() != info->index.id) {
+		error(symbol->getLine(),
+			  "Expected loop index", symbol->getSymbol().c_str());
+		return false;
+	}
 
-    // The operator is one of: ++ -- += -=.
-    switch (op) {
-        case EOpPostIncrement:
-        case EOpPostDecrement:
-        case EOpPreIncrement:
-        case EOpPreDecrement:
-            ASSERT((unOp != NULL) && (binOp == NULL));
-            break;
-        case EOpAddAssign:
-        case EOpSubAssign:
-            ASSERT((unOp == NULL) && (binOp != NULL));
-            break;
-        default:
-            error(expr->getLine(), "Invalid operator", getOperatorString(op));
-            return false;
-    }
+	// The operator is one of: ++ -- += -=.
+	switch (op) {
+		case EOpPostIncrement:
+		case EOpPostDecrement:
+		case EOpPreIncrement:
+		case EOpPreDecrement:
+			ASSERT((unOp != NULL) && (binOp == NULL));
+			break;
+		case EOpAddAssign:
+		case EOpSubAssign:
+			ASSERT((unOp == NULL) && (binOp != NULL));
+			break;
+		default:
+			error(expr->getLine(), "Invalid operator", getOperatorString(op));
+			return false;
+	}
 
-    // Loop index must be incremented/decremented with a constant.
-    if (binOp != NULL) {
-        if (!isConstExpr(binOp->getRight())) {
-            error(binOp->getLine(),
-                  "Loop index cannot be modified by non-constant expression",
-                  symbol->getSymbol().c_str());
-            return false;
-        }
-    }
+	// Loop index must be incremented/decremented with a constant.
+	if (binOp != NULL) {
+		if (!isConstExpr(binOp->getRight())) {
+			error(binOp->getLine(),
+				  "Loop index cannot be modified by non-constant expression",
+				  symbol->getSymbol().c_str());
+			return false;
+		}
+	}
 
-    return true;
+	return true;
 }
 
 bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
 {
-    ASSERT(node->getOp() == EOpFunctionCall);
+	ASSERT(node->getOp() == EOpFunctionCall);
 
-    // If not within loop body, there is nothing to check.
-    if (!withinLoopBody())
-        return true;
+	// If not within loop body, there is nothing to check.
+	if (!withinLoopBody())
+		return true;
 
-    // List of param indices for which loop indices are used as argument.
-    typedef std::vector<int> ParamIndex;
-    ParamIndex pIndex;
-    TIntermSequence& params = node->getSequence();
-    for (TIntermSequence::size_type i = 0; i < params.size(); ++i) {
-        TIntermSymbol* symbol = params[i]->getAsSymbolNode();
-        if (symbol && isLoopIndex(symbol))
-            pIndex.push_back(i);
-    }
-    // If none of the loop indices are used as arguments,
-    // there is nothing to check.
-    if (pIndex.empty())
-        return true;
+	// List of param indices for which loop indices are used as argument.
+	typedef std::vector<int> ParamIndex;
+	ParamIndex pIndex;
+	TIntermSequence& params = node->getSequence();
+	for (TIntermSequence::size_type i = 0; i < params.size(); ++i) {
+		TIntermSymbol* symbol = params[i]->getAsSymbolNode();
+		if (symbol && isLoopIndex(symbol))
+			pIndex.push_back(i);
+	}
+	// If none of the loop indices are used as arguments,
+	// there is nothing to check.
+	if (pIndex.empty())
+		return true;
 
-    bool valid = true;
-    TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
-    TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->getShaderVersion());
-    ASSERT(symbol && symbol->isFunction());
-    TFunction* function = static_cast<TFunction*>(symbol);
-    for (ParamIndex::const_iterator i = pIndex.begin();
-         i != pIndex.end(); ++i) {
-        const TParameter& param = function->getParam(*i);
-        TQualifier qual = param.type->getQualifier();
-        if ((qual == EvqOut) || (qual == EvqInOut)) {
-            error(params[*i]->getLine(),
-                  "Loop index cannot be used as argument to a function out or inout parameter",
-                  params[*i]->getAsSymbolNode()->getSymbol().c_str());
-            valid = false;
-        }
-    }
+	bool valid = true;
+	TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
+	TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->getShaderVersion());
+	ASSERT(symbol && symbol->isFunction());
+	TFunction* function = static_cast<TFunction*>(symbol);
+	for (ParamIndex::const_iterator i = pIndex.begin();
+		 i != pIndex.end(); ++i) {
+		const TParameter& param = function->getParam(*i);
+		TQualifier qual = param.type->getQualifier();
+		if ((qual == EvqOut) || (qual == EvqInOut)) {
+			error(params[*i]->getLine(),
+				  "Loop index cannot be used as argument to a function out or inout parameter",
+				  params[*i]->getAsSymbolNode()->getSymbol().c_str());
+			valid = false;
+		}
+	}
 
-    return valid;
+	return valid;
 }
 
 bool ValidateLimitations::validateOperation(TIntermOperator* node,
                                             TIntermNode* operand) {
-    // Check if loop index is modified in the loop body.
-    if (!withinLoopBody() || !node->modifiesState())
-        return true;
+	// Check if loop index is modified in the loop body.
+	if (!withinLoopBody() || !node->modifiesState())
+		return true;
 
-    const TIntermSymbol* symbol = operand->getAsSymbolNode();
-    if (symbol && isLoopIndex(symbol)) {
-        error(node->getLine(),
-              "Loop index cannot be statically assigned to within the body of the loop",
-              symbol->getSymbol().c_str());
-    }
-    return true;
+	const TIntermSymbol* symbol = operand->getAsSymbolNode();
+	if (symbol && isLoopIndex(symbol)) {
+		error(node->getLine(),
+			  "Loop index cannot be statically assigned to within the body of the loop",
+			  symbol->getSymbol().c_str());
+	}
+	return true;
 }
 
 bool ValidateLimitations::isConstExpr(TIntermNode* node)
 {
-    ASSERT(node != NULL);
-    return node->getAsConstantUnion() != NULL;
+	ASSERT(node);
+	return node->getAsConstantUnion() != nullptr;
 }
 
 bool ValidateLimitations::isConstIndexExpr(TIntermNode* node)
 {
-    ASSERT(node != NULL);
+	ASSERT(node);
 
-    ValidateConstIndexExpr validate(mLoopStack);
-    node->traverse(&validate);
-    return validate.isValid();
+	ValidateConstIndexExpr validate(mLoopStack);
+	node->traverse(&validate);
+	return validate.isValid();
 }
 
 bool ValidateLimitations::validateIndexing(TIntermBinary* node)
 {
-    ASSERT((node->getOp() == EOpIndexDirect) ||
-           (node->getOp() == EOpIndexIndirect));
+	ASSERT((node->getOp() == EOpIndexDirect) ||
+	       (node->getOp() == EOpIndexIndirect));
 
-    bool valid = true;
-    TIntermTyped* index = node->getRight();
-    // The index expression must have integral type.
-    if (!index->isScalarInt()) {
-        error(index->getLine(),
-              "Index expression must have integral type",
-              index->getCompleteString().c_str());
-        valid = false;
-    }
-    // The index expession must be a constant-index-expression unless
-    // the operand is a uniform in a vertex shader.
-    TIntermTyped* operand = node->getLeft();
-    bool skip = (mShaderType == GL_VERTEX_SHADER) &&
-                (operand->getQualifier() == EvqUniform);
-    if (!skip && !isConstIndexExpr(index)) {
-        error(index->getLine(), "Index expression must be constant", "[]");
-        valid = false;
-    }
-    return valid;
+	bool valid = true;
+	TIntermTyped* index = node->getRight();
+	// The index expression must have integral type.
+	if (!index->isScalarInt()) {
+		error(index->getLine(),
+		      "Index expression must have integral type",
+		      index->getCompleteString().c_str());
+		valid = false;
+	}
+	// The index expession must be a constant-index-expression unless
+	// the operand is a uniform in a vertex shader.
+	TIntermTyped* operand = node->getLeft();
+	bool skip = (mShaderType == GL_VERTEX_SHADER) &&
+	            (operand->getQualifier() == EvqUniform);
+	if (!skip && !isConstIndexExpr(index)) {
+		error(index->getLine(), "Index expression must be constant", "[]");
+		valid = false;
+	}
+	return valid;
 }
 
diff --git a/src/OpenGL/compiler/ValidateLimitations.h b/src/OpenGL/compiler/ValidateLimitations.h
index fa8adb1..6e43e0c 100644
--- a/src/OpenGL/compiler/ValidateLimitations.h
+++ b/src/OpenGL/compiler/ValidateLimitations.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Compiler.h"
 #include "intermediate.h"
@@ -10,10 +18,10 @@
 class TInfoSinkBase;
 
 struct TLoopInfo {
-    struct TIndex {
-        int id;  // symbol id.
-    } index;
-    TIntermLoop* loop;
+	struct TIndex {
+		int id;  // symbol id.
+	} index;
+	TIntermLoop* loop;
 };
 typedef TVector<TLoopInfo> TLoopStack;
 
@@ -21,39 +29,39 @@
 // minimum functionality mandated in GLSL 1.0 spec, Appendix A.
 class ValidateLimitations : public TIntermTraverser {
 public:
-    ValidateLimitations(GLenum shaderType, TInfoSinkBase& sink);
+	ValidateLimitations(GLenum shaderType, TInfoSinkBase& sink);
 
-    int numErrors() const { return mNumErrors; }
+	int numErrors() const { return mNumErrors; }
 
-    virtual bool visitBinary(Visit, TIntermBinary*);
-    virtual bool visitUnary(Visit, TIntermUnary*);
-    virtual bool visitAggregate(Visit, TIntermAggregate*);
-    virtual bool visitLoop(Visit, TIntermLoop*);
+	virtual bool visitBinary(Visit, TIntermBinary*);
+	virtual bool visitUnary(Visit, TIntermUnary*);
+	virtual bool visitAggregate(Visit, TIntermAggregate*);
+	virtual bool visitLoop(Visit, TIntermLoop*);
 
 private:
-    void error(TSourceLoc loc, const char *reason, const char* token);
+	void error(TSourceLoc loc, const char *reason, const char* token);
 
-    bool withinLoopBody() const;
-    bool isLoopIndex(const TIntermSymbol* symbol) const;
-    bool validateLoopType(TIntermLoop* node);
-    bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
-    bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info);
-    bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info);
-    bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info);
-    // Returns true if none of the loop indices is used as the argument to
-    // the given function out or inout parameter.
-    bool validateFunctionCall(TIntermAggregate* node);
-    bool validateOperation(TIntermOperator* node, TIntermNode* operand);
+	bool withinLoopBody() const;
+	bool isLoopIndex(const TIntermSymbol* symbol) const;
+	bool validateLoopType(TIntermLoop* node);
+	bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
+	bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info);
+	bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info);
+	bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info);
+	// Returns true if none of the loop indices is used as the argument to
+	// the given function out or inout parameter.
+	bool validateFunctionCall(TIntermAggregate* node);
+	bool validateOperation(TIntermOperator* node, TIntermNode* operand);
 
-    // Returns true if indexing does not exceed the minimum functionality
-    // mandated in GLSL 1.0 spec, Appendix A, Section 5.
-    bool isConstExpr(TIntermNode* node);
-    bool isConstIndexExpr(TIntermNode* node);
-    bool validateIndexing(TIntermBinary* node);
+	// Returns true if indexing does not exceed the minimum functionality
+	// mandated in GLSL 1.0 spec, Appendix A, Section 5.
+	bool isConstExpr(TIntermNode* node);
+	bool isConstIndexExpr(TIntermNode* node);
+	bool validateIndexing(TIntermBinary* node);
 
-    GLenum mShaderType;
-    TInfoSinkBase& mSink;
-    int mNumErrors;
-    TLoopStack mLoopStack;
+	GLenum mShaderType;
+	TInfoSinkBase& mSink;
+	int mNumErrors;
+	TLoopStack mLoopStack;
 };
 
diff --git a/src/OpenGL/compiler/ValidateSwitch.cpp b/src/OpenGL/compiler/ValidateSwitch.cpp
index 982cc51..edef69b 100644
--- a/src/OpenGL/compiler/ValidateSwitch.cpp
+++ b/src/OpenGL/compiler/ValidateSwitch.cpp
@@ -1,200 +1,208 @@
-//

-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "ValidateSwitch.h"

-

-#include "ParseHelper.h"

-

-bool ValidateSwitch::validate(TBasicType switchType, TParseContext *context,

-    TIntermAggregate *statementList, const TSourceLoc &loc)

-{

-    ValidateSwitch validate(switchType, context);

-    ASSERT(statementList);

-    statementList->traverse(&validate);

-    return validate.validateInternal(loc);

-}

-

-ValidateSwitch::ValidateSwitch(TBasicType switchType, TParseContext *context)

-    : TIntermTraverser(true, false, true),

-      mSwitchType(switchType),

-      mContext(context),

-      mCaseTypeMismatch(false),

-      mFirstCaseFound(false),

-      mStatementBeforeCase(false),

-      mLastStatementWasCase(false),

-      mControlFlowDepth(0),

-      mCaseInsideControlFlow(false),

-      mDefaultCount(0),

-      mDuplicateCases(false)

-{}

-

-void ValidateSwitch::visitSymbol(TIntermSymbol *)

-{

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-}

-

-void ValidateSwitch::visitConstantUnion(TIntermConstantUnion *)

-{

-    // Conditions of case labels are not traversed, so this is some other constant

-    // Could be just a statement like "0;"

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-}

-

-bool ValidateSwitch::visitBinary(Visit, TIntermBinary *)

-{

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-    return true;

-}

-

-bool ValidateSwitch::visitUnary(Visit, TIntermUnary *)

-{

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-    return true;

-}

-

-bool ValidateSwitch::visitSelection(Visit visit, TIntermSelection *)

-{

-    if (visit == PreVisit)

-        ++mControlFlowDepth;

-    if (visit == PostVisit)

-        --mControlFlowDepth;

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-    return true;

-}

-

-bool ValidateSwitch::visitSwitch(Visit, TIntermSwitch *)

-{

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-    // Don't go into nested switch statements

-    return false;

-}

-

-bool ValidateSwitch::visitCase(Visit, TIntermCase *node)

-{

-    const char *nodeStr = node->hasCondition() ? "case" : "default";

-    if (mControlFlowDepth > 0)

-    {

-        mContext->error(node->getLine(), "label statement nested inside control flow", nodeStr);

-        mCaseInsideControlFlow = true;

-    }

-    mFirstCaseFound = true;

-    mLastStatementWasCase = true;

-    if (!node->hasCondition())

-    {

-        ++mDefaultCount;

-        if (mDefaultCount > 1)

-        {

-            mContext->error(node->getLine(), "duplicate default label", nodeStr);

-        }

-    }

-    else

-    {

-        TIntermConstantUnion *condition = node->getCondition()->getAsConstantUnion();

-        if (condition == nullptr)

-        {

-            // This can happen in error cases.

-            return false;

-        }

-        TBasicType conditionType = condition->getBasicType();

-        if (conditionType != mSwitchType)

-        {

-            mContext->error(condition->getLine(),

-                "case label type does not match switch init-expression type", nodeStr);

-            mCaseTypeMismatch = true;

-        }

-

-        if (conditionType == EbtInt)

-        {

-            int iConst = condition->getIConst(0);

-            if (mCasesSigned.find(iConst) != mCasesSigned.end())

-            {

-                mContext->error(condition->getLine(), "duplicate case label", nodeStr);

-                mDuplicateCases = true;

-            }

-            else

-            {

-                mCasesSigned.insert(iConst);

-            }

-        }

-        else if (conditionType == EbtUInt)

-        {

-            unsigned int uConst = condition->getUConst(0);

-            if (mCasesUnsigned.find(uConst) != mCasesUnsigned.end())

-            {

-                mContext->error(condition->getLine(), "duplicate case label", nodeStr);

-                mDuplicateCases = true;

-            }

-            else

-            {

-                mCasesUnsigned.insert(uConst);

-            }

-        }

-        // Other types are possible only in error cases, where the error has already been generated

-        // when parsing the case statement.

-    }

-    // Don't traverse the condition of the case statement

-    return false;

-}

-

-bool ValidateSwitch::visitAggregate(Visit visit, TIntermAggregate *)

-{

-    if (getParentNode() != nullptr)

-    {

-        // This is not the statementList node, but some other node.

-        if (!mFirstCaseFound)

-            mStatementBeforeCase = true;

-        mLastStatementWasCase = false;

-    }

-    return true;

-}

-

-bool ValidateSwitch::visitLoop(Visit visit, TIntermLoop *)

-{

-    if (visit == PreVisit)

-        ++mControlFlowDepth;

-    if (visit == PostVisit)

-        --mControlFlowDepth;

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-    return true;

-}

-

-bool ValidateSwitch::visitBranch(Visit, TIntermBranch *)

-{

-    if (!mFirstCaseFound)

-        mStatementBeforeCase = true;

-    mLastStatementWasCase = false;

-    return true;

-}

-

-bool ValidateSwitch::validateInternal(const TSourceLoc &loc)

-{

-    if (mStatementBeforeCase)

-    {

-        mContext->error(loc,

-            "statement before the first label", "switch");

-    }

-    if (mLastStatementWasCase)

-    {

-        mContext->error(loc,

-            "no statement between the last label and the end of the switch statement", "switch");

-    }

-    return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&

-        !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "ValidateSwitch.h"
+
+#include "ParseHelper.h"
+
+bool ValidateSwitch::validate(TBasicType switchType, TParseContext *context,
+	TIntermAggregate *statementList, const TSourceLoc &loc)
+{
+	ValidateSwitch validate(switchType, context);
+	ASSERT(statementList);
+	statementList->traverse(&validate);
+	return validate.validateInternal(loc);
+}
+
+ValidateSwitch::ValidateSwitch(TBasicType switchType, TParseContext *context)
+	: TIntermTraverser(true, false, true),
+	  mSwitchType(switchType),
+	  mContext(context),
+	  mCaseTypeMismatch(false),
+	  mFirstCaseFound(false),
+	  mStatementBeforeCase(false),
+	  mLastStatementWasCase(false),
+	  mControlFlowDepth(0),
+	  mCaseInsideControlFlow(false),
+	  mDefaultCount(0),
+	  mDuplicateCases(false)
+{}
+
+void ValidateSwitch::visitSymbol(TIntermSymbol *)
+{
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+}
+
+void ValidateSwitch::visitConstantUnion(TIntermConstantUnion *)
+{
+	// Conditions of case labels are not traversed, so this is some other constant
+	// Could be just a statement like "0;"
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+}
+
+bool ValidateSwitch::visitBinary(Visit, TIntermBinary *)
+{
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+	return true;
+}
+
+bool ValidateSwitch::visitUnary(Visit, TIntermUnary *)
+{
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+	return true;
+}
+
+bool ValidateSwitch::visitSelection(Visit visit, TIntermSelection *)
+{
+	if (visit == PreVisit)
+		++mControlFlowDepth;
+	if (visit == PostVisit)
+		--mControlFlowDepth;
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+	return true;
+}
+
+bool ValidateSwitch::visitSwitch(Visit, TIntermSwitch *)
+{
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+	// Don't go into nested switch statements
+	return false;
+}
+
+bool ValidateSwitch::visitCase(Visit, TIntermCase *node)
+{
+	const char *nodeStr = node->hasCondition() ? "case" : "default";
+	if (mControlFlowDepth > 0)
+	{
+		mContext->error(node->getLine(), "label statement nested inside control flow", nodeStr);
+		mCaseInsideControlFlow = true;
+	}
+	mFirstCaseFound = true;
+	mLastStatementWasCase = true;
+	if (!node->hasCondition())
+	{
+		++mDefaultCount;
+		if (mDefaultCount > 1)
+		{
+			mContext->error(node->getLine(), "duplicate default label", nodeStr);
+		}
+	}
+	else
+	{
+		TIntermConstantUnion *condition = node->getCondition()->getAsConstantUnion();
+		if (condition == nullptr)
+		{
+			// This can happen in error cases.
+			return false;
+		}
+		TBasicType conditionType = condition->getBasicType();
+		if (conditionType != mSwitchType)
+		{
+			mContext->error(condition->getLine(),
+				"case label type does not match switch init-expression type", nodeStr);
+			mCaseTypeMismatch = true;
+		}
+
+		if (conditionType == EbtInt)
+		{
+			int iConst = condition->getIConst(0);
+			if (mCasesSigned.find(iConst) != mCasesSigned.end())
+			{
+				mContext->error(condition->getLine(), "duplicate case label", nodeStr);
+				mDuplicateCases = true;
+			}
+			else
+			{
+				mCasesSigned.insert(iConst);
+			}
+		}
+		else if (conditionType == EbtUInt)
+		{
+			unsigned int uConst = condition->getUConst(0);
+			if (mCasesUnsigned.find(uConst) != mCasesUnsigned.end())
+			{
+				mContext->error(condition->getLine(), "duplicate case label", nodeStr);
+				mDuplicateCases = true;
+			}
+			else
+			{
+				mCasesUnsigned.insert(uConst);
+			}
+		}
+		// Other types are possible only in error cases, where the error has already been generated
+		// when parsing the case statement.
+	}
+	// Don't traverse the condition of the case statement
+	return false;
+}
+
+bool ValidateSwitch::visitAggregate(Visit visit, TIntermAggregate *)
+{
+	if (getParentNode() != nullptr)
+	{
+		// This is not the statementList node, but some other node.
+		if (!mFirstCaseFound)
+			mStatementBeforeCase = true;
+		mLastStatementWasCase = false;
+	}
+	return true;
+}
+
+bool ValidateSwitch::visitLoop(Visit visit, TIntermLoop *)
+{
+	if (visit == PreVisit)
+		++mControlFlowDepth;
+	if (visit == PostVisit)
+		--mControlFlowDepth;
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+	return true;
+}
+
+bool ValidateSwitch::visitBranch(Visit, TIntermBranch *)
+{
+	if (!mFirstCaseFound)
+		mStatementBeforeCase = true;
+	mLastStatementWasCase = false;
+	return true;
+}
+
+bool ValidateSwitch::validateInternal(const TSourceLoc &loc)
+{
+	if (mStatementBeforeCase)
+	{
+		mContext->error(loc,
+			"statement before the first label", "switch");
+	}
+	if (mLastStatementWasCase)
+	{
+		mContext->error(loc,
+			"no statement between the last label and the end of the switch statement", "switch");
+	}
+	return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
+		!mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;
+}
diff --git a/src/OpenGL/compiler/ValidateSwitch.h b/src/OpenGL/compiler/ValidateSwitch.h
index 7dcc5e5..1c36e33 100644
--- a/src/OpenGL/compiler/ValidateSwitch.h
+++ b/src/OpenGL/compiler/ValidateSwitch.h
@@ -1,53 +1,61 @@
-//

-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_TRANSLATOR_VALIDATESWITCH_H_

-#define COMPILER_TRANSLATOR_VALIDATESWITCH_H_

-

-#include "intermediate.h"

-#include <set>

-

-class TParseContext;

-

-class ValidateSwitch : public TIntermTraverser

-{

-  public:

-    // Check for errors and output messages any remaining errors on the context.

-    // Returns true if there are no errors.

-    static bool validate(TBasicType switchType, TParseContext *context,

-        TIntermAggregate *statementList, const TSourceLoc &loc);

-

-    void visitSymbol(TIntermSymbol *) override;

-    void visitConstantUnion(TIntermConstantUnion *) override;

-    bool visitBinary(Visit, TIntermBinary *) override;

-    bool visitUnary(Visit, TIntermUnary *) override;

-    bool visitSelection(Visit visit, TIntermSelection *) override;

-    bool visitSwitch(Visit, TIntermSwitch *) override;

-    bool visitCase(Visit, TIntermCase *) override;

-    bool visitAggregate(Visit, TIntermAggregate *) override;

-    bool visitLoop(Visit visit, TIntermLoop *) override;

-    bool visitBranch(Visit, TIntermBranch *) override;

-

-  private:

-    ValidateSwitch(TBasicType switchType, TParseContext *context);

-

-    bool validateInternal(const TSourceLoc &loc);

-

-    TBasicType mSwitchType;

-    TParseContext *mContext;

-    bool mCaseTypeMismatch;

-    bool mFirstCaseFound;

-    bool mStatementBeforeCase;

-    bool mLastStatementWasCase;

-    int mControlFlowDepth;

-    bool mCaseInsideControlFlow;

-    int mDefaultCount;

-    std::set<int> mCasesSigned;

-    std::set<unsigned int> mCasesUnsigned;

-    bool mDuplicateCases;

-};

-

-#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_TRANSLATOR_VALIDATESWITCH_H_
+#define COMPILER_TRANSLATOR_VALIDATESWITCH_H_
+
+#include "intermediate.h"
+#include <set>
+
+class TParseContext;
+
+class ValidateSwitch : public TIntermTraverser
+{
+public:
+	// Check for errors and output messages any remaining errors on the context.
+	// Returns true if there are no errors.
+	static bool validate(TBasicType switchType, TParseContext *context,
+	                     TIntermAggregate *statementList, const TSourceLoc &loc);
+
+	void visitSymbol(TIntermSymbol *) override;
+	void visitConstantUnion(TIntermConstantUnion *) override;
+	bool visitBinary(Visit, TIntermBinary *) override;
+	bool visitUnary(Visit, TIntermUnary *) override;
+	bool visitSelection(Visit visit, TIntermSelection *) override;
+	bool visitSwitch(Visit, TIntermSwitch *) override;
+	bool visitCase(Visit, TIntermCase *) override;
+	bool visitAggregate(Visit, TIntermAggregate *) override;
+	bool visitLoop(Visit visit, TIntermLoop *) override;
+	bool visitBranch(Visit, TIntermBranch *) override;
+
+private:
+	ValidateSwitch(TBasicType switchType, TParseContext *context);
+
+	bool validateInternal(const TSourceLoc &loc);
+
+	TBasicType mSwitchType;
+	TParseContext *mContext;
+	bool mCaseTypeMismatch;
+	bool mFirstCaseFound;
+	bool mStatementBeforeCase;
+	bool mLastStatementWasCase;
+	int mControlFlowDepth;
+	bool mCaseInsideControlFlow;
+	int mDefaultCount;
+	std::set<int> mCasesSigned;
+	std::set<unsigned int> mCasesUnsigned;
+	bool mDuplicateCases;
+};
+
+#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
diff --git a/src/OpenGL/compiler/debug.cpp b/src/OpenGL/compiler/debug.cpp
index e507ff6..b30632d 100644
--- a/src/OpenGL/compiler/debug.cpp
+++ b/src/OpenGL/compiler/debug.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // debug.cpp: Debugging utilities.
 
@@ -19,18 +27,18 @@
 #ifdef TRACE_ENABLED
 extern "C" {
 void Trace(const char *format, ...) {
-    if (!format) return;
+	if (!format) return;
 
-    TParseContext* parseContext = GetGlobalParseContext();
-    if (parseContext) {
-        char buf[kTraceBufferLen];
-        va_list args;
-        va_start(args, format);
-        vsnprintf(buf, kTraceBufferLen, format, args);
-        va_end(args);
+	TParseContext* parseContext = GetGlobalParseContext();
+	if (parseContext) {
+		char buf[kTraceBufferLen];
+		va_list args;
+		va_start(args, format);
+		vsnprintf(buf, kTraceBufferLen, format, args);
+		va_end(args);
 
-        parseContext->trace(buf);
-    }
+		parseContext->trace(buf);
+	}
 }
 }  // extern "C"
 #endif  // TRACE_ENABLED
diff --git a/src/OpenGL/compiler/debug.h b/src/OpenGL/compiler/debug.h
index 1b4a69b..2755d23 100644
--- a/src/OpenGL/compiler/debug.h
+++ b/src/OpenGL/compiler/debug.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // debug.h: Debugging utilities.
 
@@ -41,21 +49,21 @@
 // A macro asserting a condition and outputting failures to the debug log
 #undef ASSERT
 #define ASSERT(expression) do { \
-    if(!(expression)) \
-        Trace("Assert failed: %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
-    assert(expression); \
+	if(!(expression)) \
+		Trace("Assert failed: %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
+	assert(expression); \
 } while(0)
 
 #undef UNIMPLEMENTED
 #define UNIMPLEMENTED() do { \
-    Trace("Unimplemented invoked: %s(%d)\n", __FUNCTION__, __LINE__); \
-    assert(false); \
+	Trace("Unimplemented invoked: %s(%d)\n", __FUNCTION__, __LINE__); \
+	assert(false); \
 } while(0)
 
 #undef UNREACHABLE
 #define UNREACHABLE(value) do { \
-    Trace("Unreachable reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value); \
-    assert(false); \
+	Trace("Unreachable reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value); \
+	assert(false); \
 } while(0)
 
 #endif   // __ANDROID__
diff --git a/src/OpenGL/compiler/generate_parser.sh b/src/OpenGL/compiler/generate_parser.sh
index e472191..428b79b 100644
--- a/src/OpenGL/compiler/generate_parser.sh
+++ b/src/OpenGL/compiler/generate_parser.sh
@@ -1,7 +1,17 @@
 #!/bin/bash
-# Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# 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.
 
 # Generates GLSL ES parser - glslang_lex.cpp, glslang_tab.h, and glslang_tab.cpp
 
diff --git a/src/OpenGL/compiler/glslang.h b/src/OpenGL/compiler/glslang.h
index 98f760b..656ba18 100644
--- a/src/OpenGL/compiler/glslang.h
+++ b/src/OpenGL/compiler/glslang.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 class TParseContext;
 extern int glslang_initialize(TParseContext* context);
diff --git a/src/OpenGL/compiler/glslang.l b/src/OpenGL/compiler/glslang.l
index 0c51a97..9acc29a 100644
--- a/src/OpenGL/compiler/glslang.l
+++ b/src/OpenGL/compiler/glslang.l
@@ -1,9 +1,17 @@
 /*
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 This file contains the Lex specification for GLSL ES.
 Based on ANSI C grammar, Lex specification:
@@ -14,11 +22,19 @@
 */
 
 %top{
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
diff --git a/src/OpenGL/compiler/glslang.y b/src/OpenGL/compiler/glslang.y
index 3030144..c7e8f28 100644
--- a/src/OpenGL/compiler/glslang.y
+++ b/src/OpenGL/compiler/glslang.y
@@ -1,9 +1,17 @@
 /*
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 This file contains the Yacc grammar for GLSL ES.
 Based on ANSI C Yacc grammar:
@@ -14,11 +22,19 @@
 */
 
 %{
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
diff --git a/src/OpenGL/compiler/glslang_lex.cpp b/src/OpenGL/compiler/glslang_lex.cpp
index 91c1310..155605c 100644
--- a/src/OpenGL/compiler/glslang_lex.cpp
+++ b/src/OpenGL/compiler/glslang_lex.cpp
@@ -1,9 +1,17 @@
 #line 17 "./glslang.l"
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
@@ -1019,11 +1027,19 @@
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
 /*
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 This file contains the Lex specification for GLSL ES.
 Based on ANSI C grammar, Lex specification:
diff --git a/src/OpenGL/compiler/glslang_tab.cpp b/src/OpenGL/compiler/glslang_tab.cpp
index 2e23afe..e4f4952 100644
--- a/src/OpenGL/compiler/glslang_tab.cpp
+++ b/src/OpenGL/compiler/glslang_tab.cpp
@@ -64,11 +64,19 @@
 /* Copy the first part of user declarations.  */
 
 
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
diff --git a/src/OpenGL/compiler/intermOut.cpp b/src/OpenGL/compiler/intermOut.cpp
index 0b219b9..704f40e 100644
--- a/src/OpenGL/compiler/intermOut.cpp
+++ b/src/OpenGL/compiler/intermOut.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "localintermediate.h"
 #include "SymbolTable.h"
@@ -22,35 +30,35 @@
 //
 class TOutputTraverser : public TIntermTraverser {
 public:
-    TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
-    TInfoSinkBase& sink;
+	TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
+	TInfoSinkBase& sink;
 
 protected:
-    void visitSymbol(TIntermSymbol*);
-    void visitConstantUnion(TIntermConstantUnion*);
-    bool visitBinary(Visit visit, TIntermBinary*);
-    bool visitUnary(Visit visit, TIntermUnary*);
-    bool visitSelection(Visit visit, TIntermSelection*);
-    bool visitAggregate(Visit visit, TIntermAggregate*);
-    bool visitLoop(Visit visit, TIntermLoop*);
-    bool visitBranch(Visit visit, TIntermBranch*);
+	void visitSymbol(TIntermSymbol*);
+	void visitConstantUnion(TIntermConstantUnion*);
+	bool visitBinary(Visit visit, TIntermBinary*);
+	bool visitUnary(Visit visit, TIntermUnary*);
+	bool visitSelection(Visit visit, TIntermSelection*);
+	bool visitAggregate(Visit visit, TIntermAggregate*);
+	bool visitLoop(Visit visit, TIntermLoop*);
+	bool visitBranch(Visit visit, TIntermBranch*);
 };
 
 TString TType::getCompleteString() const
 {
-    TStringStream stream;
+	TStringStream stream;
 
-    if (qualifier != EvqTemporary && qualifier != EvqGlobal)
-        stream << getQualifierString() << " " << getPrecisionString() << " ";
-    if (array)
-        stream << "array of ";
-    if (isMatrix())
+	if (qualifier != EvqTemporary && qualifier != EvqGlobal)
+		stream << getQualifierString() << " " << getPrecisionString() << " ";
+	if (array)
+		stream << "array of ";
+	if (isMatrix())
 		stream << static_cast<int>(primarySize) << "X" << static_cast<int>(secondarySize) << " matrix of ";
 	else if(primarySize > 1)
 		stream << static_cast<int>(primarySize) << "-component vector of ";
 
-    stream << getBasicString();
-    return stream.str();
+	stream << getBasicString();
+	return stream.str();
 }
 
 //
@@ -59,12 +67,12 @@
 
 void OutputTreeText(TInfoSinkBase& sink, TIntermNode* node, const int depth)
 {
-    int i;
+	int i;
 
-    sink.location(node->getLine());
+	sink.location(node->getLine());
 
-    for (i = 0; i < depth; ++i)
-        sink << "  ";
+	for (i = 0; i < depth; ++i)
+		sink << "  ";
 }
 
 //
@@ -78,372 +86,372 @@
 
 void TOutputTraverser::visitSymbol(TIntermSymbol* node)
 {
-    OutputTreeText(sink, node, mDepth);
+	OutputTreeText(sink, node, mDepth);
 
-    sink << "'" << node->getSymbol() << "' ";
-    sink << "(" << node->getCompleteString() << ")\n";
+	sink << "'" << node->getSymbol() << "' ";
+	sink << "(" << node->getCompleteString() << ")\n";
 }
 
 bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
 {
-    TInfoSinkBase& out = sink;
+	TInfoSinkBase& out = sink;
 
-    OutputTreeText(out, node, mDepth);
+	OutputTreeText(out, node, mDepth);
 
-    switch (node->getOp()) {
-        case EOpAssign:                   out << "move second child to first child";           break;
-        case EOpInitialize:               out << "initialize first child with second child";   break;
-        case EOpAddAssign:                out << "add second child into first child";          break;
-        case EOpSubAssign:                out << "subtract second child into first child";     break;
-        case EOpMulAssign:                out << "multiply second child into first child";     break;
-        case EOpVectorTimesMatrixAssign:  out << "matrix mult second child into first child";  break;
-        case EOpVectorTimesScalarAssign:  out << "vector scale second child into first child"; break;
-        case EOpMatrixTimesScalarAssign:  out << "matrix scale second child into first child"; break;
-        case EOpMatrixTimesMatrixAssign:  out << "matrix mult second child into first child";  break;
-        case EOpDivAssign:                out << "divide second child into first child";       break;
-        case EOpIModAssign:               out << "modulo second child into first child";       break;
-        case EOpBitShiftLeftAssign:       out << "bit-wise shift first child left by second child";  break;
-        case EOpBitShiftRightAssign:      out << "bit-wise shift first child right by second child"; break;
-        case EOpBitwiseAndAssign:         out << "bit-wise and second child into first child"; break;
-        case EOpBitwiseXorAssign:         out << "bit-wise xor second child into first child"; break;
-        case EOpBitwiseOrAssign:          out << "bit-wise or second child into first child";  break;
-        case EOpIndexDirect:   out << "direct index";   break;
-        case EOpIndexIndirect: out << "indirect index"; break;
-        case EOpIndexDirectStruct:   out << "direct index for structure";   break;
-        case EOpVectorSwizzle: out << "vector swizzle"; break;
+	switch (node->getOp()) {
+	case EOpAssign:                   out << "move second child to first child";           break;
+	case EOpInitialize:               out << "initialize first child with second child";   break;
+	case EOpAddAssign:                out << "add second child into first child";          break;
+	case EOpSubAssign:                out << "subtract second child into first child";     break;
+	case EOpMulAssign:                out << "multiply second child into first child";     break;
+	case EOpVectorTimesMatrixAssign:  out << "matrix mult second child into first child";  break;
+	case EOpVectorTimesScalarAssign:  out << "vector scale second child into first child"; break;
+	case EOpMatrixTimesScalarAssign:  out << "matrix scale second child into first child"; break;
+	case EOpMatrixTimesMatrixAssign:  out << "matrix mult second child into first child";  break;
+	case EOpDivAssign:                out << "divide second child into first child";       break;
+	case EOpIModAssign:               out << "modulo second child into first child";       break;
+	case EOpBitShiftLeftAssign:       out << "bit-wise shift first child left by second child";  break;
+	case EOpBitShiftRightAssign:      out << "bit-wise shift first child right by second child"; break;
+	case EOpBitwiseAndAssign:         out << "bit-wise and second child into first child"; break;
+	case EOpBitwiseXorAssign:         out << "bit-wise xor second child into first child"; break;
+	case EOpBitwiseOrAssign:          out << "bit-wise or second child into first child";  break;
+	case EOpIndexDirect:   out << "direct index";   break;
+	case EOpIndexIndirect: out << "indirect index"; break;
+	case EOpIndexDirectStruct:   out << "direct index for structure";   break;
+	case EOpVectorSwizzle: out << "vector swizzle"; break;
 
-        case EOpAdd:    out << "add";                     break;
-        case EOpSub:    out << "subtract";                break;
-        case EOpMul:    out << "component-wise multiply"; break;
-        case EOpDiv:    out << "divide";                  break;
-        case EOpIMod:   out << "modulo";                  break;
-        case EOpBitShiftLeft:     out << "bit-wise shift left";           break;
-        case EOpBitShiftRight:    out << "bit-wise shift right";          break;
-        case EOpBitwiseAnd:       out << "bit-wise and";                  break;
-        case EOpBitwiseXor:       out << "bit-wise xor";                  break;
-        case EOpBitwiseOr:        out << "bit-wise or";                   break;
-        case EOpEqual:            out << "Compare Equal";                 break;
-        case EOpNotEqual:         out << "Compare Not Equal";             break;
-        case EOpLessThan:         out << "Compare Less Than";             break;
-        case EOpGreaterThan:      out << "Compare Greater Than";          break;
-        case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
-        case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
+	case EOpAdd:    out << "add";                     break;
+	case EOpSub:    out << "subtract";                break;
+	case EOpMul:    out << "component-wise multiply"; break;
+	case EOpDiv:    out << "divide";                  break;
+	case EOpIMod:   out << "modulo";                  break;
+	case EOpBitShiftLeft:     out << "bit-wise shift left";           break;
+	case EOpBitShiftRight:    out << "bit-wise shift right";          break;
+	case EOpBitwiseAnd:       out << "bit-wise and";                  break;
+	case EOpBitwiseXor:       out << "bit-wise xor";                  break;
+	case EOpBitwiseOr:        out << "bit-wise or";                   break;
+	case EOpEqual:            out << "Compare Equal";                 break;
+	case EOpNotEqual:         out << "Compare Not Equal";             break;
+	case EOpLessThan:         out << "Compare Less Than";             break;
+	case EOpGreaterThan:      out << "Compare Greater Than";          break;
+	case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
+	case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
 
-        case EOpVectorTimesScalar: out << "vector-scale";          break;
-        case EOpVectorTimesMatrix: out << "vector-times-matrix";   break;
-        case EOpMatrixTimesVector: out << "matrix-times-vector";   break;
-        case EOpMatrixTimesScalar: out << "matrix-scale";          break;
-        case EOpMatrixTimesMatrix: out << "matrix-multiply";       break;
+	case EOpVectorTimesScalar: out << "vector-scale";          break;
+	case EOpVectorTimesMatrix: out << "vector-times-matrix";   break;
+	case EOpMatrixTimesVector: out << "matrix-times-vector";   break;
+	case EOpMatrixTimesScalar: out << "matrix-scale";          break;
+	case EOpMatrixTimesMatrix: out << "matrix-multiply";       break;
 
-        case EOpLogicalOr:  out << "logical-or";   break;
-        case EOpLogicalXor: out << "logical-xor"; break;
-        case EOpLogicalAnd: out << "logical-and"; break;
-        default: out << "<unknown op>";
-    }
+	case EOpLogicalOr:  out << "logical-or";   break;
+	case EOpLogicalXor: out << "logical-xor"; break;
+	case EOpLogicalAnd: out << "logical-and"; break;
+	default: out << "<unknown op>";
+	}
 
-    out << " (" << node->getCompleteString() << ")";
+	out << " (" << node->getCompleteString() << ")";
 
-    out << "\n";
+	out << "\n";
 
-    return true;
+	return true;
 }
 
 bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
 {
-    TInfoSinkBase& out = sink;
+	TInfoSinkBase& out = sink;
 
-    OutputTreeText(out, node, mDepth);
+	OutputTreeText(out, node, mDepth);
 
-    switch (node->getOp()) {
-        case EOpNegative:       out << "Negate value";         break;
-        case EOpVectorLogicalNot:
-        case EOpLogicalNot:     out << "Negate conditional";   break;
-        case EOpBitwiseNot:     out << "bit-wise not";         break;
+	switch (node->getOp()) {
+	case EOpNegative:       out << "Negate value";         break;
+	case EOpVectorLogicalNot:
+	case EOpLogicalNot:     out << "Negate conditional";   break;
+	case EOpBitwiseNot:     out << "bit-wise not";         break;
 
-        case EOpPostIncrement:  out << "Post-Increment";       break;
-        case EOpPostDecrement:  out << "Post-Decrement";       break;
-        case EOpPreIncrement:   out << "Pre-Increment";        break;
-        case EOpPreDecrement:   out << "Pre-Decrement";        break;
+	case EOpPostIncrement:  out << "Post-Increment";       break;
+	case EOpPostDecrement:  out << "Post-Decrement";       break;
+	case EOpPreIncrement:   out << "Pre-Increment";        break;
+	case EOpPreDecrement:   out << "Pre-Decrement";        break;
 
-        case EOpRadians:        out << "radians";              break;
-        case EOpDegrees:        out << "degrees";              break;
-        case EOpSin:            out << "sine";                 break;
-        case EOpCos:            out << "cosine";               break;
-        case EOpTan:            out << "tangent";              break;
-        case EOpAsin:           out << "arc sine";             break;
-        case EOpAcos:           out << "arc cosine";           break;
-        case EOpAtan:           out << "arc tangent";          break;
-        case EOpSinh:           out << "hyperbolic sine";        break;
-        case EOpCosh:           out << "hyperbolic cosine";      break;
-        case EOpTanh:           out << "hyperbolic tangent";     break;
-        case EOpAsinh:          out << "arc hyperbolic sine";    break;
-        case EOpAcosh:          out << "arc hyperbolic cosine";  break;
-        case EOpAtanh:          out << "arc hyperbolic tangent"; break;
+	case EOpRadians:        out << "radians";              break;
+	case EOpDegrees:        out << "degrees";              break;
+	case EOpSin:            out << "sine";                 break;
+	case EOpCos:            out << "cosine";               break;
+	case EOpTan:            out << "tangent";              break;
+	case EOpAsin:           out << "arc sine";             break;
+	case EOpAcos:           out << "arc cosine";           break;
+	case EOpAtan:           out << "arc tangent";          break;
+	case EOpSinh:           out << "hyperbolic sine";        break;
+	case EOpCosh:           out << "hyperbolic cosine";      break;
+	case EOpTanh:           out << "hyperbolic tangent";     break;
+	case EOpAsinh:          out << "arc hyperbolic sine";    break;
+	case EOpAcosh:          out << "arc hyperbolic cosine";  break;
+	case EOpAtanh:          out << "arc hyperbolic tangent"; break;
 
-        case EOpExp:            out << "exp";                  break;
-        case EOpLog:            out << "log";                  break;
-        case EOpExp2:           out << "exp2";                 break;
-        case EOpLog2:           out << "log2";                 break;
-        case EOpSqrt:           out << "sqrt";                 break;
-        case EOpInverseSqrt:    out << "inverse sqrt";         break;
+	case EOpExp:            out << "exp";                  break;
+	case EOpLog:            out << "log";                  break;
+	case EOpExp2:           out << "exp2";                 break;
+	case EOpLog2:           out << "log2";                 break;
+	case EOpSqrt:           out << "sqrt";                 break;
+	case EOpInverseSqrt:    out << "inverse sqrt";         break;
 
-        case EOpAbs:            out << "Absolute value";       break;
-        case EOpSign:           out << "Sign";                 break;
-        case EOpFloor:          out << "Floor";                break;
-        case EOpTrunc:          out << "Trunc";                break;
-        case EOpRound:          out << "Round";                break;
-        case EOpRoundEven:      out << "RoundEven";            break;
-        case EOpCeil:           out << "Ceiling";              break;
-        case EOpFract:          out << "Fraction";             break;
-        case EOpIsNan:          out << "Is not a number";      break;
-        case EOpIsInf:          out << "Is infinity";          break;
+	case EOpAbs:            out << "Absolute value";       break;
+	case EOpSign:           out << "Sign";                 break;
+	case EOpFloor:          out << "Floor";                break;
+	case EOpTrunc:          out << "Trunc";                break;
+	case EOpRound:          out << "Round";                break;
+	case EOpRoundEven:      out << "RoundEven";            break;
+	case EOpCeil:           out << "Ceiling";              break;
+	case EOpFract:          out << "Fraction";             break;
+	case EOpIsNan:          out << "Is not a number";      break;
+	case EOpIsInf:          out << "Is infinity";          break;
 
-        case EOpFloatBitsToInt: out << "float bits to int";    break;
-        case EOpFloatBitsToUint: out << "float bits to uint";  break;
-        case EOpIntBitsToFloat: out << "int bits to float";    break;
-        case EOpUintBitsToFloat: out << "uint bits to float";  break;
+	case EOpFloatBitsToInt: out << "float bits to int";    break;
+	case EOpFloatBitsToUint: out << "float bits to uint";  break;
+	case EOpIntBitsToFloat: out << "int bits to float";    break;
+	case EOpUintBitsToFloat: out << "uint bits to float";  break;
 
-        case EOpPackSnorm2x16:  out << "pack Snorm 2x16";      break;
-        case EOpPackUnorm2x16:  out << "pack Unorm 2x16";      break;
-        case EOpPackHalf2x16:   out << "pack half 2x16";       break;
+	case EOpPackSnorm2x16:  out << "pack Snorm 2x16";      break;
+	case EOpPackUnorm2x16:  out << "pack Unorm 2x16";      break;
+	case EOpPackHalf2x16:   out << "pack half 2x16";       break;
 
-        case EOpUnpackSnorm2x16: out << "unpack Snorm 2x16";   break;
-        case EOpUnpackUnorm2x16: out << "unpack Unorm 2x16";   break;
-        case EOpUnpackHalf2x16:  out << "unpack half 2x16";    break;
+	case EOpUnpackSnorm2x16: out << "unpack Snorm 2x16";   break;
+	case EOpUnpackUnorm2x16: out << "unpack Unorm 2x16";   break;
+	case EOpUnpackHalf2x16:  out << "unpack half 2x16";    break;
 
-        case EOpLength:         out << "length";               break;
-        case EOpNormalize:      out << "normalize";            break;
-            //	case EOpDPdx:           out << "dPdx";                 break;               
-            //	case EOpDPdy:           out << "dPdy";                 break;   
-            //	case EOpFwidth:         out << "fwidth";               break;                   
+	case EOpLength:         out << "length";               break;
+	case EOpNormalize:      out << "normalize";            break;
+		//	case EOpDPdx:           out << "dPdx";                 break;               
+		//	case EOpDPdy:           out << "dPdy";                 break;   
+		//	case EOpFwidth:         out << "fwidth";               break;                   
 
-        case EOpDeterminant:    out << "determinant";          break;
-        case EOpTranspose:      out << "transpose";            break;
-        case EOpInverse:        out << "inverse";              break;
+	case EOpDeterminant:    out << "determinant";          break;
+	case EOpTranspose:      out << "transpose";            break;
+	case EOpInverse:        out << "inverse";              break;
 
-        case EOpAny:            out << "any";                  break;
-        case EOpAll:            out << "all";                  break;
+	case EOpAny:            out << "any";                  break;
+	case EOpAll:            out << "all";                  break;
 
-        default: out.message(EPrefixError, "Bad unary op");
-    }
+	default: out.message(EPrefixError, "Bad unary op");
+	}
 
-    out << " (" << node->getCompleteString() << ")";
+	out << " (" << node->getCompleteString() << ")";
 
-    out << "\n";
+	out << "\n";
 
-    return true;
+	return true;
 }
 
 bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
 {
-    TInfoSinkBase& out = sink;
+	TInfoSinkBase& out = sink;
 
-    if (node->getOp() == EOpNull) {
-        out.message(EPrefixError, "node is still EOpNull!");
-        return true;
-    }
+	if (node->getOp() == EOpNull) {
+		out.message(EPrefixError, "node is still EOpNull!");
+		return true;
+	}
 
-    OutputTreeText(out, node, mDepth);
+	OutputTreeText(out, node, mDepth);
 
-    switch (node->getOp()) {
-        case EOpSequence:      out << "Sequence\n"; return true;
-        case EOpComma:         out << "Comma\n"; return true;
-        case EOpFunction:      out << "Function Definition: " << node->getName(); break;
-        case EOpFunctionCall:  out << "Function Call: " << node->getName(); break;
-        case EOpParameters:    out << "Function Parameters: ";              break;
+	switch (node->getOp()) {
+	case EOpSequence:      out << "Sequence\n"; return true;
+	case EOpComma:         out << "Comma\n"; return true;
+	case EOpFunction:      out << "Function Definition: " << node->getName(); break;
+	case EOpFunctionCall:  out << "Function Call: " << node->getName(); break;
+	case EOpParameters:    out << "Function Parameters: ";              break;
 
-        case EOpConstructFloat: out << "Construct float"; break;
-        case EOpConstructVec2:  out << "Construct vec2";  break;
-        case EOpConstructVec3:  out << "Construct vec3";  break;
-        case EOpConstructVec4:  out << "Construct vec4";  break;
-        case EOpConstructBool:  out << "Construct bool";  break;
-        case EOpConstructBVec2: out << "Construct bvec2"; break;
-        case EOpConstructBVec3: out << "Construct bvec3"; break;
-        case EOpConstructBVec4: out << "Construct bvec4"; break;
-        case EOpConstructInt:   out << "Construct int";   break;
-        case EOpConstructIVec2: out << "Construct ivec2"; break;
-        case EOpConstructIVec3: out << "Construct ivec3"; break;
-        case EOpConstructIVec4: out << "Construct ivec4"; break;
-        case EOpConstructUInt:  out << "Construct uint";  break;
-        case EOpConstructUVec2: out << "Construct uvec2"; break;
-        case EOpConstructUVec3: out << "Construct uvec3"; break;
-        case EOpConstructUVec4: out << "Construct uvec4"; break;
-        case EOpConstructMat2:  out << "Construct mat2";  break;
-        case EOpConstructMat3:  out << "Construct mat3";  break;
-        case EOpConstructMat4:  out << "Construct mat4";  break;
-        case EOpConstructStruct:  out << "Construct structure";  break;
+	case EOpConstructFloat: out << "Construct float"; break;
+	case EOpConstructVec2:  out << "Construct vec2";  break;
+	case EOpConstructVec3:  out << "Construct vec3";  break;
+	case EOpConstructVec4:  out << "Construct vec4";  break;
+	case EOpConstructBool:  out << "Construct bool";  break;
+	case EOpConstructBVec2: out << "Construct bvec2"; break;
+	case EOpConstructBVec3: out << "Construct bvec3"; break;
+	case EOpConstructBVec4: out << "Construct bvec4"; break;
+	case EOpConstructInt:   out << "Construct int";   break;
+	case EOpConstructIVec2: out << "Construct ivec2"; break;
+	case EOpConstructIVec3: out << "Construct ivec3"; break;
+	case EOpConstructIVec4: out << "Construct ivec4"; break;
+	case EOpConstructUInt:  out << "Construct uint";  break;
+	case EOpConstructUVec2: out << "Construct uvec2"; break;
+	case EOpConstructUVec3: out << "Construct uvec3"; break;
+	case EOpConstructUVec4: out << "Construct uvec4"; break;
+	case EOpConstructMat2:  out << "Construct mat2";  break;
+	case EOpConstructMat3:  out << "Construct mat3";  break;
+	case EOpConstructMat4:  out << "Construct mat4";  break;
+	case EOpConstructStruct:  out << "Construct structure";  break;
 
-        case EOpLessThan:         out << "Compare Less Than";             break;
-        case EOpGreaterThan:      out << "Compare Greater Than";          break;
-        case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
-        case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
-        case EOpVectorEqual:      out << "Equal";                         break;
-        case EOpVectorNotEqual:   out << "NotEqual";                      break;
+	case EOpLessThan:         out << "Compare Less Than";             break;
+	case EOpGreaterThan:      out << "Compare Greater Than";          break;
+	case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
+	case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
+	case EOpVectorEqual:      out << "Equal";                         break;
+	case EOpVectorNotEqual:   out << "NotEqual";                      break;
 
-        case EOpMod:           out << "mod";         break;
-        case EOpModf:          out << "modf";        break;
-        case EOpPow:           out << "pow";         break;
+	case EOpMod:           out << "mod";         break;
+	case EOpModf:          out << "modf";        break;
+	case EOpPow:           out << "pow";         break;
 
-        case EOpAtan:          out << "arc tangent"; break;
+	case EOpAtan:          out << "arc tangent"; break;
 
-        case EOpMin:           out << "min";         break;
-        case EOpMax:           out << "max";         break;
-        case EOpClamp:         out << "clamp";       break;
-        case EOpMix:           out << "mix";         break;
-        case EOpStep:          out << "step";        break;
-        case EOpSmoothStep:    out << "smoothstep";  break;
+	case EOpMin:           out << "min";         break;
+	case EOpMax:           out << "max";         break;
+	case EOpClamp:         out << "clamp";       break;
+	case EOpMix:           out << "mix";         break;
+	case EOpStep:          out << "step";        break;
+	case EOpSmoothStep:    out << "smoothstep";  break;
 
-        case EOpDistance:      out << "distance";                break;
-        case EOpDot:           out << "dot-product";             break;
-        case EOpCross:         out << "cross-product";           break;
-        case EOpFaceForward:   out << "face-forward";            break;
-        case EOpReflect:       out << "reflect";                 break;
-        case EOpRefract:       out << "refract";                 break;
-        case EOpMul:           out << "component-wise multiply"; break;
-        case EOpOuterProduct:  out << "outer product";           break;
+	case EOpDistance:      out << "distance";                break;
+	case EOpDot:           out << "dot-product";             break;
+	case EOpCross:         out << "cross-product";           break;
+	case EOpFaceForward:   out << "face-forward";            break;
+	case EOpReflect:       out << "reflect";                 break;
+	case EOpRefract:       out << "refract";                 break;
+	case EOpMul:           out << "component-wise multiply"; break;
+	case EOpOuterProduct:  out << "outer product";           break;
 
-        default: out.message(EPrefixError, "Bad aggregation op");
-    }
+	default: out.message(EPrefixError, "Bad aggregation op");
+	}
 
-    if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
-        out << " (" << node->getCompleteString() << ")";
+	if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
+		out << " (" << node->getCompleteString() << ")";
 
-    out << "\n";
+	out << "\n";
 
-    return true;
+	return true;
 }
 
 bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
 {
-    TInfoSinkBase& out = sink;
+	TInfoSinkBase& out = sink;
 
-    OutputTreeText(out, node, mDepth);
+	OutputTreeText(out, node, mDepth);
 
-    out << "Test condition and select";
-    out << " (" << node->getCompleteString() << ")\n";
+	out << "Test condition and select";
+	out << " (" << node->getCompleteString() << ")\n";
 
-    ++mDepth;
+	++mDepth;
 
-    OutputTreeText(sink, node, mDepth);
-    out << "Condition\n";
-    node->getCondition()->traverse(this);
+	OutputTreeText(sink, node, mDepth);
+	out << "Condition\n";
+	node->getCondition()->traverse(this);
 
-    OutputTreeText(sink, node, mDepth);
-    if (node->getTrueBlock()) {
-        out << "true case\n";
-        node->getTrueBlock()->traverse(this);
-    } else
-        out << "true case is null\n";
+	OutputTreeText(sink, node, mDepth);
+	if (node->getTrueBlock()) {
+		out << "true case\n";
+		node->getTrueBlock()->traverse(this);
+	} else
+		out << "true case is null\n";
 
-    if (node->getFalseBlock()) {
-        OutputTreeText(sink, node, mDepth);
-        out << "false case\n";
-        node->getFalseBlock()->traverse(this);
-    }
+	if (node->getFalseBlock()) {
+		OutputTreeText(sink, node, mDepth);
+		out << "false case\n";
+		node->getFalseBlock()->traverse(this);
+	}
 
-    --mDepth;
+	--mDepth;
 
-    return false;
+	return false;
 }
 
 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
 {
-    TInfoSinkBase& out = sink;
+	TInfoSinkBase& out = sink;
 
-    size_t size = node->getType().getObjectSize();
+	size_t size = node->getType().getObjectSize();
 
-    for(size_t i = 0; i < size; i++) {
-        OutputTreeText(out, node, mDepth);
-        switch (node->getUnionArrayPointer()[i].getType()) {
-            case EbtBool:
-                if (node->getUnionArrayPointer()[i].getBConst())
-                    out << "true";
-                else
-                    out << "false";
+	for(size_t i = 0; i < size; i++) {
+		OutputTreeText(out, node, mDepth);
+		switch (node->getUnionArrayPointer()[i].getType()) {
+		case EbtBool:
+			if (node->getUnionArrayPointer()[i].getBConst())
+				out << "true";
+			else
+				out << "false";
 
-                out << " (" << "const bool" << ")";
-                out << "\n";
-                break;
-            case EbtFloat:
-                out << node->getUnionArrayPointer()[i].getFConst();
-                out << " (const float)\n";
-                break;
-            case EbtInt:
-                out << node->getUnionArrayPointer()[i].getIConst();
-                out << " (const int)\n";
-                break;
-            case EbtUInt:
-                out << node->getUnionArrayPointer()[i].getUConst();
-                out << " (const uint)\n";
-                break;
-            default:
-                out.message(EPrefixInternalError, "Unknown constant", node->getLine());
-                break;
-        }
-    }
+			out << " (" << "const bool" << ")";
+			out << "\n";
+			break;
+		case EbtFloat:
+			out << node->getUnionArrayPointer()[i].getFConst();
+			out << " (const float)\n";
+			break;
+		case EbtInt:
+			out << node->getUnionArrayPointer()[i].getIConst();
+			out << " (const int)\n";
+			break;
+		case EbtUInt:
+			out << node->getUnionArrayPointer()[i].getUConst();
+			out << " (const uint)\n";
+			break;
+		default:
+			out.message(EPrefixInternalError, "Unknown constant", node->getLine());
+			break;
+		}
+	}
 }
 
 bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
 {
-    TInfoSinkBase& out = sink;
+	TInfoSinkBase& out = sink;
 
-    OutputTreeText(out, node, mDepth);
+	OutputTreeText(out, node, mDepth);
 
-    out << "Loop with condition ";
-    if (node->getType() == ELoopDoWhile)
-        out << "not ";
-    out << "tested first\n";
+	out << "Loop with condition ";
+	if (node->getType() == ELoopDoWhile)
+		out << "not ";
+	out << "tested first\n";
 
-    ++mDepth;
+	++mDepth;
 
-    OutputTreeText(sink, node, mDepth);
-    if (node->getCondition()) {
-        out << "Loop Condition\n";
-        node->getCondition()->traverse(this);
-    } else
-        out << "No loop condition\n";
+	OutputTreeText(sink, node, mDepth);
+	if (node->getCondition()) {
+		out << "Loop Condition\n";
+		node->getCondition()->traverse(this);
+	} else
+		out << "No loop condition\n";
 
-    OutputTreeText(sink, node, mDepth);
-    if (node->getBody()) {
-        out << "Loop Body\n";
-        node->getBody()->traverse(this);
-    } else
-        out << "No loop body\n";
+	OutputTreeText(sink, node, mDepth);
+	if (node->getBody()) {
+		out << "Loop Body\n";
+		node->getBody()->traverse(this);
+	} else
+		out << "No loop body\n";
 
-    if (node->getExpression()) {
-        OutputTreeText(sink, node, mDepth);
-        out << "Loop Terminal Expression\n";
-        node->getExpression()->traverse(this);
-    }
+	if (node->getExpression()) {
+		OutputTreeText(sink, node, mDepth);
+		out << "Loop Terminal Expression\n";
+		node->getExpression()->traverse(this);
+	}
 
-    --mDepth;
+	--mDepth;
 
-    return false;
+	return false;
 }
 
 bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
 {
-    TInfoSinkBase& out = sink;
+	TInfoSinkBase& out = sink;
 
-    OutputTreeText(out, node, mDepth);
+	OutputTreeText(out, node, mDepth);
 
-    switch (node->getFlowOp()) {
-        case EOpKill:      out << "Branch: Kill";           break;
-        case EOpBreak:     out << "Branch: Break";          break;
-        case EOpContinue:  out << "Branch: Continue";       break;
-        case EOpReturn:    out << "Branch: Return";         break;
-        default:           out << "Branch: Unknown Branch"; break;
-    }
+	switch (node->getFlowOp()) {
+	case EOpKill:      out << "Branch: Kill";           break;
+	case EOpBreak:     out << "Branch: Break";          break;
+	case EOpContinue:  out << "Branch: Continue";       break;
+	case EOpReturn:    out << "Branch: Return";         break;
+	default:           out << "Branch: Unknown Branch"; break;
+	}
 
-    if (node->getExpression()) {
-        out << " with expression\n";
-        ++mDepth;
-        node->getExpression()->traverse(this);
-        --mDepth;
-    } else
-        out << "\n";
+	if (node->getExpression()) {
+		out << " with expression\n";
+		++mDepth;
+		node->getExpression()->traverse(this);
+		--mDepth;
+	} else
+		out << "\n";
 
-    return false;
+	return false;
 }
 
 //
@@ -453,10 +461,10 @@
 //
 void TIntermediate::outputTree(TIntermNode* root)
 {
-    if (root == 0)
-        return;
+	if (root == 0)
+		return;
 
-    TOutputTraverser it(infoSink.info);
+	TOutputTraverser it(infoSink.info);
 
-    root->traverse(&it);
+	root->traverse(&it);
 }
diff --git a/src/OpenGL/compiler/intermediate.h b/src/OpenGL/compiler/intermediate.h
index 7db04f4..3e0d876 100644
--- a/src/OpenGL/compiler/intermediate.h
+++ b/src/OpenGL/compiler/intermediate.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 //
 // Definition of the in-memory high-level intermediate representation
@@ -24,210 +32,210 @@
 // Operators used by the high-level (parse tree) representation.
 //
 enum TOperator {
-    EOpNull,            // if in a node, should only mean a node is still being built
-    EOpSequence,        // denotes a list of statements, or parameters, etc.
-    EOpFunctionCall,
-    EOpFunction,        // For function definition
-    EOpParameters,      // an aggregate listing the parameters to a function
+	EOpNull,            // if in a node, should only mean a node is still being built
+	EOpSequence,        // denotes a list of statements, or parameters, etc.
+	EOpFunctionCall,
+	EOpFunction,        // For function definition
+	EOpParameters,      // an aggregate listing the parameters to a function
 
-    EOpDeclaration,
-    EOpInvariantDeclaration, // Specialized declarations for attributing invariance
-    EOpPrototype,
+	EOpDeclaration,
+	EOpInvariantDeclaration, // Specialized declarations for attributing invariance
+	EOpPrototype,
 
-    //
-    // Unary operators
-    //
+	//
+	// Unary operators
+	//
 
-    EOpNegative,
-    EOpLogicalNot,
-    EOpVectorLogicalNot,
-    EOpBitwiseNot,
+	EOpNegative,
+	EOpLogicalNot,
+	EOpVectorLogicalNot,
+	EOpBitwiseNot,
 
-    EOpPostIncrement,
-    EOpPostDecrement,
-    EOpPreIncrement,
-    EOpPreDecrement,
+	EOpPostIncrement,
+	EOpPostDecrement,
+	EOpPreIncrement,
+	EOpPreDecrement,
 
-    //
-    // binary operations
-    //
+	//
+	// binary operations
+	//
 
-    EOpAdd,
-    EOpSub,
-    EOpMul,
-    EOpDiv,
-    EOpEqual,
-    EOpNotEqual,
-    EOpVectorEqual,
-    EOpVectorNotEqual,
-    EOpLessThan,
-    EOpGreaterThan,
-    EOpLessThanEqual,
-    EOpGreaterThanEqual,
-    EOpComma,
+	EOpAdd,
+	EOpSub,
+	EOpMul,
+	EOpDiv,
+	EOpEqual,
+	EOpNotEqual,
+	EOpVectorEqual,
+	EOpVectorNotEqual,
+	EOpLessThan,
+	EOpGreaterThan,
+	EOpLessThanEqual,
+	EOpGreaterThanEqual,
+	EOpComma,
 
-    EOpOuterProduct,
-    EOpTranspose,
-    EOpDeterminant,
-    EOpInverse,
+	EOpOuterProduct,
+	EOpTranspose,
+	EOpDeterminant,
+	EOpInverse,
 
-    EOpVectorTimesScalar,
-    EOpVectorTimesMatrix,
-    EOpMatrixTimesVector,
-    EOpMatrixTimesScalar,
+	EOpVectorTimesScalar,
+	EOpVectorTimesMatrix,
+	EOpMatrixTimesVector,
+	EOpMatrixTimesScalar,
 
-    EOpLogicalOr,
-    EOpLogicalXor,
-    EOpLogicalAnd,
+	EOpLogicalOr,
+	EOpLogicalXor,
+	EOpLogicalAnd,
 
-    EOpIMod,
-    EOpBitShiftLeft,
-    EOpBitShiftRight,
-    EOpBitwiseAnd,
-    EOpBitwiseXor,
-    EOpBitwiseOr,
+	EOpIMod,
+	EOpBitShiftLeft,
+	EOpBitShiftRight,
+	EOpBitwiseAnd,
+	EOpBitwiseXor,
+	EOpBitwiseOr,
 
-    EOpIndexDirect,
-    EOpIndexIndirect,
-    EOpIndexDirectStruct,
-    EOpIndexDirectInterfaceBlock,
+	EOpIndexDirect,
+	EOpIndexIndirect,
+	EOpIndexDirectStruct,
+	EOpIndexDirectInterfaceBlock,
 
-    EOpVectorSwizzle,
+	EOpVectorSwizzle,
 
-    //
-    // Built-in functions potentially mapped to operators
-    //
+	//
+	// Built-in functions potentially mapped to operators
+	//
 
-    EOpRadians,
-    EOpDegrees,
-    EOpSin,
-    EOpCos,
-    EOpTan,
-    EOpAsin,
-    EOpAcos,
-    EOpAtan,
-    EOpSinh,
-    EOpCosh,
-    EOpTanh,
-    EOpAsinh,
-    EOpAcosh,
-    EOpAtanh,
+	EOpRadians,
+	EOpDegrees,
+	EOpSin,
+	EOpCos,
+	EOpTan,
+	EOpAsin,
+	EOpAcos,
+	EOpAtan,
+	EOpSinh,
+	EOpCosh,
+	EOpTanh,
+	EOpAsinh,
+	EOpAcosh,
+	EOpAtanh,
 
-    EOpPow,
-    EOpExp,
-    EOpLog,
-    EOpExp2,
-    EOpLog2,
-    EOpSqrt,
-    EOpInverseSqrt,
+	EOpPow,
+	EOpExp,
+	EOpLog,
+	EOpExp2,
+	EOpLog2,
+	EOpSqrt,
+	EOpInverseSqrt,
 
-    EOpAbs,
-    EOpSign,
-    EOpFloor,
-    EOpTrunc,
-    EOpRound,
-    EOpRoundEven,
-    EOpCeil,
-    EOpFract,
-    EOpMod,
-    EOpModf,
-    EOpMin,
-    EOpMax,
-    EOpClamp,
-    EOpMix,
-    EOpStep,
-    EOpSmoothStep,
-    EOpIsNan,
-    EOpIsInf,
-    EOpFloatBitsToInt,
-    EOpFloatBitsToUint,
-    EOpIntBitsToFloat,
-    EOpUintBitsToFloat,
-    EOpPackSnorm2x16,
-    EOpPackUnorm2x16,
-    EOpPackHalf2x16,
-    EOpUnpackSnorm2x16,
-    EOpUnpackUnorm2x16,
-    EOpUnpackHalf2x16,
+	EOpAbs,
+	EOpSign,
+	EOpFloor,
+	EOpTrunc,
+	EOpRound,
+	EOpRoundEven,
+	EOpCeil,
+	EOpFract,
+	EOpMod,
+	EOpModf,
+	EOpMin,
+	EOpMax,
+	EOpClamp,
+	EOpMix,
+	EOpStep,
+	EOpSmoothStep,
+	EOpIsNan,
+	EOpIsInf,
+	EOpFloatBitsToInt,
+	EOpFloatBitsToUint,
+	EOpIntBitsToFloat,
+	EOpUintBitsToFloat,
+	EOpPackSnorm2x16,
+	EOpPackUnorm2x16,
+	EOpPackHalf2x16,
+	EOpUnpackSnorm2x16,
+	EOpUnpackUnorm2x16,
+	EOpUnpackHalf2x16,
 
-    EOpLength,
-    EOpDistance,
-    EOpDot,
-    EOpCross,
-    EOpNormalize,
-    EOpFaceForward,
-    EOpReflect,
-    EOpRefract,
+	EOpLength,
+	EOpDistance,
+	EOpDot,
+	EOpCross,
+	EOpNormalize,
+	EOpFaceForward,
+	EOpReflect,
+	EOpRefract,
 
-    EOpDFdx,            // Fragment only, OES_standard_derivatives extension
-    EOpDFdy,            // Fragment only, OES_standard_derivatives extension
-    EOpFwidth,          // Fragment only, OES_standard_derivatives extension
+	EOpDFdx,            // Fragment only, OES_standard_derivatives extension
+	EOpDFdy,            // Fragment only, OES_standard_derivatives extension
+	EOpFwidth,          // Fragment only, OES_standard_derivatives extension
 
-    EOpMatrixTimesMatrix,
+	EOpMatrixTimesMatrix,
 
-    EOpAny,
-    EOpAll,
+	EOpAny,
+	EOpAll,
 
-    //
-    // Branch
-    //
+	//
+	// Branch
+	//
 
-    EOpKill,            // Fragment only
-    EOpReturn,
-    EOpBreak,
-    EOpContinue,
+	EOpKill,            // Fragment only
+	EOpReturn,
+	EOpBreak,
+	EOpContinue,
 
-    //
-    // Constructors
-    //
+	//
+	// Constructors
+	//
 
-    EOpConstructInt,
-    EOpConstructUInt,
-    EOpConstructBool,
-    EOpConstructFloat,
-    EOpConstructVec2,
-    EOpConstructVec3,
-    EOpConstructVec4,
-    EOpConstructBVec2,
-    EOpConstructBVec3,
-    EOpConstructBVec4,
-    EOpConstructIVec2,
-    EOpConstructIVec3,
-    EOpConstructIVec4,
-    EOpConstructUVec2,
-    EOpConstructUVec3,
-    EOpConstructUVec4,
-    EOpConstructMat2,
-    EOpConstructMat2x3,
-    EOpConstructMat2x4,
-    EOpConstructMat3x2,
-    EOpConstructMat3,
-    EOpConstructMat3x4,
-    EOpConstructMat4x2,
-    EOpConstructMat4x3,
-    EOpConstructMat4,
-    EOpConstructStruct,
+	EOpConstructInt,
+	EOpConstructUInt,
+	EOpConstructBool,
+	EOpConstructFloat,
+	EOpConstructVec2,
+	EOpConstructVec3,
+	EOpConstructVec4,
+	EOpConstructBVec2,
+	EOpConstructBVec3,
+	EOpConstructBVec4,
+	EOpConstructIVec2,
+	EOpConstructIVec3,
+	EOpConstructIVec4,
+	EOpConstructUVec2,
+	EOpConstructUVec3,
+	EOpConstructUVec4,
+	EOpConstructMat2,
+	EOpConstructMat2x3,
+	EOpConstructMat2x4,
+	EOpConstructMat3x2,
+	EOpConstructMat3,
+	EOpConstructMat3x4,
+	EOpConstructMat4x2,
+	EOpConstructMat4x3,
+	EOpConstructMat4,
+	EOpConstructStruct,
 
-    //
-    // moves
-    //
+	//
+	// moves
+	//
 
-    EOpAssign,
-    EOpInitialize,
-    EOpAddAssign,
-    EOpSubAssign,
-    EOpMulAssign,
-    EOpVectorTimesMatrixAssign,
-    EOpVectorTimesScalarAssign,
-    EOpMatrixTimesScalarAssign,
-    EOpMatrixTimesMatrixAssign,
-    EOpDivAssign,
-    EOpIModAssign,
-    EOpBitShiftLeftAssign,
-    EOpBitShiftRightAssign,
-    EOpBitwiseAndAssign,
-    EOpBitwiseXorAssign,
-    EOpBitwiseOrAssign
+	EOpAssign,
+	EOpInitialize,
+	EOpAddAssign,
+	EOpSubAssign,
+	EOpMulAssign,
+	EOpVectorTimesMatrixAssign,
+	EOpVectorTimesScalarAssign,
+	EOpMatrixTimesScalarAssign,
+	EOpMatrixTimesMatrixAssign,
+	EOpDivAssign,
+	EOpIModAssign,
+	EOpBitShiftLeftAssign,
+	EOpBitShiftRightAssign,
+	EOpBitwiseAndAssign,
+	EOpBitwiseXorAssign,
+	EOpBitwiseOrAssign
 };
 
 extern const char* getOperatorString(TOperator op);
@@ -251,43 +259,43 @@
 //
 class TIntermNode {
 public:
-    POOL_ALLOCATOR_NEW_DELETE();
+	POOL_ALLOCATOR_NEW_DELETE();
 
-    TIntermNode()
-    {
-        // TODO: Move this to TSourceLoc constructor
-        // after getting rid of TPublicType.
-        line.first_file = line.last_file = 0;
-        line.first_line = line.last_line = 0;
-    }
+	TIntermNode()
+	{
+		// TODO: Move this to TSourceLoc constructor
+		// after getting rid of TPublicType.
+		line.first_file = line.last_file = 0;
+		line.first_line = line.last_line = 0;
+	}
 
-    const TSourceLoc& getLine() const { return line; }
-    void setLine(const TSourceLoc& l) { line = l; }
+	const TSourceLoc& getLine() const { return line; }
+	void setLine(const TSourceLoc& l) { line = l; }
 
-    virtual void traverse(TIntermTraverser*) = 0;
-    virtual TIntermTyped* getAsTyped() { return 0; }
-    virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
-    virtual TIntermAggregate* getAsAggregate() { return 0; }
-    virtual TIntermBinary* getAsBinaryNode() { return 0; }
-    virtual TIntermUnary* getAsUnaryNode() { return 0; }
-    virtual TIntermSelection* getAsSelectionNode() { return 0; }
-    virtual TIntermSymbol* getAsSymbolNode() { return 0; }
-    virtual TIntermLoop* getAsLoopNode() { return 0; }
+	virtual void traverse(TIntermTraverser*) = 0;
+	virtual TIntermTyped* getAsTyped() { return 0; }
+	virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
+	virtual TIntermAggregate* getAsAggregate() { return 0; }
+	virtual TIntermBinary* getAsBinaryNode() { return 0; }
+	virtual TIntermUnary* getAsUnaryNode() { return 0; }
+	virtual TIntermSelection* getAsSelectionNode() { return 0; }
+	virtual TIntermSymbol* getAsSymbolNode() { return 0; }
+	virtual TIntermLoop* getAsLoopNode() { return 0; }
 	virtual TIntermBranch* getAsBranchNode() { return 0; }
 	virtual TIntermSwitch *getAsSwitchNode() { return 0; }
 	virtual TIntermCase *getAsCaseNode() { return 0; }
-    virtual ~TIntermNode() { }
+	virtual ~TIntermNode() { }
 
 protected:
-    TSourceLoc line;
+	TSourceLoc line;
 };
 
 //
 // This is just to help yacc.
 //
 struct TIntermNodePair {
-    TIntermNode* node1;
-    TIntermNode* node2;
+	TIntermNode* node1;
+	TIntermNode* node2;
 };
 
 //
@@ -295,30 +303,30 @@
 //
 class TIntermTyped : public TIntermNode {
 public:
-    TIntermTyped(const TType& t) : type(t)  { }
-    virtual TIntermTyped* getAsTyped() { return this; }
+	TIntermTyped(const TType& t) : type(t)  { }
+	virtual TIntermTyped* getAsTyped() { return this; }
 
-    virtual void setType(const TType& t) { type = t; }
-    const TType& getType() const { return type; }
-    TType* getTypePointer() { return &type; }
+	virtual void setType(const TType& t) { type = t; }
+	const TType& getType() const { return type; }
+	TType* getTypePointer() { return &type; }
 
-    TBasicType getBasicType() const { return type.getBasicType(); }
-    TQualifier getQualifier() const { return type.getQualifier(); }
-    TPrecision getPrecision() const { return type.getPrecision(); }
-    int getNominalSize() const { return type.getNominalSize(); }
+	TBasicType getBasicType() const { return type.getBasicType(); }
+	TQualifier getQualifier() const { return type.getQualifier(); }
+	TPrecision getPrecision() const { return type.getPrecision(); }
+	int getNominalSize() const { return type.getNominalSize(); }
 	int getSecondarySize() const { return type.getSecondarySize(); }
 
 	bool isInterfaceBlock() const { return type.isInterfaceBlock(); }
-    bool isMatrix() const { return type.isMatrix(); }
-    bool isArray()  const { return type.isArray(); }
-    bool isVector() const { return type.isVector(); }
-    bool isScalar() const { return type.isScalar(); }
-    bool isScalarInt() const { return type.isScalarInt(); }
+	bool isMatrix() const { return type.isMatrix(); }
+	bool isArray()  const { return type.isArray(); }
+	bool isVector() const { return type.isVector(); }
+	bool isScalar() const { return type.isScalar(); }
+	bool isScalarInt() const { return type.isScalarInt(); }
 	bool isRegister() const { return type.isRegister(); }   // Fits in a 4-element register
 	bool isStruct() const { return type.isStruct(); }
-    const char* getBasicString() const { return type.getBasicString(); }
-    const char* getQualifierString() const { return type.getQualifierString(); }
-    TString getCompleteString() const { return type.getCompleteString(); }
+	const char* getBasicString() const { return type.getBasicString(); }
+	const char* getQualifierString() const { return type.getQualifierString(); }
+	TString getCompleteString() const { return type.getCompleteString(); }
 
 	int totalRegisterCount() const { return type.totalRegisterCount(); }
 	int blockRegisterCount() const { return type.blockRegisterCount(); }
@@ -327,50 +335,50 @@
 	int getArraySize() const { return type.getArraySize(); }
 
 protected:
-    TType type;
+	TType type;
 };
 
 //
 // Handle for, do-while, and while loops.
 //
 enum TLoopType {
-    ELoopFor,
-    ELoopWhile,
-    ELoopDoWhile
+	ELoopFor,
+	ELoopWhile,
+	ELoopDoWhile
 };
 
 class TIntermLoop : public TIntermNode {
 public:
-    TIntermLoop(TLoopType aType,
-                TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
-                TIntermNode* aBody) :
-            type(aType),
-            init(aInit),
-            cond(aCond),
-            expr(aExpr),
-            body(aBody),
-            unrollFlag(false) { }
+	TIntermLoop(TLoopType aType,
+	            TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
+	            TIntermNode* aBody) :
+			type(aType),
+			init(aInit),
+			cond(aCond),
+			expr(aExpr),
+			body(aBody),
+			unrollFlag(false) { }
 
-    virtual TIntermLoop* getAsLoopNode() { return this; }
-    virtual void traverse(TIntermTraverser*);
+	virtual TIntermLoop* getAsLoopNode() { return this; }
+	virtual void traverse(TIntermTraverser*);
 
-    TLoopType getType() const { return type; }
-    TIntermNode* getInit() { return init; }
-    TIntermTyped* getCondition() { return cond; }
-    TIntermTyped* getExpression() { return expr; }
-    TIntermNode* getBody() { return body; }
+	TLoopType getType() const { return type; }
+	TIntermNode* getInit() { return init; }
+	TIntermTyped* getCondition() { return cond; }
+	TIntermTyped* getExpression() { return expr; }
+	TIntermNode* getBody() { return body; }
 
-    void setUnrollFlag(bool flag) { unrollFlag = flag; }
-    bool getUnrollFlag() { return unrollFlag; }
+	void setUnrollFlag(bool flag) { unrollFlag = flag; }
+	bool getUnrollFlag() { return unrollFlag; }
 
 protected:
-    TLoopType type;
-    TIntermNode* init;  // for-loop initialization
-    TIntermTyped* cond; // loop exit condition
-    TIntermTyped* expr; // for-loop expression
-    TIntermNode* body;  // loop body
+	TLoopType type;
+	TIntermNode* init;  // for-loop initialization
+	TIntermTyped* cond; // loop exit condition
+	TIntermTyped* expr; // for-loop expression
+	TIntermNode* body;  // loop body
 
-    bool unrollFlag; // Whether the loop should be unrolled or not.
+	bool unrollFlag; // Whether the loop should be unrolled or not.
 };
 
 //
@@ -378,19 +386,19 @@
 //
 class TIntermBranch : public TIntermNode {
 public:
-    TIntermBranch(TOperator op, TIntermTyped* e) :
-            flowOp(op),
-            expression(e) { }
+	TIntermBranch(TOperator op, TIntermTyped* e) :
+			flowOp(op),
+			expression(e) { }
 
 	virtual TIntermBranch* getAsBranchNode() { return this; }
-    virtual void traverse(TIntermTraverser*);
+	virtual void traverse(TIntermTraverser*);
 
-    TOperator getFlowOp() { return flowOp; }
-    TIntermTyped* getExpression() { return expression; }
+	TOperator getFlowOp() { return flowOp; }
+	TIntermTyped* getExpression() { return expression; }
 
 protected:
-    TOperator flowOp;
-    TIntermTyped* expression;  // non-zero except for "return exp;" statements
+	TOperator flowOp;
+	TIntermTyped* expression;  // non-zero except for "return exp;" statements
 };
 
 //
@@ -398,49 +406,49 @@
 //
 class TIntermSymbol : public TIntermTyped {
 public:
-    // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
-    // per process globalpoolallocator, then it causes increased memory usage per compile
-    // it is essential to use "symbol = sym" to assign to symbol
-    TIntermSymbol(int i, const TString& sym, const TType& t) :
-            TIntermTyped(t), id(i)  { symbol = sym; }
+	// if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
+	// per process globalpoolallocator, then it causes increased memory usage per compile
+	// it is essential to use "symbol = sym" to assign to symbol
+	TIntermSymbol(int i, const TString& sym, const TType& t) :
+			TIntermTyped(t), id(i)  { symbol = sym; }
 
-    int getId() const { return id; }
-    const TString& getSymbol() const { return symbol; }
+	int getId() const { return id; }
+	const TString& getSymbol() const { return symbol; }
 
-    void setId(int newId) { id = newId; }
+	void setId(int newId) { id = newId; }
 
-    virtual void traverse(TIntermTraverser*);
-    virtual TIntermSymbol* getAsSymbolNode() { return this; }
+	virtual void traverse(TIntermTraverser*);
+	virtual TIntermSymbol* getAsSymbolNode() { return this; }
 
 protected:
-    int id;
-    TString symbol;
+	int id;
+	TString symbol;
 };
 
 class TIntermConstantUnion : public TIntermTyped {
 public:
-    TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer)
+	TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer)
 	{
 		getTypePointer()->setQualifier(EvqConstExpr);
 	}
 
-    ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
+	ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
 
-    int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
-    int getUConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; }
-    float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
-    bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
+	int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
+	int getUConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; }
+	float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
+	bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
 
 	// Previous union pointer freed on pool deallocation.
 	void replaceConstantUnion(ConstantUnion *safeConstantUnion) { unionArrayPointer = safeConstantUnion; }
 
-    virtual TIntermConstantUnion* getAsConstantUnion()  { return this; }
-    virtual void traverse(TIntermTraverser*);
+	virtual TIntermConstantUnion* getAsConstantUnion()  { return this; }
+	virtual void traverse(TIntermTraverser*);
 
-    TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+	TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
 
 protected:
-    ConstantUnion *unionArrayPointer;
+	ConstantUnion *unionArrayPointer;
 };
 
 //
@@ -448,16 +456,16 @@
 //
 class TIntermOperator : public TIntermTyped {
 public:
-    TOperator getOp() const { return op; }
-    void setOp(TOperator o) { op = o; }
+	TOperator getOp() const { return op; }
+	void setOp(TOperator o) { op = o; }
 
-    bool modifiesState() const;
-    bool isConstructor() const;
+	bool modifiesState() const;
+	bool isConstructor() const;
 
 protected:
-    TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
-    TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
-    TOperator op;
+	TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
+	TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
+	TOperator op;
 };
 
 //
@@ -465,10 +473,10 @@
 //
 class TIntermBinary : public TIntermOperator {
 public:
-    TIntermBinary(TOperator o) : TIntermOperator(o) {}
+	TIntermBinary(TOperator o) : TIntermOperator(o) {}
 
-    virtual TIntermBinary* getAsBinaryNode() { return this; }
-    virtual void traverse(TIntermTraverser*);
+	virtual TIntermBinary* getAsBinaryNode() { return this; }
+	virtual void traverse(TIntermTraverser*);
 
 	void setType(const TType &t) override
 	{
@@ -480,15 +488,15 @@
 		}
 	}
 
-    void setLeft(TIntermTyped* n) { left = n; }
-    void setRight(TIntermTyped* n) { right = n; }
-    TIntermTyped* getLeft() const { return left; }
-    TIntermTyped* getRight() const { return right; }
-    bool promote(TInfoSink&);
+	void setLeft(TIntermTyped* n) { left = n; }
+	void setRight(TIntermTyped* n) { right = n; }
+	TIntermTyped* getLeft() const { return left; }
+	TIntermTyped* getRight() const { return right; }
+	bool promote(TInfoSink&);
 
 protected:
-    TIntermTyped* left;
-    TIntermTyped* right;
+	TIntermTyped* left;
+	TIntermTyped* right;
 };
 
 //
@@ -496,8 +504,8 @@
 //
 class TIntermUnary : public TIntermOperator {
 public:
-    TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
-    TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
+	TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
+	TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
 
 	void setType(const TType &t) override
 	{
@@ -509,15 +517,15 @@
 		}
 	}
 
-    virtual void traverse(TIntermTraverser*);
-    virtual TIntermUnary* getAsUnaryNode() { return this; }
+	virtual void traverse(TIntermTraverser*);
+	virtual TIntermUnary* getAsUnaryNode() { return this; }
 
-    void setOperand(TIntermTyped* o) { operand = o; }
-    TIntermTyped* getOperand() { return operand; }
-    bool promote(TInfoSink&, const TType *funcReturnType);
+	void setOperand(TIntermTyped* o) { operand = o; }
+	TIntermTyped* getOperand() { return operand; }
+	bool promote(TInfoSink&, const TType *funcReturnType);
 
 protected:
-    TIntermTyped* operand;
+	TIntermTyped* operand;
 };
 
 typedef TVector<TIntermNode*> TIntermSequence;
@@ -528,14 +536,14 @@
 //
 class TIntermAggregate : public TIntermOperator {
 public:
-    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false) { endLine = { 0, 0, 0, 0 }; }
-    TIntermAggregate(TOperator o) : TIntermOperator(o) { }
-    ~TIntermAggregate() { }
+	TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false) { endLine = { 0, 0, 0, 0 }; }
+	TIntermAggregate(TOperator o) : TIntermOperator(o) { }
+	~TIntermAggregate() { }
 
-    virtual TIntermAggregate* getAsAggregate() { return this; }
-    virtual void traverse(TIntermTraverser*);
+	virtual TIntermAggregate* getAsAggregate() { return this; }
+	virtual void traverse(TIntermTraverser*);
 
-    TIntermSequence& getSequence() { return sequence; }
+	TIntermSequence& getSequence() { return sequence; }
 
 	void setType(const TType &t) override
 	{
@@ -555,19 +563,19 @@
 		}
 	}
 
-    void setName(const TString& n) { name = n; }
-    const TString& getName() const { return name; }
+	void setName(const TString& n) { name = n; }
+	const TString& getName() const { return name; }
 
-    void setUserDefined() { userDefined = true; }
-    bool isUserDefined() const { return userDefined; }
+	void setUserDefined() { userDefined = true; }
+	bool isUserDefined() const { return userDefined; }
 
-    void setOptimize(bool o) { optimize = o; }
-    bool getOptimize() { return optimize; }
-    void setDebug(bool d) { debug = d; }
-    bool getDebug() { return debug; }
+	void setOptimize(bool o) { optimize = o; }
+	bool getOptimize() { return optimize; }
+	void setDebug(bool d) { debug = d; }
+	bool getDebug() { return debug; }
 
-    void setEndLine(const TSourceLoc& line) { endLine = line; }
-    const TSourceLoc& getEndLine() const { return endLine; }
+	void setEndLine(const TSourceLoc& line) { endLine = line; }
+	const TSourceLoc& getEndLine() const { return endLine; }
 
 	bool isConstantFoldable()
 	{
@@ -583,15 +591,15 @@
 	}
 
 protected:
-    TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
-    TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
-    TIntermSequence sequence;
-    TString name;
-    bool userDefined; // used for user defined function names
+	TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
+	TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
+	TIntermSequence sequence;
+	TString name;
+	bool userDefined; // used for user defined function names
 
-    bool optimize;
-    bool debug;
-    TSourceLoc endLine;
+	bool optimize;
+	bool debug;
+	TSourceLoc endLine;
 };
 
 //
@@ -599,26 +607,26 @@
 //
 class TIntermSelection : public TIntermTyped {
 public:
-    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
-            TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
-    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
-            TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB)
+	TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
+			TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
+	TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
+			TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB)
 	{
 		this->type.setQualifier(EvqTemporary);
 	}
 
-    virtual void traverse(TIntermTraverser*);
+	virtual void traverse(TIntermTraverser*);
 
-    bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
-    TIntermTyped* getCondition() const { return condition; }
-    TIntermNode* getTrueBlock() const { return trueBlock; }
-    TIntermNode* getFalseBlock() const { return falseBlock; }
-    TIntermSelection* getAsSelectionNode() { return this; }
+	bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
+	TIntermTyped* getCondition() const { return condition; }
+	TIntermNode* getTrueBlock() const { return trueBlock; }
+	TIntermNode* getFalseBlock() const { return falseBlock; }
+	TIntermSelection* getAsSelectionNode() { return this; }
 
 protected:
-    TIntermTyped* condition;
-    TIntermNode* trueBlock;
-    TIntermNode* falseBlock;
+	TIntermTyped* condition;
+	TIntermNode* trueBlock;
+	TIntermNode* falseBlock;
 };
 
 //
@@ -666,9 +674,9 @@
 
 enum Visit
 {
-    PreVisit,
-    InVisit,
-    PostVisit
+	PreVisit,
+	InVisit,
+	PostVisit
 };
 
 //
@@ -682,23 +690,23 @@
 class TIntermTraverser
 {
 public:
-    POOL_ALLOCATOR_NEW_DELETE();
-    TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
-            preVisit(preVisit),
-            inVisit(inVisit),
-            postVisit(postVisit),
-            rightToLeft(rightToLeft),
-            mDepth(0) {}
-    virtual ~TIntermTraverser() {};
+	POOL_ALLOCATOR_NEW_DELETE();
+	TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
+			preVisit(preVisit),
+			inVisit(inVisit),
+			postVisit(postVisit),
+			rightToLeft(rightToLeft),
+			mDepth(0) {}
+	virtual ~TIntermTraverser() {};
 
-    virtual void visitSymbol(TIntermSymbol*) {}
-    virtual void visitConstantUnion(TIntermConstantUnion*) {}
-    virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
-    virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
-    virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
-    virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
-    virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
-    virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
+	virtual void visitSymbol(TIntermSymbol*) {}
+	virtual void visitConstantUnion(TIntermConstantUnion*) {}
+	virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
+	virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
+	virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
+	virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
+	virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
+	virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
 	virtual bool visitSwitch(Visit, TIntermSwitch*) { return true; }
 	virtual bool visitCase(Visit, TIntermCase*) { return true; }
 
@@ -716,13 +724,13 @@
 
 	TIntermNode *getParentNode()
 	{
-		return mPath.size() == 0 ? NULL : mPath.back();
+		return mPath.size() == 0 ? nullptr : mPath.back();
 	}
 
-    const bool preVisit;
-    const bool inVisit;
-    const bool postVisit;
-    const bool rightToLeft;
+	const bool preVisit;
+	const bool inVisit;
+	const bool postVisit;
+	const bool rightToLeft;
 
 protected:
 	int mDepth;
diff --git a/src/OpenGL/compiler/localintermediate.h b/src/OpenGL/compiler/localintermediate.h
index 4d6ed79..5210451 100644
--- a/src/OpenGL/compiler/localintermediate.h
+++ b/src/OpenGL/compiler/localintermediate.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef _LOCAL_INTERMEDIATE_INCLUDED_
 #define _LOCAL_INTERMEDIATE_INCLUDED_
@@ -10,8 +18,8 @@
 #include "intermediate.h"
 
 struct TVectorFields {
-    int offsets[4];
-    int num;
+	int offsets[4];
+	int num;
 };
 
 //
@@ -20,37 +28,37 @@
 class TInfoSink;
 class TIntermediate {
 public:
-    POOL_ALLOCATOR_NEW_DELETE();
+	POOL_ALLOCATOR_NEW_DELETE();
 
-    TIntermediate(TInfoSink& i) : infoSink(i) { }
-    TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
-    TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
-    TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
-    TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&);
-    TIntermTyped* addUnaryMath(TOperator op, TIntermTyped* child, const TSourceLoc&, const TType*);
-    TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
-    TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
-    TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&);
-    TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
-    TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
-    TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line);
-    TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &line);
-    TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
-    TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, const TSourceLoc&);
-    TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*);
-    bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TType, bool singleConstantParam = false);
-    TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, const TSourceLoc&);
-    TIntermBranch* addBranch(TOperator, const TSourceLoc&);
-    TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
-    TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
-    bool postProcess(TIntermNode*);
-    void outputTree(TIntermNode*);
+	TIntermediate(TInfoSink& i) : infoSink(i) { }
+	TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
+	TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
+	TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
+	TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&);
+	TIntermTyped* addUnaryMath(TOperator op, TIntermTyped* child, const TSourceLoc&, const TType*);
+	TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
+	TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
+	TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&);
+	TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
+	TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
+	TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line);
+	TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &line);
+	TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
+	TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, const TSourceLoc&);
+	TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*);
+	bool parseConstTree(const TSourceLoc&, TIntermNode*, ConstantUnion*, TOperator, TType, bool singleConstantParam = false);
+	TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, const TSourceLoc&);
+	TIntermBranch* addBranch(TOperator, const TSourceLoc&);
+	TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
+	TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
+	bool postProcess(TIntermNode*);
+	void outputTree(TIntermNode*);
 
 protected:
-    TInfoSink& infoSink;
+	TInfoSink& infoSink;
 
 private:
-    void operator=(TIntermediate&); // prevent assignments
+	void operator=(TIntermediate&); // prevent assignments
 };
 
 #endif // _LOCAL_INTERMEDIATE_INCLUDED_
diff --git a/src/OpenGL/compiler/osinclude.h b/src/OpenGL/compiler/osinclude.h
index 8349a4a..650f871 100644
--- a/src/OpenGL/compiler/osinclude.h
+++ b/src/OpenGL/compiler/osinclude.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef __OSINCLUDE_H
 #define __OSINCLUDE_H
diff --git a/src/OpenGL/compiler/ossource_posix.cpp b/src/OpenGL/compiler/ossource_posix.cpp
index f8ed83b..0e12fda 100644
--- a/src/OpenGL/compiler/ossource_posix.cpp
+++ b/src/OpenGL/compiler/ossource_posix.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 //
 // This file contains the posix specific functions
@@ -18,47 +26,47 @@
 //
 OS_TLSIndex OS_AllocTLSIndex()
 {
-    pthread_key_t pPoolIndex;
+	pthread_key_t pPoolIndex;
 
-    //
-    // Create global pool key.
-    //
-    if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
-        assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
-        return false;
-    }
-    else {
-        return pPoolIndex;
-    }
+	//
+	// Create global pool key.
+	//
+	if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
+		assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
+		return false;
+	}
+	else {
+		return pPoolIndex;
+	}
 }
 
 
 bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
 {
-    if (nIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
-        return false;
-    }
+	if (nIndex == OS_INVALID_TLS_INDEX) {
+		assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
+		return false;
+	}
 
-    if (pthread_setspecific(nIndex, lpvValue) == 0)
-        return true;
-    else
-        return false;
+	if (pthread_setspecific(nIndex, lpvValue) == 0)
+		return true;
+	else
+		return false;
 }
 
 
 bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
 {
-    if (nIndex == OS_INVALID_TLS_INDEX) {
-        assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
-        return false;
-    }
+	if (nIndex == OS_INVALID_TLS_INDEX) {
+		assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
+		return false;
+	}
 
-    //
-    // Delete the global pool key.
-    //
-    if (pthread_key_delete(nIndex) == 0)
-        return true;
-    else
-        return false;
+	//
+	// Delete the global pool key.
+	//
+	if (pthread_key_delete(nIndex) == 0)
+		return true;
+	else
+		return false;
 }
diff --git a/src/OpenGL/compiler/ossource_win.cpp b/src/OpenGL/compiler/ossource_win.cpp
index 71fda7a..a442167 100644
--- a/src/OpenGL/compiler/ossource_win.cpp
+++ b/src/OpenGL/compiler/ossource_win.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "osinclude.h"
 //
diff --git a/src/OpenGL/compiler/parseConst.cpp b/src/OpenGL/compiler/parseConst.cpp
index 59b39b4..c3e0b0c 100644
--- a/src/OpenGL/compiler/parseConst.cpp
+++ b/src/OpenGL/compiler/parseConst.cpp
@@ -1,51 +1,59 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "ParseHelper.h"
 
 //
-// Use this class to carry along data from node to node in 
+// Use this class to carry along data from node to node in
 // the traversal
 //
 class TConstTraverser : public TIntermTraverser {
 public:
-    TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TType& t)
-        : error(false),
-          index(0),
-          unionArray(cUnion),
-          type(t),
-          constructorType(constructType),
-          singleConstantParam(singleConstParam),
-          infoSink(sink),
-          size(0),
-          isMatrix(false),
-          matrixSize(0) {
-    }
+	TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TType& t)
+		: error(false),
+		  index(0),
+		  unionArray(cUnion),
+		  type(t),
+		  constructorType(constructType),
+		  singleConstantParam(singleConstParam),
+		  infoSink(sink),
+		  size(0),
+		  isMatrix(false),
+		  matrixSize(0) {
+	}
 
-    bool error;
+	bool error;
 
 protected:
-    void visitSymbol(TIntermSymbol*);
-    void visitConstantUnion(TIntermConstantUnion*);
-    bool visitBinary(Visit visit, TIntermBinary*);
-    bool visitUnary(Visit visit, TIntermUnary*);
-    bool visitSelection(Visit visit, TIntermSelection*);
-    bool visitAggregate(Visit visit, TIntermAggregate*);
-    bool visitLoop(Visit visit, TIntermLoop*);
-    bool visitBranch(Visit visit, TIntermBranch*);
+	void visitSymbol(TIntermSymbol*);
+	void visitConstantUnion(TIntermConstantUnion*);
+	bool visitBinary(Visit visit, TIntermBinary*);
+	bool visitUnary(Visit visit, TIntermUnary*);
+	bool visitSelection(Visit visit, TIntermSelection*);
+	bool visitAggregate(Visit visit, TIntermAggregate*);
+	bool visitLoop(Visit visit, TIntermLoop*);
+	bool visitBranch(Visit visit, TIntermBranch*);
 
-    size_t index;
-    ConstantUnion *unionArray;
-    TType type;
-    TOperator constructorType;
-    bool singleConstantParam;
-    TInfoSink& infoSink;
-    size_t size; // size of the constructor ( 4 for vec4)
-    bool isMatrix;
-    int matrixSize; // dimension of the matrix (nominal size and not the instance size)
+	size_t index;
+	ConstantUnion *unionArray;
+	TType type;
+	TOperator constructorType;
+	bool singleConstantParam;
+	TInfoSink& infoSink;
+	size_t size; // size of the constructor ( 4 for vec4)
+	bool isMatrix;
+	int matrixSize; // dimension of the matrix (nominal size and not the instance size)
 };
 
 //
@@ -59,168 +67,168 @@
 
 void TConstTraverser::visitSymbol(TIntermSymbol* node)
 {
-    infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
-    return;
+	infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
+	return;
 }
 
 bool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node)
 {
-    TQualifier qualifier = node->getType().getQualifier();
+	TQualifier qualifier = node->getType().getQualifier();
 
-    if (qualifier != EvqConstExpr) {
-        TString buf;
-        buf.append("'constructor' : assigning non-constant to ");
-        buf.append(type.getCompleteString());
-        infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
-        error = true;
-        return false;
-    }
+	if (qualifier != EvqConstExpr) {
+		TString buf;
+		buf.append("'constructor' : assigning non-constant to ");
+		buf.append(type.getCompleteString());
+		infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+		error = true;
+		return false;
+	}
 
-    infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
+	infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
 
-    return false;
+	return false;
 }
 
 bool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node)
 {
-    TString buf;
-    buf.append("'constructor' : assigning non-constant to ");
-    buf.append(type.getCompleteString());
-    infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
-    error = true;
-    return false;
+	TString buf;
+	buf.append("'constructor' : assigning non-constant to ");
+	buf.append(type.getCompleteString());
+	infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+	error = true;
+	return false;
 }
 
 bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
 {
-    if (!node->isConstructor() && node->getOp() != EOpComma) {
-        TString buf;
-        buf.append("'constructor' : assigning non-constant to ");
-        buf.append(type.getCompleteString());
-        infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
-        error = true;
-        return false;
-    }
+	if (!node->isConstructor() && node->getOp() != EOpComma) {
+		TString buf;
+		buf.append("'constructor' : assigning non-constant to ");
+		buf.append(type.getCompleteString());
+		infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
+		error = true;
+		return false;
+	}
 
-    if (node->getSequence().size() == 0) {
-        error = true;
-        return false;
-    }
+	if (node->getSequence().size() == 0) {
+		error = true;
+		return false;
+	}
 
-    bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
-    if (flag)
-    {
-        singleConstantParam = true;
-        constructorType = node->getOp();
-        size = node->getType().getObjectSize();
+	bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
+	if (flag)
+	{
+		singleConstantParam = true;
+		constructorType = node->getOp();
+		size = node->getType().getObjectSize();
 
-        if (node->getType().isMatrix()) {
-            isMatrix = true;
-            matrixSize = node->getType().getNominalSize();
-        }
-    }
+		if (node->getType().isMatrix()) {
+			isMatrix = true;
+			matrixSize = node->getType().getNominalSize();
+		}
+	}
 
-    for (TIntermSequence::iterator p = node->getSequence().begin();
-                                   p != node->getSequence().end(); p++) {
+	for (TIntermSequence::iterator p = node->getSequence().begin();
+	                               p != node->getSequence().end(); p++) {
 
-        if (node->getOp() == EOpComma)
-            index = 0;
+		if (node->getOp() == EOpComma)
+			index = 0;
 
-        (*p)->traverse(this);
-    }
-    if (flag)
-    {
-        singleConstantParam = false;
-        constructorType = EOpNull;
-        size = 0;
-        isMatrix = false;
-        matrixSize = 0;
-    }
-    return false;
+		(*p)->traverse(this);
+	}
+	if (flag)
+	{
+		singleConstantParam = false;
+		constructorType = EOpNull;
+		size = 0;
+		isMatrix = false;
+		matrixSize = 0;
+	}
+	return false;
 }
 
 bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
 {
-    infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
-    error = true;
-    return false;
+	infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
+	error = true;
+	return false;
 }
 
 void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
 {
-    if (!node->getUnionArrayPointer())
-    {
-        // The constant was not initialized, this should already have been logged
-        assert(infoSink.info.size() != 0);
-        return;
-    }
+	if (!node->getUnionArrayPointer())
+	{
+		// The constant was not initialized, this should already have been logged
+		assert(infoSink.info.size() != 0);
+		return;
+	}
 
-    ConstantUnion* leftUnionArray = unionArray;
-    size_t instanceSize = type.getObjectSize();
-    TBasicType basicType = type.getBasicType();
+	ConstantUnion* leftUnionArray = unionArray;
+	size_t instanceSize = type.getObjectSize();
+	TBasicType basicType = type.getBasicType();
 
-    if (index >= instanceSize)
-        return;
+	if (index >= instanceSize)
+		return;
 
-    if (!singleConstantParam) {
-        size_t size = node->getType().getObjectSize();
+	if (!singleConstantParam) {
+		size_t size = node->getType().getObjectSize();
 
-        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
-        for(size_t i = 0; i < size; i++) {
-            if (index >= instanceSize)
-                return;
-            leftUnionArray[index].cast(basicType, rightUnionArray[i]);
+		ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
+		for(size_t i = 0; i < size; i++) {
+			if (index >= instanceSize)
+				return;
+			leftUnionArray[index].cast(basicType, rightUnionArray[i]);
 
-            (index)++;
-        }
-    } else {
-        size_t totalSize = index + size;
-        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
-        if (!isMatrix) {
-            int count = 0;
-            for(size_t i = index; i < totalSize; i++) {
-                if (i >= instanceSize)
-                    return;
+			(index)++;
+		}
+	} else {
+		size_t totalSize = index + size;
+		ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
+		if (!isMatrix) {
+			int count = 0;
+			for(size_t i = index; i < totalSize; i++) {
+				if (i >= instanceSize)
+					return;
 
-                leftUnionArray[i].cast(basicType, rightUnionArray[count]);
+				leftUnionArray[i].cast(basicType, rightUnionArray[count]);
 
-                (index)++;
+				(index)++;
 
-                if (node->getType().getObjectSize() > 1)
-                    count++;
-            }
-        } else {  // for matrix constructors
-            int count = 0;
-            int element = index;
-            for(size_t i = index; i < totalSize; i++) {
-                if (i >= instanceSize)
-                    return;
-                if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 )
-                    leftUnionArray[i].cast(basicType, rightUnionArray[0]);
-                else
-                    leftUnionArray[i].setFConst(0.0f);
+				if (node->getType().getObjectSize() > 1)
+					count++;
+			}
+		} else {  // for matrix constructors
+			int count = 0;
+			int element = index;
+			for(size_t i = index; i < totalSize; i++) {
+				if (i >= instanceSize)
+					return;
+				if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 )
+					leftUnionArray[i].cast(basicType, rightUnionArray[0]);
+				else
+					leftUnionArray[i].setFConst(0.0f);
 
-                (index)++;
+				(index)++;
 
-                if (node->getType().getObjectSize() > 1)
-                    count++;
-            }
-        }
-    }
+				if (node->getType().getObjectSize() > 1)
+					count++;
+			}
+		}
+	}
 }
 
 bool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node)
 {
-    infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
-    error = true;
-    return false;
+	infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
+	error = true;
+	return false;
 }
 
 bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
 {
-    infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
-    error = true;
-    return false;
+	infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
+	error = true;
+	return false;
 }
 
 //
@@ -230,14 +238,14 @@
 //
 bool TIntermediate::parseConstTree(const TSourceLoc& line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TType t, bool singleConstantParam)
 {
-    if (root == 0)
-        return false;
+	if (root == 0)
+		return false;
 
-    TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, t);
+	TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, t);
 
-    root->traverse(&it);
-    if (it.error)
-        return true;
-    else
-        return false;
+	root->traverse(&it);
+	if (it.error)
+		return true;
+	else
+		return false;
 }
diff --git a/src/OpenGL/compiler/preprocessor/Diagnostics.cpp b/src/OpenGL/compiler/preprocessor/Diagnostics.cpp
index b6888b9..767edd9 100644
--- a/src/OpenGL/compiler/preprocessor/Diagnostics.cpp
+++ b/src/OpenGL/compiler/preprocessor/Diagnostics.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Diagnostics.h"
 
@@ -19,113 +27,113 @@
                          const SourceLocation& loc,
                          const std::string& text)
 {
-    // TODO(alokp): Keep a count of errors and warnings.
-    print(id, loc, text);
+	// TODO(alokp): Keep a count of errors and warnings.
+	print(id, loc, text);
 }
 
 Diagnostics::Severity Diagnostics::severity(ID id)
 {
-    if ((id > ERROR_BEGIN) && (id < ERROR_END))
-        return PP_ERROR;
+	if ((id > ERROR_BEGIN) && (id < ERROR_END))
+		return PP_ERROR;
 
-    if ((id > WARNING_BEGIN) && (id < WARNING_END))
-        return PP_WARNING;
+	if ((id > WARNING_BEGIN) && (id < WARNING_END))
+		return PP_WARNING;
 
-    assert(false);
-    return PP_ERROR;
+	assert(false);
+	return PP_ERROR;
 }
 
 std::string Diagnostics::message(ID id)
 {
-    switch (id)
-    {
-      // Errors begin.
-      case INTERNAL_ERROR:
-          return "internal error";
-      case OUT_OF_MEMORY:
-          return "out of memory";
-      case INVALID_CHARACTER:
-          return "invalid character";
-      case INVALID_NUMBER:
-          return "invalid number";
-      case INTEGER_OVERFLOW:
-          return "integer overflow";
-      case FLOAT_OVERFLOW:
-          return "float overflow";
-      case TOKEN_TOO_LONG:
-          return "token too long";
-      case INVALID_EXPRESSION:
-          return "invalid expression";
-      case DIVISION_BY_ZERO:
-          return "division by zero";
-      case EOF_IN_COMMENT:
-          return "unexpected end of file found in comment";
-      case UNEXPECTED_TOKEN:
-          return "unexpected token";
-      case DIRECTIVE_INVALID_NAME:
-          return "invalid directive name";
-      case MACRO_NAME_RESERVED:
-          return "macro name is reserved";
-      case MACRO_REDEFINED:
-          return "macro redefined";
-      case MACRO_PREDEFINED_REDEFINED:
-          return "predefined macro redefined";
-      case MACRO_PREDEFINED_UNDEFINED:
-          return "predefined macro undefined";
-      case MACRO_UNTERMINATED_INVOCATION:
-          return "unterminated macro invocation";
-      case MACRO_TOO_FEW_ARGS:
-          return "Not enough arguments for macro";
-      case MACRO_TOO_MANY_ARGS:
-          return "Too many arguments for macro";
-      case MACRO_DUPLICATE_PARAMETER_NAMES:
-          return "duplicate macro parameter name";
-      case CONDITIONAL_ENDIF_WITHOUT_IF:
-          return "unexpected #endif found without a matching #if";
-      case CONDITIONAL_ELSE_WITHOUT_IF:
-          return "unexpected #else found without a matching #if";
-      case CONDITIONAL_ELSE_AFTER_ELSE:
-          return "unexpected #else found after another #else";
-      case CONDITIONAL_ELIF_WITHOUT_IF:
-          return "unexpected #elif found without a matching #if";
-      case CONDITIONAL_ELIF_AFTER_ELSE:
-          return "unexpected #elif found after #else";
-      case CONDITIONAL_UNTERMINATED:
-          return "unexpected end of file found in conditional block";
-      case INVALID_EXTENSION_NAME:
-          return "invalid extension name";
-      case INVALID_EXTENSION_BEHAVIOR:
-          return "invalid extension behavior";
-      case INVALID_EXTENSION_DIRECTIVE:
-          return "invalid extension directive";
-      case INVALID_VERSION_NUMBER:
-          return "invalid version number";
-      case INVALID_VERSION_DIRECTIVE:
-          return "invalid version directive";
-      case VERSION_NOT_FIRST_STATEMENT:
-        return "#version directive must occur before anything else, "
-               "except for comments and white space";
-      case INVALID_LINE_NUMBER:
-          return "invalid line number";
-      case INVALID_FILE_NUMBER:
-          return "invalid file number";
-      case INVALID_LINE_DIRECTIVE:
-          return "invalid line directive";
-      case UNDEFINED_IDENTIFIER:
-          return "undefined identifier";
-      // Errors end.
-      // Warnings begin.
-      case EOF_IN_DIRECTIVE:
-          return "unexpected end of file found in directive";
-      case CONDITIONAL_UNEXPECTED_TOKEN:
-          return "unexpected token after conditional expression";
-      case UNRECOGNIZED_PRAGMA:
-          return "unrecognized pragma";
-      // Warnings end.
-      default:
-          assert(false);
-          return "";
-    }
+	switch (id)
+	{
+	// Errors begin.
+	case INTERNAL_ERROR:
+		  return "internal error";
+	case OUT_OF_MEMORY:
+		  return "out of memory";
+	case INVALID_CHARACTER:
+		  return "invalid character";
+	case INVALID_NUMBER:
+		  return "invalid number";
+	case INTEGER_OVERFLOW:
+		  return "integer overflow";
+	case FLOAT_OVERFLOW:
+		  return "float overflow";
+	case TOKEN_TOO_LONG:
+		  return "token too long";
+	case INVALID_EXPRESSION:
+		  return "invalid expression";
+	case DIVISION_BY_ZERO:
+		  return "division by zero";
+	case EOF_IN_COMMENT:
+		  return "unexpected end of file found in comment";
+	case UNEXPECTED_TOKEN:
+		  return "unexpected token";
+	case DIRECTIVE_INVALID_NAME:
+		  return "invalid directive name";
+	case MACRO_NAME_RESERVED:
+		  return "macro name is reserved";
+	case MACRO_REDEFINED:
+		  return "macro redefined";
+	case MACRO_PREDEFINED_REDEFINED:
+		  return "predefined macro redefined";
+	case MACRO_PREDEFINED_UNDEFINED:
+		  return "predefined macro undefined";
+	case MACRO_UNTERMINATED_INVOCATION:
+		  return "unterminated macro invocation";
+	case MACRO_TOO_FEW_ARGS:
+		  return "Not enough arguments for macro";
+	case MACRO_TOO_MANY_ARGS:
+		  return "Too many arguments for macro";
+	case MACRO_DUPLICATE_PARAMETER_NAMES:
+		  return "duplicate macro parameter name";
+	case CONDITIONAL_ENDIF_WITHOUT_IF:
+		  return "unexpected #endif found without a matching #if";
+	case CONDITIONAL_ELSE_WITHOUT_IF:
+		  return "unexpected #else found without a matching #if";
+	case CONDITIONAL_ELSE_AFTER_ELSE:
+		  return "unexpected #else found after another #else";
+	case CONDITIONAL_ELIF_WITHOUT_IF:
+		  return "unexpected #elif found without a matching #if";
+	case CONDITIONAL_ELIF_AFTER_ELSE:
+		  return "unexpected #elif found after #else";
+	case CONDITIONAL_UNTERMINATED:
+		  return "unexpected end of file found in conditional block";
+	case INVALID_EXTENSION_NAME:
+		  return "invalid extension name";
+	case INVALID_EXTENSION_BEHAVIOR:
+		  return "invalid extension behavior";
+	case INVALID_EXTENSION_DIRECTIVE:
+		  return "invalid extension directive";
+	case INVALID_VERSION_NUMBER:
+		  return "invalid version number";
+	case INVALID_VERSION_DIRECTIVE:
+		  return "invalid version directive";
+	case VERSION_NOT_FIRST_STATEMENT:
+		return "#version directive must occur before anything else, "
+		       "except for comments and white space";
+	case INVALID_LINE_NUMBER:
+		  return "invalid line number";
+	case INVALID_FILE_NUMBER:
+		  return "invalid file number";
+	case INVALID_LINE_DIRECTIVE:
+		  return "invalid line directive";
+	case UNDEFINED_IDENTIFIER:
+		  return "undefined identifier";
+	// Errors end.
+	// Warnings begin.
+	case EOF_IN_DIRECTIVE:
+		  return "unexpected end of file found in directive";
+	case CONDITIONAL_UNEXPECTED_TOKEN:
+		  return "unexpected token after conditional expression";
+	case UNRECOGNIZED_PRAGMA:
+		  return "unrecognized pragma";
+	// Warnings end.
+	default:
+		  assert(false);
+		  return "";
+	}
 }
 
 }  // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Diagnostics.h b/src/OpenGL/compiler/preprocessor/Diagnostics.h
index 0516c2b..1f4cfc4 100644
--- a/src/OpenGL/compiler/preprocessor/Diagnostics.h
+++ b/src/OpenGL/compiler/preprocessor/Diagnostics.h
@@ -1,89 +1,97 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICS_H_

-#define COMPILER_PREPROCESSOR_DIAGNOSTICS_H_

-

-#include <string>

-

-namespace pp

-{

-

-struct SourceLocation;

-

-// Base class for reporting diagnostic messages.

-// Derived classes are responsible for formatting and printing the messages.

-class Diagnostics

-{

-  public:

-    enum Severity

-    {

-        PP_ERROR,

-        PP_WARNING

-    };

-    enum ID

-    {

-        ERROR_BEGIN,

-        INTERNAL_ERROR,

-        OUT_OF_MEMORY,

-        INVALID_CHARACTER,

-        INVALID_NUMBER,

-        INTEGER_OVERFLOW,

-        FLOAT_OVERFLOW,

-        TOKEN_TOO_LONG,

-        INVALID_EXPRESSION,

-        DIVISION_BY_ZERO,

-        EOF_IN_COMMENT,

-        UNEXPECTED_TOKEN,

-        DIRECTIVE_INVALID_NAME,

-        MACRO_NAME_RESERVED,

-        MACRO_REDEFINED,

-        MACRO_PREDEFINED_REDEFINED,

-        MACRO_PREDEFINED_UNDEFINED,

-        MACRO_UNTERMINATED_INVOCATION,

-        MACRO_TOO_FEW_ARGS,

-        MACRO_TOO_MANY_ARGS,

-        MACRO_DUPLICATE_PARAMETER_NAMES,

-        CONDITIONAL_ENDIF_WITHOUT_IF,

-        CONDITIONAL_ELSE_WITHOUT_IF,

-        CONDITIONAL_ELSE_AFTER_ELSE,

-        CONDITIONAL_ELIF_WITHOUT_IF,

-        CONDITIONAL_ELIF_AFTER_ELSE,

-        CONDITIONAL_UNTERMINATED,

-		CONDITIONAL_UNEXPECTED_TOKEN,

-        INVALID_EXTENSION_NAME,

-        INVALID_EXTENSION_BEHAVIOR,

-        INVALID_EXTENSION_DIRECTIVE,

-        INVALID_VERSION_NUMBER,

-        INVALID_VERSION_DIRECTIVE,

-        VERSION_NOT_FIRST_STATEMENT,

-        INVALID_LINE_NUMBER,

-        INVALID_FILE_NUMBER,

-        INVALID_LINE_DIRECTIVE,

-		UNDEFINED_IDENTIFIER,

-        ERROR_END,

-

-        WARNING_BEGIN,

-        EOF_IN_DIRECTIVE,

-        UNRECOGNIZED_PRAGMA,

-        WARNING_END

-    };

-

-    virtual ~Diagnostics();

-

-    void report(ID id, const SourceLocation& loc, const std::string& text);

-

-  protected:

-    Severity severity(ID id);

-    std::string message(ID id);

-

-    virtual void print(ID id,

-                       const SourceLocation& loc,

-                       const std::string& text) = 0;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_DIAGNOSTICS_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
+#define COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
+
+#include <string>
+
+namespace pp
+{
+
+struct SourceLocation;
+
+// Base class for reporting diagnostic messages.
+// Derived classes are responsible for formatting and printing the messages.
+class Diagnostics
+{
+public:
+	enum Severity
+	{
+		PP_ERROR,
+		PP_WARNING
+	};
+	enum ID
+	{
+		ERROR_BEGIN,
+		INTERNAL_ERROR,
+		OUT_OF_MEMORY,
+		INVALID_CHARACTER,
+		INVALID_NUMBER,
+		INTEGER_OVERFLOW,
+		FLOAT_OVERFLOW,
+		TOKEN_TOO_LONG,
+		INVALID_EXPRESSION,
+		DIVISION_BY_ZERO,
+		EOF_IN_COMMENT,
+		UNEXPECTED_TOKEN,
+		DIRECTIVE_INVALID_NAME,
+		MACRO_NAME_RESERVED,
+		MACRO_REDEFINED,
+		MACRO_PREDEFINED_REDEFINED,
+		MACRO_PREDEFINED_UNDEFINED,
+		MACRO_UNTERMINATED_INVOCATION,
+		MACRO_TOO_FEW_ARGS,
+		MACRO_TOO_MANY_ARGS,
+		MACRO_DUPLICATE_PARAMETER_NAMES,
+		CONDITIONAL_ENDIF_WITHOUT_IF,
+		CONDITIONAL_ELSE_WITHOUT_IF,
+		CONDITIONAL_ELSE_AFTER_ELSE,
+		CONDITIONAL_ELIF_WITHOUT_IF,
+		CONDITIONAL_ELIF_AFTER_ELSE,
+		CONDITIONAL_UNTERMINATED,
+		CONDITIONAL_UNEXPECTED_TOKEN,
+		INVALID_EXTENSION_NAME,
+		INVALID_EXTENSION_BEHAVIOR,
+		INVALID_EXTENSION_DIRECTIVE,
+		INVALID_VERSION_NUMBER,
+		INVALID_VERSION_DIRECTIVE,
+		VERSION_NOT_FIRST_STATEMENT,
+		INVALID_LINE_NUMBER,
+		INVALID_FILE_NUMBER,
+		INVALID_LINE_DIRECTIVE,
+		UNDEFINED_IDENTIFIER,
+		ERROR_END,
+
+		WARNING_BEGIN,
+		EOF_IN_DIRECTIVE,
+		UNRECOGNIZED_PRAGMA,
+		WARNING_END
+	};
+
+	virtual ~Diagnostics();
+
+	void report(ID id, const SourceLocation& loc, const std::string& text);
+
+protected:
+	Severity severity(ID id);
+	std::string message(ID id);
+
+	virtual void print(ID id,
+	                   const SourceLocation& loc,
+	                   const std::string& text) = 0;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveHandler.cpp b/src/OpenGL/compiler/preprocessor/DirectiveHandler.cpp
index d67bee3..ac26c83 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveHandler.cpp
+++ b/src/OpenGL/compiler/preprocessor/DirectiveHandler.cpp
@@ -1,16 +1,24 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "DirectiveHandler.h"

-

-namespace pp

-{

-

-DirectiveHandler::~DirectiveHandler()

-{

-}

-

-}  // namespace pp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "DirectiveHandler.h"
+
+namespace pp
+{
+
+DirectiveHandler::~DirectiveHandler()
+{
+}
+
+}  // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveHandler.h b/src/OpenGL/compiler/preprocessor/DirectiveHandler.h
index 572b897..f7b3784 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveHandler.h
+++ b/src/OpenGL/compiler/preprocessor/DirectiveHandler.h
@@ -1,43 +1,51 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_

-#define COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_

-

-#include <string>

-

-namespace pp

-{

-

-struct SourceLocation;

-

-// Base class for handling directives.

-// Preprocessor uses this class to notify the clients about certain

-// preprocessor directives. Derived classes are responsible for

-// handling them in an appropriate manner.

-class DirectiveHandler

-{

-  public:

-    virtual ~DirectiveHandler();

-

-    virtual void handleError(const SourceLocation& loc,

-                             const std::string& msg) = 0;

-

-    // Handle pragma of form: #pragma name[(value)]

-    virtual void handlePragma(const SourceLocation& loc,

-                              const std::string& name,

-                              const std::string& value) = 0;

-

-    virtual void handleExtension(const SourceLocation& loc,

-                                 const std::string& name,

-                                 const std::string& behavior) = 0;

-

-    virtual void handleVersion(const SourceLocation& loc,

-                               int version) = 0;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
+#define COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
+
+#include <string>
+
+namespace pp
+{
+
+struct SourceLocation;
+
+// Base class for handling directives.
+// Preprocessor uses this class to notify the clients about certain
+// preprocessor directives. Derived classes are responsible for
+// handling them in an appropriate manner.
+class DirectiveHandler
+{
+public:
+	virtual ~DirectiveHandler();
+
+	virtual void handleError(const SourceLocation& loc,
+	                         const std::string& msg) = 0;
+
+	// Handle pragma of form: #pragma name[(value)]
+	virtual void handlePragma(const SourceLocation& loc,
+	                          const std::string& name,
+	                          const std::string& value) = 0;
+
+	virtual void handleExtension(const SourceLocation& loc,
+	                             const std::string& name,
+	                             const std::string& behavior) = 0;
+
+	virtual void handleVersion(const SourceLocation& loc,
+	                           int version) = 0;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp b/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
index 8e6dcbd..ec77c21 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
+++ b/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
@@ -1,891 +1,899 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "DirectiveParser.h"

-

-#include <cassert>

-#include <cstdlib>

-#include <sstream>

-

-#include "Diagnostics.h"

-#include "DirectiveHandler.h"

-#include "ExpressionParser.h"

-#include "MacroExpander.h"

-#include "Token.h"

-#include "Tokenizer.h"

-

-namespace {

-enum DirectiveType

-{

-    DIRECTIVE_NONE,

-    DIRECTIVE_DEFINE,

-    DIRECTIVE_UNDEF,

-    DIRECTIVE_IF,

-    DIRECTIVE_IFDEF,

-    DIRECTIVE_IFNDEF,

-    DIRECTIVE_ELSE,

-    DIRECTIVE_ELIF,

-    DIRECTIVE_ENDIF,

-    DIRECTIVE_ERROR,

-    DIRECTIVE_PRAGMA,

-    DIRECTIVE_EXTENSION,

-    DIRECTIVE_VERSION,

-    DIRECTIVE_LINE

-};

-}  // namespace

-

-static DirectiveType getDirective(const pp::Token* token)

-{

-    static const std::string kDirectiveDefine("define");

-    static const std::string kDirectiveUndef("undef");

-    static const std::string kDirectiveIf("if");

-    static const std::string kDirectiveIfdef("ifdef");

-    static const std::string kDirectiveIfndef("ifndef");

-    static const std::string kDirectiveElse("else");

-    static const std::string kDirectiveElif("elif");

-    static const std::string kDirectiveEndif("endif");

-    static const std::string kDirectiveError("error");

-    static const std::string kDirectivePragma("pragma");

-    static const std::string kDirectiveExtension("extension");

-    static const std::string kDirectiveVersion("version");

-    static const std::string kDirectiveLine("line");

-

-    if (token->type != pp::Token::IDENTIFIER)

-        return DIRECTIVE_NONE;

-

-    if (token->text == kDirectiveDefine)

-        return DIRECTIVE_DEFINE;

-    else if (token->text == kDirectiveUndef)

-        return DIRECTIVE_UNDEF;

-    else if (token->text == kDirectiveIf)

-        return DIRECTIVE_IF;

-    else if (token->text == kDirectiveIfdef)

-        return DIRECTIVE_IFDEF;

-    else if (token->text == kDirectiveIfndef)

-        return DIRECTIVE_IFNDEF;

-    else if (token->text == kDirectiveElse)

-        return DIRECTIVE_ELSE;

-    else if (token->text == kDirectiveElif)

-        return DIRECTIVE_ELIF;

-    else if (token->text == kDirectiveEndif)

-        return DIRECTIVE_ENDIF;

-    else if (token->text == kDirectiveError)

-        return DIRECTIVE_ERROR;

-    else if (token->text == kDirectivePragma)

-        return DIRECTIVE_PRAGMA;

-    else if (token->text == kDirectiveExtension)

-        return DIRECTIVE_EXTENSION;

-    else if (token->text == kDirectiveVersion)

-        return DIRECTIVE_VERSION;

-    else if (token->text == kDirectiveLine)

-        return DIRECTIVE_LINE;

-

-    return DIRECTIVE_NONE;

-}

-

-static bool isConditionalDirective(DirectiveType directive)

-{

-    switch (directive)

-    {

-      case DIRECTIVE_IF:

-      case DIRECTIVE_IFDEF:

-      case DIRECTIVE_IFNDEF:

-      case DIRECTIVE_ELSE:

-      case DIRECTIVE_ELIF:

-      case DIRECTIVE_ENDIF:

-        return true;

-      default:

-        return false;

-    }

-}

-

-// Returns true if the token represents End Of Directive.

-static bool isEOD(const pp::Token* token)

-{

-    return (token->type == '\n') || (token->type == pp::Token::LAST);

-}

-

-static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token)

-{

-    while(!isEOD(token))

-    {

-        lexer->lex(token);

-    }

-}

-

-static bool isMacroNameReserved(const std::string& name)

-{

-    // Names prefixed with "GL_" are reserved.

-    if (name.substr(0, 3) == "GL_")

-        return true;

-

-    // Names containing two consecutive underscores are reserved.

-    if (name.find("__") != std::string::npos)

-        return true;

-

-    return false;

-}

-

-static bool isMacroPredefined(const std::string& name,

-                              const pp::MacroSet& macroSet)

-{

-    pp::MacroSet::const_iterator iter = macroSet.find(name);

-    return iter != macroSet.end() ? iter->second.predefined : false;

-}

-

-namespace pp

-{

-

-DirectiveParser::DirectiveParser(Tokenizer* tokenizer,

-                                 MacroSet* macroSet,

-                                 Diagnostics* diagnostics,

-                                 DirectiveHandler* directiveHandler) :

-    mPastFirstStatement(false),

-    mTokenizer(tokenizer),

-    mMacroSet(macroSet),

-    mDiagnostics(diagnostics),

-    mDirectiveHandler(directiveHandler)

-{

-}

-

-void DirectiveParser::lex(Token* token)

-{

-    do

-    {

-        mTokenizer->lex(token);

-

-        if (token->type == Token::PP_HASH)

-        {

-            parseDirective(token);

-            mPastFirstStatement = true;

-        }

-

-        if (token->type == Token::LAST)

-        {

-            if (!mConditionalStack.empty())

-            {

-                const ConditionalBlock& block = mConditionalStack.back();

-                mDiagnostics->report(Diagnostics::CONDITIONAL_UNTERMINATED,

-                                     block.location, block.type);

-            }

-            break;

-        }

-

-    } while (skipping() || (token->type == '\n'));

-

-    mPastFirstStatement = true;

-}

-

-void DirectiveParser::parseDirective(Token* token)

-{

-    assert(token->type == Token::PP_HASH);

-

-    mTokenizer->lex(token);

-    if (isEOD(token))

-    {

-        // Empty Directive.

-        return;

-    }

-

-    DirectiveType directive = getDirective(token);

-

-    // While in an excluded conditional block/group,

-    // we only parse conditional directives.

-    if (skipping() && !isConditionalDirective(directive))

-    {

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-

-    switch(directive)

-    {

-      case DIRECTIVE_NONE:

-        mDiagnostics->report(Diagnostics::DIRECTIVE_INVALID_NAME,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        break;

-      case DIRECTIVE_DEFINE:

-        parseDefine(token);

-        break;

-      case DIRECTIVE_UNDEF:

-        parseUndef(token);

-        break;

-      case DIRECTIVE_IF:

-        parseIf(token);

-        break;

-      case DIRECTIVE_IFDEF:

-        parseIfdef(token);

-        break;

-      case DIRECTIVE_IFNDEF:

-        parseIfndef(token);

-        break;

-      case DIRECTIVE_ELSE:

-        parseElse(token);

-        break;

-      case DIRECTIVE_ELIF:

-        parseElif(token);

-        break;

-      case DIRECTIVE_ENDIF:

-        parseEndif(token);

-        break;

-      case DIRECTIVE_ERROR:

-        parseError(token);

-        break;

-      case DIRECTIVE_PRAGMA:

-        parsePragma(token);

-        break;

-      case DIRECTIVE_EXTENSION:

-        parseExtension(token);

-        break;

-      case DIRECTIVE_VERSION:

-        parseVersion(token);

-        break;

-      case DIRECTIVE_LINE:

-        parseLine(token);

-        break;

-      default:

-        assert(false);

-        break;

-    }

-

-    skipUntilEOD(mTokenizer, token);

-    if (token->type == Token::LAST)

-    {

-        mDiagnostics->report(Diagnostics::EOF_IN_DIRECTIVE,

-                             token->location, token->text);

-    }

-}

-

-void DirectiveParser::parseDefine(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_DEFINE);

-

-    mTokenizer->lex(token);

-    if (token->type != Token::IDENTIFIER)

-    {

-        mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                             token->location, token->text);

-        return;

-    }

-    if (isMacroPredefined(token->text, *mMacroSet))

-    {

-        mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_REDEFINED,

-                             token->location, token->text);

-        return;

-    }

-    if (isMacroNameReserved(token->text))

-    {

-        mDiagnostics->report(Diagnostics::MACRO_NAME_RESERVED,

-                             token->location, token->text);

-        return;

-    }

-

-    Macro macro;

-    macro.type = Macro::kTypeObj;

-    macro.name = token->text;

-

-    mTokenizer->lex(token);

-    if (token->type == '(' && !token->hasLeadingSpace())

-    {

-        // Function-like macro. Collect arguments.

-        macro.type = Macro::kTypeFunc;

-        do {

-            mTokenizer->lex(token);

-            if (token->type != Token::IDENTIFIER)

-                break;

-

-            if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end())

-            {

-                mDiagnostics->report(Diagnostics::MACRO_DUPLICATE_PARAMETER_NAMES,

-                                     token->location, token->text);

-                return;

-            }

-

-            macro.parameters.push_back(token->text);

-

-            mTokenizer->lex(token);  // Get ','.

-        } while (token->type == ',');

-

-        if (token->type != ')')

-        {

-            mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                                 token->location,

-                                 token->text);

-            return;

-        }

-        mTokenizer->lex(token);  // Get ')'.

-    }

-

-    while ((token->type != '\n') && (token->type != Token::LAST))

-    {

-        // Reset the token location because it is unnecessary in replacement

-        // list. Resetting it also allows us to reuse Token::equals() to

-        // compare macros.

-        token->location = SourceLocation();

-        macro.replacements.push_back(*token);

-        mTokenizer->lex(token);

-    }

-    if (!macro.replacements.empty())

-    {

-        // Whitespace preceding the replacement list is not considered part of

-        // the replacement list for either form of macro.

-        macro.replacements.front().setHasLeadingSpace(false);

-    }

-

-    // Check for macro redefinition.

-    MacroSet::const_iterator iter = mMacroSet->find(macro.name);

-    if (iter != mMacroSet->end() && !macro.equals(iter->second))

-    {

-        mDiagnostics->report(Diagnostics::MACRO_REDEFINED,

-                             token->location,

-                             macro.name);

-        return;

-    }

-    mMacroSet->insert(std::make_pair(macro.name, macro));

-}

-

-void DirectiveParser::parseUndef(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_UNDEF);

-

-    mTokenizer->lex(token);

-    if (token->type != Token::IDENTIFIER)

-    {

-        mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                             token->location, token->text);

-        return;

-    }

-

-    MacroSet::iterator iter = mMacroSet->find(token->text);

-    if (iter != mMacroSet->end())

-    {

-        if (iter->second.predefined)

-        {

-            mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_UNDEFINED,

-                                 token->location, token->text);

-        }

-        else

-        {

-            mMacroSet->erase(iter);

-        }

-    }

-

-    mTokenizer->lex(token);

-}

-

-void DirectiveParser::parseIf(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_IF);

-    parseConditionalIf(token);

-}

-

-void DirectiveParser::parseIfdef(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_IFDEF);

-    parseConditionalIf(token);

-}

-

-void DirectiveParser::parseIfndef(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_IFNDEF);

-    parseConditionalIf(token);

-}

-

-void DirectiveParser::parseElse(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_ELSE);

-

-    if (mConditionalStack.empty())

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_WITHOUT_IF,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-

-    ConditionalBlock& block = mConditionalStack.back();

-    if (block.skipBlock)

-    {

-        // No diagnostics. Just skip the whole line.

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-    if (block.foundElseGroup)

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_AFTER_ELSE,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-

-    block.foundElseGroup = true;

-    block.skipGroup = block.foundValidGroup;

-    block.foundValidGroup = true;

-

-    // Check if there are extra tokens after #else.

-    mTokenizer->lex(token);

-    if (!isEOD(token))

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-    }

-}

-

-void DirectiveParser::parseElif(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_ELIF);

-

-    if (mConditionalStack.empty())

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_WITHOUT_IF,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-

-    ConditionalBlock& block = mConditionalStack.back();

-    if (block.skipBlock)

-    {

-        // No diagnostics. Just skip the whole line.

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-    if (block.foundElseGroup)

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_AFTER_ELSE,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-    if (block.foundValidGroup)

-    {

-        // Do not parse the expression.

-        // Also be careful not to emit a diagnostic.

-        block.skipGroup = true;

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-

-    int expression = parseExpressionIf(token);

-    block.skipGroup = expression == 0;

-    block.foundValidGroup = expression != 0;

-}

-

-void DirectiveParser::parseEndif(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_ENDIF);

-

-    if (mConditionalStack.empty())

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_ENDIF_WITHOUT_IF,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-

-    mConditionalStack.pop_back();

-

-    // Check if there are tokens after #endif.

-    mTokenizer->lex(token);

-    if (!isEOD(token))

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-    }

-}

-

-void DirectiveParser::parseError(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_ERROR);

-

-    std::ostringstream stream;

-    mTokenizer->lex(token);

-    while ((token->type != '\n') && (token->type != Token::LAST))

-    {

-        stream << *token;

-        mTokenizer->lex(token);

-    }

-    mDirectiveHandler->handleError(token->location, stream.str());

-}

-

-// Parses pragma of form: #pragma name[(value)].

-void DirectiveParser::parsePragma(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_PRAGMA);

-

-    enum State

-    {

-        PRAGMA_NAME,

-        LEFT_PAREN,

-        PRAGMA_VALUE,

-        RIGHT_PAREN

-    };

-

-    bool valid = true;

-    std::string name, value;

-    int state = PRAGMA_NAME;

-

-    mTokenizer->lex(token);

-    while ((token->type != '\n') && (token->type != Token::LAST))

-    {

-        switch(state++)

-        {

-          case PRAGMA_NAME:

-            name = token->text;

-            valid = valid && (token->type == Token::IDENTIFIER);

-            break;

-          case LEFT_PAREN:

-            valid = valid && (token->type == '(');

-            break;

-          case PRAGMA_VALUE:

-            value = token->text;

-            valid = valid && (token->type == Token::IDENTIFIER);

-            break;

-          case RIGHT_PAREN:

-            valid = valid && (token->type == ')');

-            break;

-          default:

-            valid = false;

-            break;

-        }

-        mTokenizer->lex(token);

-    }

-

-    valid = valid && ((state == PRAGMA_NAME) ||     // Empty pragma.

-                      (state == LEFT_PAREN) ||      // Without value.

-                      (state == RIGHT_PAREN + 1));  // With value.

-    if (!valid)

-    {

-        mDiagnostics->report(Diagnostics::UNRECOGNIZED_PRAGMA,

-                             token->location, name);

-    }

-    else if (state > PRAGMA_NAME)  // Do not notify for empty pragma.

-    {

-        mDirectiveHandler->handlePragma(token->location, name, value);

-    }

-}

-

-void DirectiveParser::parseExtension(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_EXTENSION);

-

-    enum State

-    {

-        EXT_NAME,

-        COLON,

-        EXT_BEHAVIOR

-    };

-

-    bool valid = true;

-    std::string name, behavior;

-    int state = EXT_NAME;

-

-    mTokenizer->lex(token);

-    while ((token->type != '\n') && (token->type != Token::LAST))

-    {

-        switch (state++)

-        {

-          case EXT_NAME:

-            if (valid && (token->type != Token::IDENTIFIER))

-            {

-                mDiagnostics->report(Diagnostics::INVALID_EXTENSION_NAME,

-                                     token->location, token->text);

-                valid = false;

-            }

-            if (valid) name = token->text;

-            break;

-          case COLON:

-            if (valid && (token->type != ':'))

-            {

-                mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                                     token->location, token->text);

-                valid = false;

-            }

-            break;

-          case EXT_BEHAVIOR:

-            if (valid && (token->type != Token::IDENTIFIER))

-            {

-                mDiagnostics->report(Diagnostics::INVALID_EXTENSION_BEHAVIOR,

-                                     token->location, token->text);

-                valid = false;

-            }

-            if (valid) behavior = token->text;

-            break;

-          default:

-            if (valid)

-            {

-                mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                                     token->location, token->text);

-                valid = false;

-            }

-            break;

-        }

-        mTokenizer->lex(token);

-    }

-    if (valid && (state != EXT_BEHAVIOR + 1))

-    {

-        mDiagnostics->report(Diagnostics::INVALID_EXTENSION_DIRECTIVE,

-                             token->location, token->text);

-        valid = false;

-    }

-    if (valid)

-        mDirectiveHandler->handleExtension(token->location, name, behavior);

-}

-

-void DirectiveParser::parseVersion(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_VERSION);

-

-    if (mPastFirstStatement)

-    {

-        mDiagnostics->report(Diagnostics::VERSION_NOT_FIRST_STATEMENT,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        return;

-    }

-

-    enum State

-    {

-        VERSION_NUMBER,

-        VERSION_PROFILE,

-        VERSION_ENDLINE

-    };

-

-    bool valid = true;

-    int version = 0;

-    int state = VERSION_NUMBER;

-

-    mTokenizer->lex(token);

-    while (valid && (token->type != '\n') && (token->type != Token::LAST))

-    {

-        switch (state)

-        {

-          case VERSION_NUMBER:

-            if (token->type != Token::CONST_INT)

-            {

-                mDiagnostics->report(Diagnostics::INVALID_VERSION_NUMBER,

-                                     token->location, token->text);

-                valid = false;

-            }

-            if (valid && !token->iValue(&version))

-            {

-                mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,

-                                     token->location, token->text);

-                valid = false;

-            }

-            if (valid)

-            {

-                state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE;

-            }

-            break;

-          case VERSION_PROFILE:

-            if (token->type != Token::IDENTIFIER || token->text != "es")

-            {

-                mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,

-                                     token->location, token->text);

-                valid = false;

-            }

-            state = VERSION_ENDLINE;

-            break;

-          default:

-            mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                                 token->location, token->text);

-            valid = false;

-            break;

-        }

-

-        mTokenizer->lex(token);

-    }

-

-    if (valid && (state != VERSION_ENDLINE))

-    {

-        mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,

-                             token->location, token->text);

-        valid = false;

-    }

-

-    if (valid)

-    {

-        mDirectiveHandler->handleVersion(token->location, version);

-    }

-}

-

-void DirectiveParser::parseLine(Token* token)

-{

-    assert(getDirective(token) == DIRECTIVE_LINE);

-

-    enum State

-    {

-        LINE_NUMBER,

-        FILE_NUMBER

-    };

-

-    bool valid = true;

-    int line = 0, file = 0;

-    int state = LINE_NUMBER;

-

-    MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false);

-    macroExpander.lex(token);

-    while ((token->type != '\n') && (token->type != Token::LAST))

-    {

-        switch (state++)

-        {

-          case LINE_NUMBER:

-            if (valid && (token->type != Token::CONST_INT))

-            {

-                mDiagnostics->report(Diagnostics::INVALID_LINE_NUMBER,

-                                     token->location, token->text);

-                valid = false;

-            }

-            if (valid && !token->iValue(&line))

-            {

-                mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,

-                                     token->location, token->text);

-                valid = false;

-            }

-            break;

-          case FILE_NUMBER:

-            if (valid && (token->type != Token::CONST_INT))

-            {

-                mDiagnostics->report(Diagnostics::INVALID_FILE_NUMBER,

-                                     token->location, token->text);

-                valid = false;

-            }

-            if (valid && !token->iValue(&file))

-            {

-                mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,

-                                     token->location, token->text);

-                valid = false;

-            }

-            break;

-          default:

-            if (valid)

-            {

-                mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                                     token->location, token->text);

-                valid = false;

-            }

-            break;

-        }

-        macroExpander.lex(token);

-    }

-

-    if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))

-    {

-        mDiagnostics->report(Diagnostics::INVALID_LINE_DIRECTIVE,

-                             token->location, token->text);

-        valid = false;

-    }

-    if (valid)

-    {

-        mTokenizer->setLineNumber(line);

-        if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file);

-    }

-}

-

-bool DirectiveParser::skipping() const

-{

-    if (mConditionalStack.empty()) return false;

-

-    const ConditionalBlock& block = mConditionalStack.back();

-    return block.skipBlock || block.skipGroup;

-}

-

-void DirectiveParser::parseConditionalIf(Token* token)

-{

-    ConditionalBlock block;

-    block.type = token->text;

-    block.location = token->location;

-

-    if (skipping())

-    {

-        // This conditional block is inside another conditional group

-        // which is skipped. As a consequence this whole block is skipped.

-        // Be careful not to parse the conditional expression that might

-        // emit a diagnostic.

-        skipUntilEOD(mTokenizer, token);

-        block.skipBlock = true;

-    }

-    else

-    {

-        DirectiveType directive = getDirective(token);

-

-        int expression = 0;

-        switch (directive)

-        {

-          case DIRECTIVE_IF:

-            expression = parseExpressionIf(token);

-            break;

-          case DIRECTIVE_IFDEF:

-            expression = parseExpressionIfdef(token);

-            break;

-          case DIRECTIVE_IFNDEF:

-            expression = parseExpressionIfdef(token) == 0 ? 1 : 0;

-            break;

-          default:

-            assert(false);

-            break;

-        }

-        block.skipGroup = expression == 0;

-        block.foundValidGroup = expression != 0;

-    }

-    mConditionalStack.push_back(block);

-}

-

-int DirectiveParser::parseExpressionIf(Token* token)

-{

-    assert((getDirective(token) == DIRECTIVE_IF) ||

-           (getDirective(token) == DIRECTIVE_ELIF));

-

-    MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true);

-    ExpressionParser expressionParser(&macroExpander, mDiagnostics);

-

-    int expression = 0;

-    macroExpander.lex(token);

-    expressionParser.parse(token, &expression);

-

-    // Check if there are tokens after #if expression.

-    if (!isEOD(token))

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-    }

-

-    return expression;

-}

-

-int DirectiveParser::parseExpressionIfdef(Token* token)

-{

-    assert((getDirective(token) == DIRECTIVE_IFDEF) ||

-           (getDirective(token) == DIRECTIVE_IFNDEF));

-

-    mTokenizer->lex(token);

-    if (token->type != Token::IDENTIFIER)

-    {

-        mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-        return 0;

-    }

-

-    MacroSet::const_iterator iter = mMacroSet->find(token->text);

-    int expression = iter != mMacroSet->end() ? 1 : 0;

-

-    // Check if there are tokens after #ifdef expression.

-    mTokenizer->lex(token);

-    if (!isEOD(token))

-    {

-        mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,

-                             token->location, token->text);

-        skipUntilEOD(mTokenizer, token);

-    }

-    return expression;

-}

-

-}  // namespace pp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "DirectiveParser.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <sstream>
+
+#include "Diagnostics.h"
+#include "DirectiveHandler.h"
+#include "ExpressionParser.h"
+#include "MacroExpander.h"
+#include "Token.h"
+#include "Tokenizer.h"
+
+namespace {
+enum DirectiveType
+{
+	DIRECTIVE_NONE,
+	DIRECTIVE_DEFINE,
+	DIRECTIVE_UNDEF,
+	DIRECTIVE_IF,
+	DIRECTIVE_IFDEF,
+	DIRECTIVE_IFNDEF,
+	DIRECTIVE_ELSE,
+	DIRECTIVE_ELIF,
+	DIRECTIVE_ENDIF,
+	DIRECTIVE_ERROR,
+	DIRECTIVE_PRAGMA,
+	DIRECTIVE_EXTENSION,
+	DIRECTIVE_VERSION,
+	DIRECTIVE_LINE
+};
+}  // namespace
+
+static DirectiveType getDirective(const pp::Token* token)
+{
+	static const std::string kDirectiveDefine("define");
+	static const std::string kDirectiveUndef("undef");
+	static const std::string kDirectiveIf("if");
+	static const std::string kDirectiveIfdef("ifdef");
+	static const std::string kDirectiveIfndef("ifndef");
+	static const std::string kDirectiveElse("else");
+	static const std::string kDirectiveElif("elif");
+	static const std::string kDirectiveEndif("endif");
+	static const std::string kDirectiveError("error");
+	static const std::string kDirectivePragma("pragma");
+	static const std::string kDirectiveExtension("extension");
+	static const std::string kDirectiveVersion("version");
+	static const std::string kDirectiveLine("line");
+
+	if (token->type != pp::Token::IDENTIFIER)
+		return DIRECTIVE_NONE;
+
+	if (token->text == kDirectiveDefine)
+		return DIRECTIVE_DEFINE;
+	else if (token->text == kDirectiveUndef)
+		return DIRECTIVE_UNDEF;
+	else if (token->text == kDirectiveIf)
+		return DIRECTIVE_IF;
+	else if (token->text == kDirectiveIfdef)
+		return DIRECTIVE_IFDEF;
+	else if (token->text == kDirectiveIfndef)
+		return DIRECTIVE_IFNDEF;
+	else if (token->text == kDirectiveElse)
+		return DIRECTIVE_ELSE;
+	else if (token->text == kDirectiveElif)
+		return DIRECTIVE_ELIF;
+	else if (token->text == kDirectiveEndif)
+		return DIRECTIVE_ENDIF;
+	else if (token->text == kDirectiveError)
+		return DIRECTIVE_ERROR;
+	else if (token->text == kDirectivePragma)
+		return DIRECTIVE_PRAGMA;
+	else if (token->text == kDirectiveExtension)
+		return DIRECTIVE_EXTENSION;
+	else if (token->text == kDirectiveVersion)
+		return DIRECTIVE_VERSION;
+	else if (token->text == kDirectiveLine)
+		return DIRECTIVE_LINE;
+
+	return DIRECTIVE_NONE;
+}
+
+static bool isConditionalDirective(DirectiveType directive)
+{
+	switch (directive)
+	{
+	case DIRECTIVE_IF:
+	case DIRECTIVE_IFDEF:
+	case DIRECTIVE_IFNDEF:
+	case DIRECTIVE_ELSE:
+	case DIRECTIVE_ELIF:
+	case DIRECTIVE_ENDIF:
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true if the token represents End Of Directive.
+static bool isEOD(const pp::Token* token)
+{
+	return (token->type == '\n') || (token->type == pp::Token::LAST);
+}
+
+static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token)
+{
+	while(!isEOD(token))
+	{
+		lexer->lex(token);
+	}
+}
+
+static bool isMacroNameReserved(const std::string& name)
+{
+	// Names prefixed with "GL_" are reserved.
+	if (name.substr(0, 3) == "GL_")
+		return true;
+
+	// Names containing two consecutive underscores are reserved.
+	if (name.find("__") != std::string::npos)
+		return true;
+
+	return false;
+}
+
+static bool isMacroPredefined(const std::string& name,
+                              const pp::MacroSet& macroSet)
+{
+	pp::MacroSet::const_iterator iter = macroSet.find(name);
+	return iter != macroSet.end() ? iter->second.predefined : false;
+}
+
+namespace pp
+{
+
+DirectiveParser::DirectiveParser(Tokenizer* tokenizer,
+                                 MacroSet* macroSet,
+                                 Diagnostics* diagnostics,
+                                 DirectiveHandler* directiveHandler) :
+	mPastFirstStatement(false),
+	mTokenizer(tokenizer),
+	mMacroSet(macroSet),
+	mDiagnostics(diagnostics),
+	mDirectiveHandler(directiveHandler)
+{
+}
+
+void DirectiveParser::lex(Token* token)
+{
+	do
+	{
+		mTokenizer->lex(token);
+
+		if (token->type == Token::PP_HASH)
+		{
+			parseDirective(token);
+			mPastFirstStatement = true;
+		}
+
+		if (token->type == Token::LAST)
+		{
+			if (!mConditionalStack.empty())
+			{
+				const ConditionalBlock& block = mConditionalStack.back();
+				mDiagnostics->report(Diagnostics::CONDITIONAL_UNTERMINATED,
+				                     block.location, block.type);
+			}
+			break;
+		}
+
+	} while (skipping() || (token->type == '\n'));
+
+	mPastFirstStatement = true;
+}
+
+void DirectiveParser::parseDirective(Token* token)
+{
+	assert(token->type == Token::PP_HASH);
+
+	mTokenizer->lex(token);
+	if (isEOD(token))
+	{
+		// Empty Directive.
+		return;
+	}
+
+	DirectiveType directive = getDirective(token);
+
+	// While in an excluded conditional block/group,
+	// we only parse conditional directives.
+	if (skipping() && !isConditionalDirective(directive))
+	{
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	switch(directive)
+	{
+	case DIRECTIVE_NONE:
+		mDiagnostics->report(Diagnostics::DIRECTIVE_INVALID_NAME,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		break;
+	case DIRECTIVE_DEFINE:
+		parseDefine(token);
+		break;
+	case DIRECTIVE_UNDEF:
+		parseUndef(token);
+		break;
+	case DIRECTIVE_IF:
+		parseIf(token);
+		break;
+	case DIRECTIVE_IFDEF:
+		parseIfdef(token);
+		break;
+	case DIRECTIVE_IFNDEF:
+		parseIfndef(token);
+		break;
+	case DIRECTIVE_ELSE:
+		parseElse(token);
+		break;
+	case DIRECTIVE_ELIF:
+		parseElif(token);
+		break;
+	case DIRECTIVE_ENDIF:
+		parseEndif(token);
+		break;
+	case DIRECTIVE_ERROR:
+		parseError(token);
+		break;
+	case DIRECTIVE_PRAGMA:
+		parsePragma(token);
+		break;
+	case DIRECTIVE_EXTENSION:
+		parseExtension(token);
+		break;
+	case DIRECTIVE_VERSION:
+		parseVersion(token);
+		break;
+	case DIRECTIVE_LINE:
+		parseLine(token);
+		break;
+	default:
+		assert(false);
+		break;
+	}
+
+	skipUntilEOD(mTokenizer, token);
+	if (token->type == Token::LAST)
+	{
+		mDiagnostics->report(Diagnostics::EOF_IN_DIRECTIVE,
+		                     token->location, token->text);
+	}
+}
+
+void DirectiveParser::parseDefine(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_DEFINE);
+
+	mTokenizer->lex(token);
+	if (token->type != Token::IDENTIFIER)
+	{
+		mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		return;
+	}
+	if (isMacroPredefined(token->text, *mMacroSet))
+	{
+		mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_REDEFINED,
+		                     token->location, token->text);
+		return;
+	}
+	if (isMacroNameReserved(token->text))
+	{
+		mDiagnostics->report(Diagnostics::MACRO_NAME_RESERVED,
+		                     token->location, token->text);
+		return;
+	}
+
+	Macro macro;
+	macro.type = Macro::kTypeObj;
+	macro.name = token->text;
+
+	mTokenizer->lex(token);
+	if (token->type == '(' && !token->hasLeadingSpace())
+	{
+		// Function-like macro. Collect arguments.
+		macro.type = Macro::kTypeFunc;
+		do {
+			mTokenizer->lex(token);
+			if (token->type != Token::IDENTIFIER)
+				break;
+
+			if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end())
+			{
+				mDiagnostics->report(Diagnostics::MACRO_DUPLICATE_PARAMETER_NAMES,
+				                     token->location, token->text);
+				return;
+			}
+
+			macro.parameters.push_back(token->text);
+
+			mTokenizer->lex(token);  // Get ','.
+		} while (token->type == ',');
+
+		if (token->type != ')')
+		{
+			mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+			                     token->location,
+			                     token->text);
+			return;
+		}
+		mTokenizer->lex(token);  // Get ')'.
+	}
+
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		// Reset the token location because it is unnecessary in replacement
+		// list. Resetting it also allows us to reuse Token::equals() to
+		// compare macros.
+		token->location = SourceLocation();
+		macro.replacements.push_back(*token);
+		mTokenizer->lex(token);
+	}
+	if (!macro.replacements.empty())
+	{
+		// Whitespace preceding the replacement list is not considered part of
+		// the replacement list for either form of macro.
+		macro.replacements.front().setHasLeadingSpace(false);
+	}
+
+	// Check for macro redefinition.
+	MacroSet::const_iterator iter = mMacroSet->find(macro.name);
+	if (iter != mMacroSet->end() && !macro.equals(iter->second))
+	{
+		mDiagnostics->report(Diagnostics::MACRO_REDEFINED,
+		                     token->location,
+		                     macro.name);
+		return;
+	}
+	mMacroSet->insert(std::make_pair(macro.name, macro));
+}
+
+void DirectiveParser::parseUndef(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_UNDEF);
+
+	mTokenizer->lex(token);
+	if (token->type != Token::IDENTIFIER)
+	{
+		mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		return;
+	}
+
+	MacroSet::iterator iter = mMacroSet->find(token->text);
+	if (iter != mMacroSet->end())
+	{
+		if (iter->second.predefined)
+		{
+			mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_UNDEFINED,
+			                     token->location, token->text);
+		}
+		else
+		{
+			mMacroSet->erase(iter);
+		}
+	}
+
+	mTokenizer->lex(token);
+}
+
+void DirectiveParser::parseIf(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_IF);
+	parseConditionalIf(token);
+}
+
+void DirectiveParser::parseIfdef(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_IFDEF);
+	parseConditionalIf(token);
+}
+
+void DirectiveParser::parseIfndef(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_IFNDEF);
+	parseConditionalIf(token);
+}
+
+void DirectiveParser::parseElse(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ELSE);
+
+	if (mConditionalStack.empty())
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_WITHOUT_IF,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	ConditionalBlock& block = mConditionalStack.back();
+	if (block.skipBlock)
+	{
+		// No diagnostics. Just skip the whole line.
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+	if (block.foundElseGroup)
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_AFTER_ELSE,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	block.foundElseGroup = true;
+	block.skipGroup = block.foundValidGroup;
+	block.foundValidGroup = true;
+
+	// Check if there are extra tokens after #else.
+	mTokenizer->lex(token);
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+}
+
+void DirectiveParser::parseElif(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ELIF);
+
+	if (mConditionalStack.empty())
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_WITHOUT_IF,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	ConditionalBlock& block = mConditionalStack.back();
+	if (block.skipBlock)
+	{
+		// No diagnostics. Just skip the whole line.
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+	if (block.foundElseGroup)
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_AFTER_ELSE,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+	if (block.foundValidGroup)
+	{
+		// Do not parse the expression.
+		// Also be careful not to emit a diagnostic.
+		block.skipGroup = true;
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	int expression = parseExpressionIf(token);
+	block.skipGroup = expression == 0;
+	block.foundValidGroup = expression != 0;
+}
+
+void DirectiveParser::parseEndif(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ENDIF);
+
+	if (mConditionalStack.empty())
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_ENDIF_WITHOUT_IF,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	mConditionalStack.pop_back();
+
+	// Check if there are tokens after #endif.
+	mTokenizer->lex(token);
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+}
+
+void DirectiveParser::parseError(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_ERROR);
+
+	std::ostringstream stream;
+	mTokenizer->lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		stream << *token;
+		mTokenizer->lex(token);
+	}
+	mDirectiveHandler->handleError(token->location, stream.str());
+}
+
+// Parses pragma of form: #pragma name[(value)].
+void DirectiveParser::parsePragma(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_PRAGMA);
+
+	enum State
+	{
+		PRAGMA_NAME,
+		LEFT_PAREN,
+		PRAGMA_VALUE,
+		RIGHT_PAREN
+	};
+
+	bool valid = true;
+	std::string name, value;
+	int state = PRAGMA_NAME;
+
+	mTokenizer->lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch(state++)
+		{
+		case PRAGMA_NAME:
+			name = token->text;
+			valid = valid && (token->type == Token::IDENTIFIER);
+			break;
+		case LEFT_PAREN:
+			valid = valid && (token->type == '(');
+			break;
+		case PRAGMA_VALUE:
+			value = token->text;
+			valid = valid && (token->type == Token::IDENTIFIER);
+			break;
+		case RIGHT_PAREN:
+			valid = valid && (token->type == ')');
+			break;
+		default:
+			valid = false;
+			break;
+		}
+		mTokenizer->lex(token);
+	}
+
+	valid = valid && ((state == PRAGMA_NAME) ||     // Empty pragma.
+	                  (state == LEFT_PAREN) ||      // Without value.
+	                  (state == RIGHT_PAREN + 1));  // With value.
+	if (!valid)
+	{
+		mDiagnostics->report(Diagnostics::UNRECOGNIZED_PRAGMA,
+		                     token->location, name);
+	}
+	else if (state > PRAGMA_NAME)  // Do not notify for empty pragma.
+	{
+		mDirectiveHandler->handlePragma(token->location, name, value);
+	}
+}
+
+void DirectiveParser::parseExtension(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_EXTENSION);
+
+	enum State
+	{
+		EXT_NAME,
+		COLON,
+		EXT_BEHAVIOR
+	};
+
+	bool valid = true;
+	std::string name, behavior;
+	int state = EXT_NAME;
+
+	mTokenizer->lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch (state++)
+		{
+		case EXT_NAME:
+			if (valid && (token->type != Token::IDENTIFIER))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_EXTENSION_NAME,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid) name = token->text;
+			break;
+		case COLON:
+			if (valid && (token->type != ':'))
+			{
+				mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		case EXT_BEHAVIOR:
+			if (valid && (token->type != Token::IDENTIFIER))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_EXTENSION_BEHAVIOR,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid) behavior = token->text;
+			break;
+		default:
+			if (valid)
+			{
+				mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		}
+		mTokenizer->lex(token);
+	}
+	if (valid && (state != EXT_BEHAVIOR + 1))
+	{
+		mDiagnostics->report(Diagnostics::INVALID_EXTENSION_DIRECTIVE,
+		                     token->location, token->text);
+		valid = false;
+	}
+	if (valid)
+		mDirectiveHandler->handleExtension(token->location, name, behavior);
+}
+
+void DirectiveParser::parseVersion(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_VERSION);
+
+	if (mPastFirstStatement)
+	{
+		mDiagnostics->report(Diagnostics::VERSION_NOT_FIRST_STATEMENT,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return;
+	}
+
+	enum State
+	{
+		VERSION_NUMBER,
+		VERSION_PROFILE,
+		VERSION_ENDLINE
+	};
+
+	bool valid = true;
+	int version = 0;
+	int state = VERSION_NUMBER;
+
+	mTokenizer->lex(token);
+	while (valid && (token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch (state)
+		{
+		case VERSION_NUMBER:
+			if (token->type != Token::CONST_INT)
+			{
+				mDiagnostics->report(Diagnostics::INVALID_VERSION_NUMBER,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid && !token->iValue(&version))
+			{
+				mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid)
+			{
+				state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE;
+			}
+			break;
+		case VERSION_PROFILE:
+			if (token->type != Token::IDENTIFIER || token->text != "es")
+			{
+				mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
+				                     token->location, token->text);
+				valid = false;
+			}
+			state = VERSION_ENDLINE;
+			break;
+		default:
+			mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+			                     token->location, token->text);
+			valid = false;
+			break;
+		}
+
+		mTokenizer->lex(token);
+	}
+
+	if (valid && (state != VERSION_ENDLINE))
+	{
+		mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
+		                     token->location, token->text);
+		valid = false;
+	}
+
+	if (valid)
+	{
+		mDirectiveHandler->handleVersion(token->location, version);
+	}
+}
+
+void DirectiveParser::parseLine(Token* token)
+{
+	assert(getDirective(token) == DIRECTIVE_LINE);
+
+	enum State
+	{
+		LINE_NUMBER,
+		FILE_NUMBER
+	};
+
+	bool valid = true;
+	int line = 0, file = 0;
+	int state = LINE_NUMBER;
+
+	MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false);
+	macroExpander.lex(token);
+	while ((token->type != '\n') && (token->type != Token::LAST))
+	{
+		switch (state++)
+		{
+		case LINE_NUMBER:
+			if (valid && (token->type != Token::CONST_INT))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_LINE_NUMBER,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid && !token->iValue(&line))
+			{
+				mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		case FILE_NUMBER:
+			if (valid && (token->type != Token::CONST_INT))
+			{
+				mDiagnostics->report(Diagnostics::INVALID_FILE_NUMBER,
+				                     token->location, token->text);
+				valid = false;
+			}
+			if (valid && !token->iValue(&file))
+			{
+				mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		default:
+			if (valid)
+			{
+				mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+				                     token->location, token->text);
+				valid = false;
+			}
+			break;
+		}
+		macroExpander.lex(token);
+	}
+
+	if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))
+	{
+		mDiagnostics->report(Diagnostics::INVALID_LINE_DIRECTIVE,
+		                     token->location, token->text);
+		valid = false;
+	}
+	if (valid)
+	{
+		mTokenizer->setLineNumber(line);
+		if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file);
+	}
+}
+
+bool DirectiveParser::skipping() const
+{
+	if (mConditionalStack.empty()) return false;
+
+	const ConditionalBlock& block = mConditionalStack.back();
+	return block.skipBlock || block.skipGroup;
+}
+
+void DirectiveParser::parseConditionalIf(Token* token)
+{
+	ConditionalBlock block;
+	block.type = token->text;
+	block.location = token->location;
+
+	if (skipping())
+	{
+		// This conditional block is inside another conditional group
+		// which is skipped. As a consequence this whole block is skipped.
+		// Be careful not to parse the conditional expression that might
+		// emit a diagnostic.
+		skipUntilEOD(mTokenizer, token);
+		block.skipBlock = true;
+	}
+	else
+	{
+		DirectiveType directive = getDirective(token);
+
+		int expression = 0;
+		switch (directive)
+		{
+		case DIRECTIVE_IF:
+			expression = parseExpressionIf(token);
+			break;
+		case DIRECTIVE_IFDEF:
+			expression = parseExpressionIfdef(token);
+			break;
+		case DIRECTIVE_IFNDEF:
+			expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
+			break;
+		default:
+			assert(false);
+			break;
+		}
+		block.skipGroup = expression == 0;
+		block.foundValidGroup = expression != 0;
+	}
+	mConditionalStack.push_back(block);
+}
+
+int DirectiveParser::parseExpressionIf(Token* token)
+{
+	assert((getDirective(token) == DIRECTIVE_IF) ||
+	       (getDirective(token) == DIRECTIVE_ELIF));
+
+	MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true);
+	ExpressionParser expressionParser(&macroExpander, mDiagnostics);
+
+	int expression = 0;
+	macroExpander.lex(token);
+	expressionParser.parse(token, &expression);
+
+	// Check if there are tokens after #if expression.
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+
+	return expression;
+}
+
+int DirectiveParser::parseExpressionIfdef(Token* token)
+{
+	assert((getDirective(token) == DIRECTIVE_IFDEF) ||
+		   (getDirective(token) == DIRECTIVE_IFNDEF));
+
+	mTokenizer->lex(token);
+	if (token->type != Token::IDENTIFIER)
+	{
+		mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+		return 0;
+	}
+
+	MacroSet::const_iterator iter = mMacroSet->find(token->text);
+	int expression = iter != mMacroSet->end() ? 1 : 0;
+
+	// Check if there are tokens after #ifdef expression.
+	mTokenizer->lex(token);
+	if (!isEOD(token))
+	{
+		mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+		                     token->location, token->text);
+		skipUntilEOD(mTokenizer, token);
+	}
+	return expression;
+}
+
+}  // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveParser.h b/src/OpenGL/compiler/preprocessor/DirectiveParser.h
index 7b07392..b23a99e 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveParser.h
+++ b/src/OpenGL/compiler/preprocessor/DirectiveParser.h
@@ -1,82 +1,90 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_

-#define COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_

-

-#include "Lexer.h"

-#include "Macro.h"

-#include "pp_utils.h"

-#include "SourceLocation.h"

-

-namespace pp

-{

-

-class Diagnostics;

-class DirectiveHandler;

-class Tokenizer;

-

-class DirectiveParser : public Lexer

-{

-  public:

-    DirectiveParser(Tokenizer* tokenizer,

-                    MacroSet* macroSet,

-                    Diagnostics* diagnostics,

-                    DirectiveHandler* directiveHandler);

-

-    virtual void lex(Token* token);

-

-  private:

-    PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser);

-

-    void parseDirective(Token* token);

-    void parseDefine(Token* token);

-    void parseUndef(Token* token);

-    void parseIf(Token* token);

-    void parseIfdef(Token* token);

-    void parseIfndef(Token* token);

-    void parseElse(Token* token);

-    void parseElif(Token* token);

-    void parseEndif(Token* token);

-    void parseError(Token* token);

-    void parsePragma(Token* token);

-    void parseExtension(Token* token);

-    void parseVersion(Token* token);

-    void parseLine(Token* token);

-

-    bool skipping() const;

-    void parseConditionalIf(Token* token);

-    int parseExpressionIf(Token* token);

-    int parseExpressionIfdef(Token* token);

-

-    struct ConditionalBlock

-    {

-        std::string type;

-        SourceLocation location;

-        bool skipBlock;

-        bool skipGroup;

-        bool foundValidGroup;

-        bool foundElseGroup;

-

-        ConditionalBlock() :

-            skipBlock(false),

-            skipGroup(false),

-            foundValidGroup(false),

-            foundElseGroup(false)

-        {

-        }

-    };

-    bool mPastFirstStatement;

-    std::vector<ConditionalBlock> mConditionalStack;

-    Tokenizer* mTokenizer;

-    MacroSet* mMacroSet;

-    Diagnostics* mDiagnostics;

-    DirectiveHandler* mDirectiveHandler;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
+#define COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
+
+#include "Lexer.h"
+#include "Macro.h"
+#include "pp_utils.h"
+#include "SourceLocation.h"
+
+namespace pp
+{
+
+class Diagnostics;
+class DirectiveHandler;
+class Tokenizer;
+
+class DirectiveParser : public Lexer
+{
+public:
+	DirectiveParser(Tokenizer* tokenizer,
+	                MacroSet* macroSet,
+	                Diagnostics* diagnostics,
+	                DirectiveHandler* directiveHandler);
+
+	virtual void lex(Token* token);
+
+private:
+	PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser);
+
+	void parseDirective(Token* token);
+	void parseDefine(Token* token);
+	void parseUndef(Token* token);
+	void parseIf(Token* token);
+	void parseIfdef(Token* token);
+	void parseIfndef(Token* token);
+	void parseElse(Token* token);
+	void parseElif(Token* token);
+	void parseEndif(Token* token);
+	void parseError(Token* token);
+	void parsePragma(Token* token);
+	void parseExtension(Token* token);
+	void parseVersion(Token* token);
+	void parseLine(Token* token);
+
+	bool skipping() const;
+	void parseConditionalIf(Token* token);
+	int parseExpressionIf(Token* token);
+	int parseExpressionIfdef(Token* token);
+
+	struct ConditionalBlock
+	{
+		std::string type;
+		SourceLocation location;
+		bool skipBlock;
+		bool skipGroup;
+		bool foundValidGroup;
+		bool foundElseGroup;
+
+		ConditionalBlock() :
+			skipBlock(false),
+			skipGroup(false),
+			foundValidGroup(false),
+			foundElseGroup(false)
+		{
+		}
+	};
+	bool mPastFirstStatement;
+	std::vector<ConditionalBlock> mConditionalStack;
+	Tokenizer* mTokenizer;
+	MacroSet* mMacroSet;
+	Diagnostics* mDiagnostics;
+	DirectiveHandler* mDirectiveHandler;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
+
diff --git a/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp b/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp
index 7a8892e..b2aa9d7 100644
--- a/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp
+++ b/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp
@@ -70,11 +70,19 @@
 /* Copy the first part of user declarations.  */
 
 
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
diff --git a/src/OpenGL/compiler/preprocessor/ExpressionParser.h b/src/OpenGL/compiler/preprocessor/ExpressionParser.h
index 3ee5b7a..c28f4bb 100644
--- a/src/OpenGL/compiler/preprocessor/ExpressionParser.h
+++ b/src/OpenGL/compiler/preprocessor/ExpressionParser.h
@@ -1,34 +1,42 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_

-#define COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_

-

-#include "pp_utils.h"

-

-namespace pp

-{

-

-class Diagnostics;

-class Lexer;

-struct Token;

-

-class ExpressionParser

-{

-  public:

-    ExpressionParser(Lexer* lexer, Diagnostics* diagnostics);

-

-    bool parse(Token* token, int* result);

-

-  private:

-    PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser);

-

-    Lexer* mLexer;

-    Diagnostics* mDiagnostics;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
+#define COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
+
+#include "pp_utils.h"
+
+namespace pp
+{
+
+class Diagnostics;
+class Lexer;
+struct Token;
+
+class ExpressionParser
+{
+public:
+	ExpressionParser(Lexer* lexer, Diagnostics* diagnostics);
+
+	bool parse(Token* token, int* result);
+
+private:
+	PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser);
+
+	Lexer* mLexer;
+	Diagnostics* mDiagnostics;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
diff --git a/src/OpenGL/compiler/preprocessor/ExpressionParser.y b/src/OpenGL/compiler/preprocessor/ExpressionParser.y
index 1324288..09e86aa 100644
--- a/src/OpenGL/compiler/preprocessor/ExpressionParser.y
+++ b/src/OpenGL/compiler/preprocessor/ExpressionParser.y
@@ -1,9 +1,17 @@
 /*
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 This file contains the Yacc grammar for GLSL ES preprocessor expression.
 
@@ -12,11 +20,19 @@
 */
 
 %{
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
diff --git a/src/OpenGL/compiler/preprocessor/Input.cpp b/src/OpenGL/compiler/preprocessor/Input.cpp
index 5cbf138..c22622a 100644
--- a/src/OpenGL/compiler/preprocessor/Input.cpp
+++ b/src/OpenGL/compiler/preprocessor/Input.cpp
@@ -1,55 +1,63 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "Input.h"

-

-#include <algorithm>

-#include <cassert>

-#include <cstring>

-

-namespace pp

-{

-

-Input::Input() : mCount(0), mString(0)

-{

-}

-

-Input::Input(int count, const char* const string[], const int length[]) :

-    mCount(count),

-    mString(string)

-{

-    assert(mCount >= 0);

-    mLength.reserve(mCount);

-    for (int i = 0; i < mCount; ++i)

-    {

-        int len = length ? length[i] : -1;

-        mLength.push_back(len < 0 ? strlen(mString[i]) : len);

-    }

-}

-

-int Input::read(char* buf, int maxSize)

-{

-    int nRead = 0;

-    while ((nRead < maxSize) && (mReadLoc.sIndex < mCount))

-    {

-        int size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;

-        size = std::min(size, maxSize);

-        memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);

-        nRead += size;

-        mReadLoc.cIndex += size;

-

-        // Advance string if we reached the end of current string.

-        if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])

-        {

-            ++mReadLoc.sIndex;

-            mReadLoc.cIndex = 0;

-        }

-    }

-    return nRead;

-}

-

-}  // namespace pp

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Input.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+
+namespace pp
+{
+
+Input::Input() : mCount(0), mString(0)
+{
+}
+
+Input::Input(int count, const char* const string[], const int length[]) :
+	mCount(count),
+	mString(string)
+{
+	assert(mCount >= 0);
+	mLength.reserve(mCount);
+	for (int i = 0; i < mCount; ++i)
+	{
+		int len = length ? length[i] : -1;
+		mLength.push_back(len < 0 ? strlen(mString[i]) : len);
+	}
+}
+
+int Input::read(char* buf, int maxSize)
+{
+	int nRead = 0;
+	while ((nRead < maxSize) && (mReadLoc.sIndex < mCount))
+	{
+		int size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
+		size = std::min(size, maxSize);
+		memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
+		nRead += size;
+		mReadLoc.cIndex += size;
+
+		// Advance string if we reached the end of current string.
+		if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
+		{
+			++mReadLoc.sIndex;
+			mReadLoc.cIndex = 0;
+		}
+	}
+	return nRead;
+}
+
+}  // namespace pp
+
diff --git a/src/OpenGL/compiler/preprocessor/Input.h b/src/OpenGL/compiler/preprocessor/Input.h
index 8e5b1e9..35776e7 100644
--- a/src/OpenGL/compiler/preprocessor/Input.h
+++ b/src/OpenGL/compiler/preprocessor/Input.h
@@ -1,48 +1,56 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_INPUT_H_

-#define COMPILER_PREPROCESSOR_INPUT_H_

-

-#include <vector>

-

-namespace pp

-{

-

-// Holds and reads input for Lexer.

-class Input

-{

-  public:

-    Input();

-    Input(int count, const char* const string[], const int length[]);

-

-    int count() const { return mCount; }

-    const char* string(int index) const { return mString[index]; }

-    int length(int index) const { return mLength[index]; }

-

-    int read(char* buf, int maxSize);

-

-    struct Location

-    {

-        int sIndex;  // String index;

-        int cIndex;  // Char index.

-

-        Location() : sIndex(0), cIndex(0) { }

-    };

-    const Location& readLoc() const { return mReadLoc; }

-

-  private:

-    // Input.

-    int mCount;

-    const char* const* mString;

-    std::vector<int> mLength;

-

-    Location mReadLoc;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_INPUT_H_

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_INPUT_H_
+#define COMPILER_PREPROCESSOR_INPUT_H_
+
+#include <vector>
+
+namespace pp
+{
+
+// Holds and reads input for Lexer.
+class Input
+{
+public:
+	Input();
+	Input(int count, const char* const string[], const int length[]);
+
+	int count() const { return mCount; }
+	const char* string(int index) const { return mString[index]; }
+	int length(int index) const { return mLength[index]; }
+
+	int read(char* buf, int maxSize);
+
+	struct Location
+	{
+		int sIndex;  // String index;
+		int cIndex;  // Char index.
+
+		Location() : sIndex(0), cIndex(0) { }
+	};
+	const Location& readLoc() const { return mReadLoc; }
+
+private:
+	// Input.
+	int mCount;
+	const char* const* mString;
+	std::vector<int> mLength;
+
+	Location mReadLoc;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_INPUT_H_
+
diff --git a/src/OpenGL/compiler/preprocessor/Lexer.cpp b/src/OpenGL/compiler/preprocessor/Lexer.cpp
index 231a906..157a998 100644
--- a/src/OpenGL/compiler/preprocessor/Lexer.cpp
+++ b/src/OpenGL/compiler/preprocessor/Lexer.cpp
@@ -1,16 +1,24 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "Lexer.h"

-

-namespace pp

-{

-

-Lexer::~Lexer()

-{

-}

-

-}  // namespace pp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Lexer.h"
+
+namespace pp
+{
+
+Lexer::~Lexer()
+{
+}
+
+}  // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Lexer.h b/src/OpenGL/compiler/preprocessor/Lexer.h
index cb29a10..558fc98 100644
--- a/src/OpenGL/compiler/preprocessor/Lexer.h
+++ b/src/OpenGL/compiler/preprocessor/Lexer.h
@@ -1,25 +1,33 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_LEXER_H_

-#define COMPILER_PREPROCESSOR_LEXER_H_

-

-namespace pp

-{

-

-struct Token;

-

-class Lexer

-{

-  public:

-    virtual ~Lexer();

-

-    virtual void lex(Token* token) = 0;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_LEXER_H_

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_LEXER_H_
+#define COMPILER_PREPROCESSOR_LEXER_H_
+
+namespace pp
+{
+
+struct Token;
+
+class Lexer
+{
+public:
+	virtual ~Lexer();
+
+	virtual void lex(Token* token) = 0;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_LEXER_H_
+
diff --git a/src/OpenGL/compiler/preprocessor/Macro.cpp b/src/OpenGL/compiler/preprocessor/Macro.cpp
index 3c57afe..9024f8a 100644
--- a/src/OpenGL/compiler/preprocessor/Macro.cpp
+++ b/src/OpenGL/compiler/preprocessor/Macro.cpp
@@ -1,23 +1,31 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "Macro.h"

-

-#include "Token.h"

-

-namespace pp

-{

-

-bool Macro::equals(const Macro& other) const

-{

-    return (type == other.type) &&

-           (name == other.name) &&

-           (parameters == other.parameters) &&

-           (replacements == other.replacements);

-}

-

-}  // namespace pp

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Macro.h"
+
+#include "Token.h"
+
+namespace pp
+{
+
+bool Macro::equals(const Macro& other) const
+{
+    return (type == other.type) &&
+           (name == other.name) &&
+           (parameters == other.parameters) &&
+           (replacements == other.replacements);
+}
+
+}  // namespace pp
+
diff --git a/src/OpenGL/compiler/preprocessor/Macro.h b/src/OpenGL/compiler/preprocessor/Macro.h
index 36faae9..bad8db3 100644
--- a/src/OpenGL/compiler/preprocessor/Macro.h
+++ b/src/OpenGL/compiler/preprocessor/Macro.h
@@ -1,44 +1,52 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_MACRO_H_

-#define COMPILER_PREPROCESSOR_MACRO_H_

-

-#include <map>

-#include <string>

-#include <vector>

-

-namespace pp

-{

-

-struct Token;

-

-struct Macro

-{

-    enum Type

-    {

-        kTypeObj,

-        kTypeFunc

-    };

-    typedef std::vector<std::string> Parameters;

-    typedef std::vector<Token> Replacements;

-

-    Macro() : predefined(false), disabled(false), type(kTypeObj) { }

-    bool equals(const Macro& other) const;

-

-    bool predefined;

-    mutable bool disabled;

-

-    Type type;

-    std::string name;

-    Parameters parameters;

-    Replacements replacements;

-};

-

-typedef std::map<std::string, Macro> MacroSet;

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_MACRO_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_MACRO_H_
+#define COMPILER_PREPROCESSOR_MACRO_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace pp
+{
+
+struct Token;
+
+struct Macro
+{
+    enum Type
+    {
+        kTypeObj,
+        kTypeFunc
+    };
+    typedef std::vector<std::string> Parameters;
+    typedef std::vector<Token> Replacements;
+
+    Macro() : predefined(false), disabled(false), type(kTypeObj) { }
+    bool equals(const Macro& other) const;
+
+    bool predefined;
+    mutable bool disabled;
+
+    Type type;
+    std::string name;
+    Parameters parameters;
+    Replacements replacements;
+};
+
+typedef std::map<std::string, Macro> MacroSet;
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_MACRO_H_
diff --git a/src/OpenGL/compiler/preprocessor/MacroExpander.cpp b/src/OpenGL/compiler/preprocessor/MacroExpander.cpp
index 325daba..31c14e4 100644
--- a/src/OpenGL/compiler/preprocessor/MacroExpander.cpp
+++ b/src/OpenGL/compiler/preprocessor/MacroExpander.cpp
@@ -1,410 +1,418 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "MacroExpander.h"

-

-#include <algorithm>

-#include <sstream>

-

-#include "Diagnostics.h"

-#include "Token.h"

-

-namespace pp

-{

-

-class TokenLexer : public Lexer

-{

- public:

-    typedef std::vector<Token> TokenVector;

-

-    TokenLexer(TokenVector* tokens)

-    {

-        tokens->swap(mTokens);

-        mIter = mTokens.begin();

-    }

-

-    virtual void lex(Token* token)

-    {

-        if (mIter == mTokens.end())

-        {

-            token->reset();

-            token->type = Token::LAST;

-        }

-        else

-        {

-            *token = *mIter++;

-        }

-    }

-

- private:

-    PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer);

-

-    TokenVector mTokens;

-    TokenVector::const_iterator mIter;

-};

-

-MacroExpander::MacroExpander(Lexer* lexer,

-                             MacroSet* macroSet,

-                             Diagnostics* diagnostics,

-                             bool parseDefined) :

-    mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mParseDefined(parseDefined)

-{

-}

-

-MacroExpander::~MacroExpander()

-{

-    for (size_t i = 0; i < mContextStack.size(); ++i)

-    {

-        delete mContextStack[i];

-    }

-}

-

-void MacroExpander::lex(Token* token)

-{

-    while (true)

-    {

-        getToken(token);

-

-        if (token->type != Token::IDENTIFIER)

-            break;

-

-		// Defined operator is parsed here since it may be generated by macro expansion.

-        // Defined operator produced by macro expansion has undefined behavior according to C++

-        // spec, which the GLSL spec references (see C++14 draft spec section 16.1.4), but this

-        // behavior is needed for passing dEQP tests, which enforce stricter compatibility between

-        // implementations.

-        if (mParseDefined && token->text == "defined")

-        {

-            bool paren = false;

-            getToken(token);

-            if (token->type == '(')

-            {

-                paren = true;

-                getToken(token);

-            }

-            if (token->type != Token::IDENTIFIER)

-            {

-                mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, token->location,

-                                     token->text);

-                break;

-            }

-            auto iter = mMacroSet->find(token->text);

-            std::string expression = iter != mMacroSet->end() ? "1" : "0";

-

-            if (paren)

-            {

-                getToken(token);

-                if (token->type != ')')

-                {

-                    mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, token->location,

-                                         token->text);

-                    break;

-                }

-            }

-

-            // We have a valid defined operator.

-            // Convert the current token into a CONST_INT token.

-            token->type = Token::CONST_INT;

-            token->text = expression;

-            break;

-        }

-

-        if (token->expansionDisabled())

-            break;

-

-        MacroSet::const_iterator iter = mMacroSet->find(token->text);

-        if (iter == mMacroSet->end())

-            break;

-

-        const Macro& macro = iter->second;

-        if (macro.disabled)

-        {

-            // If a particular token is not expanded, it is never expanded.

-            token->setExpansionDisabled(true);

-            break;

-        }

-        if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen())

-        {

-            // If the token immediately after the macro name is not a '(',

-            // this macro should not be expanded.

-            break;

-        }

-

-        pushMacro(macro, *token);

-    }

-}

-

-void MacroExpander::getToken(Token* token)

-{

-    if (mReserveToken.get())

-    {

-        *token = *mReserveToken;

-        mReserveToken.reset();

-        return;

-    }

-

-    // First pop all empty macro contexts.

-    while (!mContextStack.empty() && mContextStack.back()->empty())

-    {

-        popMacro();

-    }

-

-    if (!mContextStack.empty())

-    {

-        *token = mContextStack.back()->get();

-    }

-    else

-    {

-        mLexer->lex(token);

-    }

-}

-

-void MacroExpander::ungetToken(const Token& token)

-{

-    if (!mContextStack.empty())

-    {

-        MacroContext* context = mContextStack.back();

-        context->unget();

-        assert(context->replacements[context->index] == token);

-    }

-    else

-    {

-        assert(!mReserveToken.get());

-        mReserveToken.reset(new Token(token));

-    }

-}

-

-bool MacroExpander::isNextTokenLeftParen()

-{

-    Token token;

-    getToken(&token);

-

-    bool lparen = token.type == '(';

-    ungetToken(token);

-

-    return lparen;

-}

-

-bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier)

-{

-    assert(!macro.disabled);

-    assert(!identifier.expansionDisabled());

-    assert(identifier.type == Token::IDENTIFIER);

-    assert(identifier.text == macro.name);

-

-    std::vector<Token> replacements;

-    if (!expandMacro(macro, identifier, &replacements))

-        return false;

-

-    // Macro is disabled for expansion until it is popped off the stack.

-    macro.disabled = true;

-

-    MacroContext* context = new MacroContext;

-    context->macro = &macro;

-    context->replacements.swap(replacements);

-    mContextStack.push_back(context);

-    return true;

-}

-

-void MacroExpander::popMacro()

-{

-    assert(!mContextStack.empty());

-

-    MacroContext* context = mContextStack.back();

-    mContextStack.pop_back();

-

-    assert(context->empty());

-    assert(context->macro->disabled);

-    context->macro->disabled = false;

-    delete context;

-}

-

-bool MacroExpander::expandMacro(const Macro& macro,

-                                const Token& identifier,

-                                std::vector<Token>* replacements)

-{

-    replacements->clear();

-    if (macro.type == Macro::kTypeObj)

-    {

-        replacements->assign(macro.replacements.begin(),

-                             macro.replacements.end());

-

-        if (macro.predefined)

-        {

-            static const std::string kLine = "__LINE__";

-            static const std::string kFile = "__FILE__";

-

-            assert(replacements->size() == 1);

-            Token& repl = replacements->front();

-            if (macro.name == kLine)

-            {

-                std::ostringstream stream;

-                stream << identifier.location.line;

-                repl.text = stream.str();

-            }

-            else if (macro.name == kFile)

-            {

-                std::ostringstream stream;

-                stream << identifier.location.file;

-                repl.text = stream.str();

-            }

-        }

-    }

-    else

-    {

-        assert(macro.type == Macro::kTypeFunc);

-        std::vector<MacroArg> args;

-        args.reserve(macro.parameters.size());

-        if (!collectMacroArgs(macro, identifier, &args))

-            return false;

-

-        replaceMacroParams(macro, args, replacements);

-    }

-

-    for (size_t i = 0; i < replacements->size(); ++i)

-    {

-        Token& repl = replacements->at(i);

-        if (i == 0)

-        {

-            // The first token in the replacement list inherits the padding

-            // properties of the identifier token.

-            repl.setAtStartOfLine(identifier.atStartOfLine());

-            repl.setHasLeadingSpace(identifier.hasLeadingSpace());

-        }

-        repl.location = identifier.location;

-    }

-    return true;

-}

-

-bool MacroExpander::collectMacroArgs(const Macro& macro,

-                                     const Token& identifier,

-                                     std::vector<MacroArg>* args)

-{

-    Token token;

-    getToken(&token);

-    assert(token.type == '(');

-

-    args->push_back(MacroArg());

-    for (int openParens = 1; openParens != 0; )

-    {

-        getToken(&token);

-

-        if (token.type == Token::LAST)

-        {

-            mDiagnostics->report(Diagnostics::MACRO_UNTERMINATED_INVOCATION,

-                                 identifier.location, identifier.text);

-            // Do not lose EOF token.

-            ungetToken(token);

-            return false;

-        }

-

-        bool isArg = false; // True if token is part of the current argument.

-        switch (token.type)

-        {

-          case '(':

-            ++openParens;

-            isArg = true;

-            break;

-          case ')':

-            --openParens;

-            isArg = openParens != 0;

-            break;

-          case ',':

-            // The individual arguments are separated by comma tokens, but

-            // the comma tokens between matching inner parentheses do not

-            // seperate arguments.

-            if (openParens == 1) args->push_back(MacroArg());

-            isArg = openParens != 1;

-            break;

-          default:

-            isArg = true;

-            break;

-        }

-        if (isArg)

-        {

-            MacroArg& arg = args->back();

-            // Initial whitespace is not part of the argument.

-            if (arg.empty()) token.setHasLeadingSpace(false);

-            arg.push_back(token);

-        }

-    }

-

-    const Macro::Parameters& params = macro.parameters;

-    // If there is only one empty argument, it is equivalent to no argument.

-    if (params.empty() && (args->size() == 1) && args->front().empty())

-    {

-        args->clear();

-    }

-    // Validate the number of arguments.

-    if (args->size() != params.size())

-    {

-        Diagnostics::ID id = args->size() < macro.parameters.size() ?

-            Diagnostics::MACRO_TOO_FEW_ARGS :

-            Diagnostics::MACRO_TOO_MANY_ARGS;

-        mDiagnostics->report(id, identifier.location, identifier.text);

-        return false;

-    }

-

-    // Pre-expand each argument before substitution.

-    // This step expands each argument individually before they are

-    // inserted into the macro body.

-    for (size_t i = 0; i < args->size(); ++i)

-    {

-        MacroArg& arg = args->at(i);

-        TokenLexer lexer(&arg);

-        MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined);

-

-        arg.clear();

-        expander.lex(&token);

-        while (token.type != Token::LAST)

-        {

-            arg.push_back(token);

-            expander.lex(&token);

-        }

-    }

-    return true;

-}

-

-void MacroExpander::replaceMacroParams(const Macro& macro,

-                                       const std::vector<MacroArg>& args,

-                                       std::vector<Token>* replacements)

-{

-    for (size_t i = 0; i < macro.replacements.size(); ++i)

-    {

-        const Token& repl = macro.replacements[i];

-        if (repl.type != Token::IDENTIFIER)

-        {

-            replacements->push_back(repl);

-            continue;

-        }

-

-        // TODO(alokp): Optimize this.

-        // There is no need to search for macro params every time.

-        // The param index can be cached with the replacement token.

-        Macro::Parameters::const_iterator iter = std::find(

-            macro.parameters.begin(), macro.parameters.end(), repl.text);

-        if (iter == macro.parameters.end())

-        {

-            replacements->push_back(repl);

-            continue;

-        }

-

-        size_t iArg = std::distance(macro.parameters.begin(), iter);

-        const MacroArg& arg = args[iArg];

-        if (arg.empty())

-        {

-            continue;

-        }

-        size_t iRepl = replacements->size();

-        replacements->insert(replacements->end(), arg.begin(), arg.end());

-        // The replacement token inherits padding properties from

-        // macro replacement token.

-        replacements->at(iRepl).setHasLeadingSpace(repl.hasLeadingSpace());

-    }

-}

-

-}  // namespace pp

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "MacroExpander.h"
+
+#include <algorithm>
+#include <sstream>
+
+#include "Diagnostics.h"
+#include "Token.h"
+
+namespace pp
+{
+
+class TokenLexer : public Lexer
+{
+ public:
+	typedef std::vector<Token> TokenVector;
+
+	TokenLexer(TokenVector* tokens)
+	{
+		tokens->swap(mTokens);
+		mIter = mTokens.begin();
+	}
+
+	virtual void lex(Token* token)
+	{
+		if (mIter == mTokens.end())
+		{
+			token->reset();
+			token->type = Token::LAST;
+		}
+		else
+		{
+			*token = *mIter++;
+		}
+	}
+
+ private:
+	PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer);
+
+	TokenVector mTokens;
+	TokenVector::const_iterator mIter;
+};
+
+MacroExpander::MacroExpander(Lexer* lexer,
+                             MacroSet* macroSet,
+                             Diagnostics* diagnostics,
+                             bool parseDefined) :
+	mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mParseDefined(parseDefined)
+{
+}
+
+MacroExpander::~MacroExpander()
+{
+	for (size_t i = 0; i < mContextStack.size(); ++i)
+	{
+		delete mContextStack[i];
+	}
+}
+
+void MacroExpander::lex(Token* token)
+{
+	while (true)
+	{
+		getToken(token);
+
+		if (token->type != Token::IDENTIFIER)
+			break;
+
+		// Defined operator is parsed here since it may be generated by macro expansion.
+		// Defined operator produced by macro expansion has undefined behavior according to C++
+		// spec, which the GLSL spec references (see C++14 draft spec section 16.1.4), but this
+		// behavior is needed for passing dEQP tests, which enforce stricter compatibility between
+		// implementations.
+		if (mParseDefined && token->text == "defined")
+		{
+			bool paren = false;
+			getToken(token);
+			if (token->type == '(')
+			{
+				paren = true;
+				getToken(token);
+			}
+			if (token->type != Token::IDENTIFIER)
+			{
+				mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, token->location,
+				                     token->text);
+				break;
+			}
+			auto iter = mMacroSet->find(token->text);
+			std::string expression = iter != mMacroSet->end() ? "1" : "0";
+
+			if (paren)
+			{
+				getToken(token);
+				if (token->type != ')')
+				{
+					mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, token->location,
+					                     token->text);
+					break;
+				}
+			}
+
+			// We have a valid defined operator.
+			// Convert the current token into a CONST_INT token.
+			token->type = Token::CONST_INT;
+			token->text = expression;
+			break;
+		}
+
+		if (token->expansionDisabled())
+			break;
+
+		MacroSet::const_iterator iter = mMacroSet->find(token->text);
+		if (iter == mMacroSet->end())
+			break;
+
+		const Macro& macro = iter->second;
+		if (macro.disabled)
+		{
+			// If a particular token is not expanded, it is never expanded.
+			token->setExpansionDisabled(true);
+			break;
+		}
+		if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen())
+		{
+			// If the token immediately after the macro name is not a '(',
+			// this macro should not be expanded.
+			break;
+		}
+
+		pushMacro(macro, *token);
+	}
+}
+
+void MacroExpander::getToken(Token* token)
+{
+	if (mReserveToken.get())
+	{
+		*token = *mReserveToken;
+		mReserveToken.reset();
+		return;
+	}
+
+	// First pop all empty macro contexts.
+	while (!mContextStack.empty() && mContextStack.back()->empty())
+	{
+		popMacro();
+	}
+
+	if (!mContextStack.empty())
+	{
+		*token = mContextStack.back()->get();
+	}
+	else
+	{
+		mLexer->lex(token);
+	}
+}
+
+void MacroExpander::ungetToken(const Token& token)
+{
+	if (!mContextStack.empty())
+	{
+		MacroContext* context = mContextStack.back();
+		context->unget();
+		assert(context->replacements[context->index] == token);
+	}
+	else
+	{
+		assert(!mReserveToken.get());
+		mReserveToken.reset(new Token(token));
+	}
+}
+
+bool MacroExpander::isNextTokenLeftParen()
+{
+	Token token;
+	getToken(&token);
+
+	bool lparen = token.type == '(';
+	ungetToken(token);
+
+	return lparen;
+}
+
+bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier)
+{
+	assert(!macro.disabled);
+	assert(!identifier.expansionDisabled());
+	assert(identifier.type == Token::IDENTIFIER);
+	assert(identifier.text == macro.name);
+
+	std::vector<Token> replacements;
+	if (!expandMacro(macro, identifier, &replacements))
+		return false;
+
+	// Macro is disabled for expansion until it is popped off the stack.
+	macro.disabled = true;
+
+	MacroContext* context = new MacroContext;
+	context->macro = &macro;
+	context->replacements.swap(replacements);
+	mContextStack.push_back(context);
+	return true;
+}
+
+void MacroExpander::popMacro()
+{
+	assert(!mContextStack.empty());
+
+	MacroContext* context = mContextStack.back();
+	mContextStack.pop_back();
+
+	assert(context->empty());
+	assert(context->macro->disabled);
+	context->macro->disabled = false;
+	delete context;
+}
+
+bool MacroExpander::expandMacro(const Macro& macro,
+                                const Token& identifier,
+                                std::vector<Token>* replacements)
+{
+	replacements->clear();
+	if (macro.type == Macro::kTypeObj)
+	{
+		replacements->assign(macro.replacements.begin(),
+		                     macro.replacements.end());
+
+		if (macro.predefined)
+		{
+			static const std::string kLine = "__LINE__";
+			static const std::string kFile = "__FILE__";
+
+			assert(replacements->size() == 1);
+			Token& repl = replacements->front();
+			if (macro.name == kLine)
+			{
+				std::ostringstream stream;
+				stream << identifier.location.line;
+				repl.text = stream.str();
+			}
+			else if (macro.name == kFile)
+			{
+				std::ostringstream stream;
+				stream << identifier.location.file;
+				repl.text = stream.str();
+			}
+		}
+	}
+	else
+	{
+		assert(macro.type == Macro::kTypeFunc);
+		std::vector<MacroArg> args;
+		args.reserve(macro.parameters.size());
+		if (!collectMacroArgs(macro, identifier, &args))
+			return false;
+
+		replaceMacroParams(macro, args, replacements);
+	}
+
+	for (size_t i = 0; i < replacements->size(); ++i)
+	{
+		Token& repl = replacements->at(i);
+		if (i == 0)
+		{
+			// The first token in the replacement list inherits the padding
+			// properties of the identifier token.
+			repl.setAtStartOfLine(identifier.atStartOfLine());
+			repl.setHasLeadingSpace(identifier.hasLeadingSpace());
+		}
+		repl.location = identifier.location;
+	}
+	return true;
+}
+
+bool MacroExpander::collectMacroArgs(const Macro& macro,
+                                     const Token& identifier,
+                                     std::vector<MacroArg>* args)
+{
+	Token token;
+	getToken(&token);
+	assert(token.type == '(');
+
+	args->push_back(MacroArg());
+	for (int openParens = 1; openParens != 0; )
+	{
+		getToken(&token);
+
+		if (token.type == Token::LAST)
+		{
+			mDiagnostics->report(Diagnostics::MACRO_UNTERMINATED_INVOCATION,
+			                     identifier.location, identifier.text);
+			// Do not lose EOF token.
+			ungetToken(token);
+			return false;
+		}
+
+		bool isArg = false; // True if token is part of the current argument.
+		switch (token.type)
+		{
+		case '(':
+			++openParens;
+			isArg = true;
+			break;
+		case ')':
+			--openParens;
+			isArg = openParens != 0;
+			break;
+		case ',':
+			// The individual arguments are separated by comma tokens, but
+			// the comma tokens between matching inner parentheses do not
+			// seperate arguments.
+			if (openParens == 1) args->push_back(MacroArg());
+			isArg = openParens != 1;
+			break;
+		default:
+			isArg = true;
+			break;
+		}
+		if (isArg)
+		{
+			MacroArg& arg = args->back();
+			// Initial whitespace is not part of the argument.
+			if (arg.empty()) token.setHasLeadingSpace(false);
+			arg.push_back(token);
+		}
+	}
+
+	const Macro::Parameters& params = macro.parameters;
+	// If there is only one empty argument, it is equivalent to no argument.
+	if (params.empty() && (args->size() == 1) && args->front().empty())
+	{
+		args->clear();
+	}
+	// Validate the number of arguments.
+	if (args->size() != params.size())
+	{
+		Diagnostics::ID id = args->size() < macro.parameters.size() ?
+			Diagnostics::MACRO_TOO_FEW_ARGS :
+			Diagnostics::MACRO_TOO_MANY_ARGS;
+		mDiagnostics->report(id, identifier.location, identifier.text);
+		return false;
+	}
+
+	// Pre-expand each argument before substitution.
+	// This step expands each argument individually before they are
+	// inserted into the macro body.
+	for (size_t i = 0; i < args->size(); ++i)
+	{
+		MacroArg& arg = args->at(i);
+		TokenLexer lexer(&arg);
+		MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined);
+
+		arg.clear();
+		expander.lex(&token);
+		while (token.type != Token::LAST)
+		{
+			arg.push_back(token);
+			expander.lex(&token);
+		}
+	}
+	return true;
+}
+
+void MacroExpander::replaceMacroParams(const Macro& macro,
+                                       const std::vector<MacroArg>& args,
+                                       std::vector<Token>* replacements)
+{
+	for (size_t i = 0; i < macro.replacements.size(); ++i)
+	{
+		const Token& repl = macro.replacements[i];
+		if (repl.type != Token::IDENTIFIER)
+		{
+			replacements->push_back(repl);
+			continue;
+		}
+
+		// TODO(alokp): Optimize this.
+		// There is no need to search for macro params every time.
+		// The param index can be cached with the replacement token.
+		Macro::Parameters::const_iterator iter = std::find(
+			macro.parameters.begin(), macro.parameters.end(), repl.text);
+		if (iter == macro.parameters.end())
+		{
+			replacements->push_back(repl);
+			continue;
+		}
+
+		size_t iArg = std::distance(macro.parameters.begin(), iter);
+		const MacroArg& arg = args[iArg];
+		if (arg.empty())
+		{
+			continue;
+		}
+		size_t iRepl = replacements->size();
+		replacements->insert(replacements->end(), arg.begin(), arg.end());
+		// The replacement token inherits padding properties from
+		// macro replacement token.
+		replacements->at(iRepl).setHasLeadingSpace(repl.hasLeadingSpace());
+	}
+}
+
+}  // namespace pp
+
diff --git a/src/OpenGL/compiler/preprocessor/MacroExpander.h b/src/OpenGL/compiler/preprocessor/MacroExpander.h
index e1b049a..9d304a9 100644
--- a/src/OpenGL/compiler/preprocessor/MacroExpander.h
+++ b/src/OpenGL/compiler/preprocessor/MacroExpander.h
@@ -1,76 +1,84 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_

-#define COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_

-

-#include <cassert>

-#include <memory>

-#include <vector>

-

-#include "Lexer.h"

-#include "Macro.h"

-#include "pp_utils.h"

-

-namespace pp

-{

-

-class Diagnostics;

-

-class MacroExpander : public Lexer

-{

-  public:

-    MacroExpander(Lexer* lexer, MacroSet* macroSet, Diagnostics* diagnostics, bool parseDefined);

-    virtual ~MacroExpander();

-

-    virtual void lex(Token* token);

-

-  private:

-    PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);

-

-    void getToken(Token* token);

-    void ungetToken(const Token& token);

-    bool isNextTokenLeftParen();

-

-    bool pushMacro(const Macro& macro, const Token& identifier);

-    void popMacro();

-

-    bool expandMacro(const Macro& macro,

-                     const Token& identifier,

-                     std::vector<Token>* replacements);

-

-    typedef std::vector<Token> MacroArg;

-    bool collectMacroArgs(const Macro& macro,

-                          const Token& identifier,

-                          std::vector<MacroArg>* args);

-    void replaceMacroParams(const Macro& macro,

-                            const std::vector<MacroArg>& args,

-                            std::vector<Token>* replacements);

-

-    struct MacroContext

-    {

-        const Macro* macro;

-        size_t index;

-        std::vector<Token> replacements;

-

-        MacroContext() : macro(0), index(0) { }

-        bool empty() const { return index == replacements.size(); }

-        const Token& get() { return replacements[index++]; }

-        void unget() { assert(index > 0); --index; }

-    };

-

-    Lexer* mLexer;

-    MacroSet* mMacroSet;

-    Diagnostics* mDiagnostics;

-	const bool mParseDefined;

-

-    std::auto_ptr<Token> mReserveToken;

-    std::vector<MacroContext*> mContextStack;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
+#define COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
+
+#include <cassert>
+#include <memory>
+#include <vector>
+
+#include "Lexer.h"
+#include "Macro.h"
+#include "pp_utils.h"
+
+namespace pp
+{
+
+class Diagnostics;
+
+class MacroExpander : public Lexer
+{
+public:
+	MacroExpander(Lexer* lexer, MacroSet* macroSet, Diagnostics* diagnostics, bool parseDefined);
+	virtual ~MacroExpander();
+
+	virtual void lex(Token* token);
+
+private:
+	PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);
+
+	void getToken(Token* token);
+	void ungetToken(const Token& token);
+	bool isNextTokenLeftParen();
+
+	bool pushMacro(const Macro& macro, const Token& identifier);
+	void popMacro();
+
+	bool expandMacro(const Macro& macro,
+	                 const Token& identifier,
+	                 std::vector<Token>* replacements);
+
+	typedef std::vector<Token> MacroArg;
+	bool collectMacroArgs(const Macro& macro,
+	                      const Token& identifier,
+	                      std::vector<MacroArg>* args);
+	void replaceMacroParams(const Macro& macro,
+	                        const std::vector<MacroArg>& args,
+	                        std::vector<Token>* replacements);
+
+	struct MacroContext
+	{
+		const Macro* macro;
+		size_t index;
+		std::vector<Token> replacements;
+
+		MacroContext() : macro(0), index(0) { }
+		bool empty() const { return index == replacements.size(); }
+		const Token& get() { return replacements[index++]; }
+		void unget() { assert(index > 0); --index; }
+	};
+
+	Lexer* mLexer;
+	MacroSet* mMacroSet;
+	Diagnostics* mDiagnostics;
+	const bool mParseDefined;
+
+	std::auto_ptr<Token> mReserveToken;
+	std::vector<MacroContext*> mContextStack;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
+
diff --git a/src/OpenGL/compiler/preprocessor/Preprocessor.cpp b/src/OpenGL/compiler/preprocessor/Preprocessor.cpp
index 675b30b..4ce0bf4 100644
--- a/src/OpenGL/compiler/preprocessor/Preprocessor.cpp
+++ b/src/OpenGL/compiler/preprocessor/Preprocessor.cpp
@@ -1,141 +1,149 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "Preprocessor.h"

-

-#include <cassert>

-#include <sstream>

-

-#include "Diagnostics.h"

-#include "DirectiveParser.h"

-#include "Macro.h"

-#include "MacroExpander.h"

-#include "Token.h"

-#include "Tokenizer.h"

-

-namespace pp

-{

-

-struct PreprocessorImpl

-{

-    Diagnostics* diagnostics;

-    MacroSet macroSet;

-    Tokenizer tokenizer;

-    DirectiveParser directiveParser;

-    MacroExpander macroExpander;

-

-    PreprocessorImpl(Diagnostics* diag, DirectiveHandler* directiveHandler) :

-        diagnostics(diag),

-        tokenizer(diag),

-        directiveParser(&tokenizer, &macroSet, diag, directiveHandler),

-        macroExpander(&directiveParser, &macroSet, diag, false)

-    {

-    }

-};

-

-Preprocessor::Preprocessor(Diagnostics* diagnostics,

-                           DirectiveHandler* directiveHandler)

-{

-    mImpl = new PreprocessorImpl(diagnostics, directiveHandler);

-}

-

-Preprocessor::~Preprocessor()

-{

-    delete mImpl;

-}

-

-bool Preprocessor::init(int count,

-                        const char* const string[],

-                        const int length[])

-{

-    static const int kGLSLVersion = 100;

-

-    // Add standard pre-defined macros.

-    predefineMacro("__LINE__", 0);

-    predefineMacro("__FILE__", 0);

-    predefineMacro("__VERSION__", kGLSLVersion);

-    predefineMacro("GL_ES", 1);

-

-    return mImpl->tokenizer.init(count, string, length);

-}

-

-void Preprocessor::predefineMacro(const char* name, int value)

-{

-    std::ostringstream stream;

-    stream << value;

-

-    Token token;

-    token.type = Token::CONST_INT;

-    token.text = stream.str();

-

-    Macro macro;

-    macro.predefined = true;

-    macro.type = Macro::kTypeObj;

-    macro.name = name;

-    macro.replacements.push_back(token);

-

-    mImpl->macroSet[name] = macro;

-}

-

-void Preprocessor::lex(Token* token)

-{

-    bool validToken = false;

-    while (!validToken)

-    {

-        mImpl->macroExpander.lex(token);

-        switch (token->type)

-        {

-          // We should not be returning internal preprocessing tokens.

-          // Convert preprocessing tokens to compiler tokens or report

-          // diagnostics.

-          case Token::PP_HASH:

-            assert(false);

-            break;

-          case Token::CONST_INT:

-          {

-            int val = 0;

-            if (!token->iValue(&val))

-            {

-                // Do not mark the token as invalid.

-                // Just emit the diagnostic and reset value to 0.

-                mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,

-                                           token->location, token->text);

-                token->text.assign("0");

-            }

-            validToken = true;

-            break;

-          }

-          case Token::CONST_FLOAT:

-          {

-            float val = 0;

-            if (!token->fValue(&val))

-            {

-                // Do not mark the token as invalid.

-                // Just emit the diagnostic and reset value to 0.0.

-                mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,

-                                           token->location, token->text);

-                token->text.assign("0.0");

-            }

-            validToken = true;

-            break;

-          }

-          case Token::PP_NUMBER:

-            mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,

-                                       token->location, token->text);

-            break;

-          case Token::PP_OTHER:

-            mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,

-                                       token->location, token->text);

-            break;

-          default:

-            validToken = true;

-            break;

-        }

-    }

-}

-

-}  // namespace pp

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Preprocessor.h"
+
+#include <cassert>
+#include <sstream>
+
+#include "Diagnostics.h"
+#include "DirectiveParser.h"
+#include "Macro.h"
+#include "MacroExpander.h"
+#include "Token.h"
+#include "Tokenizer.h"
+
+namespace pp
+{
+
+struct PreprocessorImpl
+{
+	Diagnostics* diagnostics;
+	MacroSet macroSet;
+	Tokenizer tokenizer;
+	DirectiveParser directiveParser;
+	MacroExpander macroExpander;
+
+	PreprocessorImpl(Diagnostics* diag, DirectiveHandler* directiveHandler) :
+		diagnostics(diag),
+		tokenizer(diag),
+		directiveParser(&tokenizer, &macroSet, diag, directiveHandler),
+		macroExpander(&directiveParser, &macroSet, diag, false)
+	{
+	}
+};
+
+Preprocessor::Preprocessor(Diagnostics* diagnostics,
+                           DirectiveHandler* directiveHandler)
+{
+	mImpl = new PreprocessorImpl(diagnostics, directiveHandler);
+}
+
+Preprocessor::~Preprocessor()
+{
+	delete mImpl;
+}
+
+bool Preprocessor::init(int count,
+                        const char* const string[],
+                        const int length[])
+{
+	static const int kGLSLVersion = 100;
+
+	// Add standard pre-defined macros.
+	predefineMacro("__LINE__", 0);
+	predefineMacro("__FILE__", 0);
+	predefineMacro("__VERSION__", kGLSLVersion);
+	predefineMacro("GL_ES", 1);
+
+	return mImpl->tokenizer.init(count, string, length);
+}
+
+void Preprocessor::predefineMacro(const char* name, int value)
+{
+	std::ostringstream stream;
+	stream << value;
+
+	Token token;
+	token.type = Token::CONST_INT;
+	token.text = stream.str();
+
+	Macro macro;
+	macro.predefined = true;
+	macro.type = Macro::kTypeObj;
+	macro.name = name;
+	macro.replacements.push_back(token);
+
+	mImpl->macroSet[name] = macro;
+}
+
+void Preprocessor::lex(Token* token)
+{
+	bool validToken = false;
+	while (!validToken)
+	{
+		mImpl->macroExpander.lex(token);
+		switch (token->type)
+		{
+		// We should not be returning internal preprocessing tokens.
+		// Convert preprocessing tokens to compiler tokens or report
+		// diagnostics.
+		case Token::PP_HASH:
+			assert(false);
+			break;
+		case Token::CONST_INT:
+		  {
+			int val = 0;
+			if (!token->iValue(&val))
+			{
+				// Do not mark the token as invalid.
+				// Just emit the diagnostic and reset value to 0.
+				mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+				                           token->location, token->text);
+				token->text.assign("0");
+			}
+			validToken = true;
+			break;
+		  }
+		case Token::CONST_FLOAT:
+		  {
+			float val = 0;
+			if (!token->fValue(&val))
+			{
+				// Do not mark the token as invalid.
+				// Just emit the diagnostic and reset value to 0.0.
+				mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
+				                           token->location, token->text);
+				token->text.assign("0.0");
+			}
+			validToken = true;
+			break;
+		  }
+		case Token::PP_NUMBER:
+			mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
+			                           token->location, token->text);
+			break;
+		case Token::PP_OTHER:
+			mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
+			                           token->location, token->text);
+			break;
+		default:
+			validToken = true;
+			break;
+		}
+	}
+}
+
+}  // namespace pp
+
diff --git a/src/OpenGL/compiler/preprocessor/Preprocessor.h b/src/OpenGL/compiler/preprocessor/Preprocessor.h
index 7a54da0..62eca56 100644
--- a/src/OpenGL/compiler/preprocessor/Preprocessor.h
+++ b/src/OpenGL/compiler/preprocessor/Preprocessor.h
@@ -1,49 +1,57 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_

-#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_

-

-#include "pp_utils.h"

-

-namespace pp

-{

-

-class Diagnostics;

-class DirectiveHandler;

-struct PreprocessorImpl;

-struct Token;

-

-class Preprocessor

-{

-  public:

-    Preprocessor(Diagnostics* diagnostics, DirectiveHandler* directiveHandler);

-    ~Preprocessor();

-

-    // count: specifies the number of elements in the string and length arrays.

-    // string: specifies an array of pointers to strings.

-    // length: specifies an array of string lengths.

-    // If length is NULL, each string is assumed to be null terminated.

-    // If length is a value other than NULL, it points to an array containing

-    // a string length for each of the corresponding elements of string.

-    // Each element in the length array may contain the length of the

-    // corresponding string or a value less than 0 to indicate that the string

-    // is null terminated.

-    bool init(int count, const char* const string[], const int length[]);

-    // Adds a pre-defined macro.

-    void predefineMacro(const char* name, int value);

-

-    void lex(Token* token);

-

-  private:

-    PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor);

-

-    PreprocessorImpl* mImpl;

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_PREPROCESSOR_H_

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_
+#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
+
+#include "pp_utils.h"
+
+namespace pp
+{
+
+class Diagnostics;
+class DirectiveHandler;
+struct PreprocessorImpl;
+struct Token;
+
+class Preprocessor
+{
+public:
+	Preprocessor(Diagnostics* diagnostics, DirectiveHandler* directiveHandler);
+	~Preprocessor();
+
+	// count: specifies the number of elements in the string and length arrays.
+	// string: specifies an array of pointers to strings.
+	// length: specifies an array of string lengths.
+	// If length is NULL, each string is assumed to be null terminated.
+	// If length is a value other than NULL, it points to an array containing
+	// a string length for each of the corresponding elements of string.
+	// Each element in the length array may contain the length of the
+	// corresponding string or a value less than 0 to indicate that the string
+	// is null terminated.
+	bool init(int count, const char* const string[], const int length[]);
+	// Adds a pre-defined macro.
+	void predefineMacro(const char* name, int value);
+
+	void lex(Token* token);
+
+private:
+	PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor);
+
+	PreprocessorImpl* mImpl;
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_PREPROCESSOR_H_
+
diff --git a/src/OpenGL/compiler/preprocessor/SourceLocation.h b/src/OpenGL/compiler/preprocessor/SourceLocation.h
index 9c0d1d3..b01e73b 100644
--- a/src/OpenGL/compiler/preprocessor/SourceLocation.h
+++ b/src/OpenGL/compiler/preprocessor/SourceLocation.h
@@ -1,38 +1,46 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_

-#define COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_

-

-namespace pp

-{

-

-struct SourceLocation

-{

-    SourceLocation() : file(0), line(0) { }

-    SourceLocation(int f, int l) : file(f), line(l) { }

-

-    bool equals(const SourceLocation& other) const

-    {

-        return (file == other.file) && (line == other.line);

-    }

-

-    int file;

-    int line;

-};

-

-inline bool operator==(const SourceLocation& lhs, const SourceLocation& rhs)

-{

-    return lhs.equals(rhs);

-}

-

-inline bool operator!=(const SourceLocation& lhs, const SourceLocation& rhs)

-{

-    return !lhs.equals(rhs);

-}

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
+#define COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
+
+namespace pp
+{
+
+struct SourceLocation
+{
+	SourceLocation() : file(0), line(0) { }
+	SourceLocation(int f, int l) : file(f), line(l) { }
+
+	bool equals(const SourceLocation& other) const
+	{
+		return (file == other.file) && (line == other.line);
+	}
+
+	int file;
+	int line;
+};
+
+inline bool operator==(const SourceLocation& lhs, const SourceLocation& rhs)
+{
+	return lhs.equals(rhs);
+}
+
+inline bool operator!=(const SourceLocation& lhs, const SourceLocation& rhs)
+{
+	return !lhs.equals(rhs);
+}
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
diff --git a/src/OpenGL/compiler/preprocessor/Token.cpp b/src/OpenGL/compiler/preprocessor/Token.cpp
index a465aa1..28d6f8c 100644
--- a/src/OpenGL/compiler/preprocessor/Token.cpp
+++ b/src/OpenGL/compiler/preprocessor/Token.cpp
@@ -1,83 +1,91 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#include "Token.h"

-

-#include <cassert>

-

-#include "numeric_lex.h"

-

-namespace pp

-{

-

-void Token::reset()

-{

-    type = 0;

-    flags = 0;

-    location = SourceLocation();

-    text.clear();

-}

-

-bool Token::equals(const Token& other) const

-{

-    return (type == other.type) &&

-           (flags == other.flags) &&

-           (location == other.location) &&

-           (text == other.text);

-}

-

-void Token::setAtStartOfLine(bool start)

-{

-    if (start)

-        flags |= AT_START_OF_LINE;

-    else

-        flags &= ~AT_START_OF_LINE;

-}

-

-void Token::setHasLeadingSpace(bool space)

-{

-    if (space)

-        flags |= HAS_LEADING_SPACE;

-    else

-        flags &= ~HAS_LEADING_SPACE;

-}

-

-void Token::setExpansionDisabled(bool disable)

-{

-    if (disable)

-        flags |= EXPANSION_DISABLED;

-    else

-        flags &= ~EXPANSION_DISABLED;

-}

-

-bool Token::iValue(int* value) const

-{

-    assert(type == CONST_INT);

-    return numeric_lex_int(text, value);

-}

-

-bool Token::uValue(unsigned int* value) const

-{

-    assert(type == CONST_INT);

-    return numeric_lex_int(text, value);

-}

-

-bool Token::fValue(float* value) const

-{

-    assert(type == CONST_FLOAT);

-    return numeric_lex_float(text, value);

-}

-

-std::ostream& operator<<(std::ostream& out, const Token& token)

-{

-    if (token.hasLeadingSpace())

-        out << " ";

-

-    out << token.text;

-    return out;

-}

-

-}  // namespace pp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Token.h"
+
+#include <cassert>
+
+#include "numeric_lex.h"
+
+namespace pp
+{
+
+void Token::reset()
+{
+	type = 0;
+	flags = 0;
+	location = SourceLocation();
+	text.clear();
+}
+
+bool Token::equals(const Token& other) const
+{
+	return (type == other.type) &&
+	       (flags == other.flags) &&
+	       (location == other.location) &&
+	       (text == other.text);
+}
+
+void Token::setAtStartOfLine(bool start)
+{
+	if (start)
+		flags |= AT_START_OF_LINE;
+	else
+		flags &= ~AT_START_OF_LINE;
+}
+
+void Token::setHasLeadingSpace(bool space)
+{
+	if (space)
+		flags |= HAS_LEADING_SPACE;
+	else
+		flags &= ~HAS_LEADING_SPACE;
+}
+
+void Token::setExpansionDisabled(bool disable)
+{
+	if (disable)
+		flags |= EXPANSION_DISABLED;
+	else
+		flags &= ~EXPANSION_DISABLED;
+}
+
+bool Token::iValue(int* value) const
+{
+	assert(type == CONST_INT);
+	return numeric_lex_int(text, value);
+}
+
+bool Token::uValue(unsigned int* value) const
+{
+	assert(type == CONST_INT);
+	return numeric_lex_int(text, value);
+}
+
+bool Token::fValue(float* value) const
+{
+	assert(type == CONST_FLOAT);
+	return numeric_lex_float(text, value);
+}
+
+std::ostream& operator<<(std::ostream& out, const Token& token)
+{
+	if (token.hasLeadingSpace())
+		out << " ";
+
+	out << token.text;
+	return out;
+}
+
+}  // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Token.h b/src/OpenGL/compiler/preprocessor/Token.h
index 45b1129..ddd3aac 100644
--- a/src/OpenGL/compiler/preprocessor/Token.h
+++ b/src/OpenGL/compiler/preprocessor/Token.h
@@ -1,106 +1,114 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_TOKEN_H_

-#define COMPILER_PREPROCESSOR_TOKEN_H_

-

-#include <ostream>

-#include <string>

-

-#include "SourceLocation.h"

-

-namespace pp

-{

-

-struct Token

-{

-    enum Type

-    {

-        LAST = 0,  // EOF.

-

-        IDENTIFIER = 258,

-

-        CONST_INT,

-        CONST_FLOAT,

-

-        OP_INC,

-        OP_DEC,

-        OP_LEFT,

-        OP_RIGHT,

-        OP_LE,

-        OP_GE,

-        OP_EQ,

-        OP_NE,

-        OP_AND,

-        OP_XOR,

-        OP_OR,

-        OP_ADD_ASSIGN,

-        OP_SUB_ASSIGN,

-        OP_MUL_ASSIGN,

-        OP_DIV_ASSIGN,

-        OP_MOD_ASSIGN,

-        OP_LEFT_ASSIGN,

-        OP_RIGHT_ASSIGN,

-        OP_AND_ASSIGN,

-        OP_XOR_ASSIGN,

-        OP_OR_ASSIGN,

-

-        // Preprocessing token types.

-        // These types are used by the preprocessor internally.

-        // Preprocessor clients must not depend or check for them.

-        PP_HASH,

-        PP_NUMBER,

-        PP_OTHER

-    };

-    enum Flags

-    {

-        AT_START_OF_LINE   = 1 << 0,

-        HAS_LEADING_SPACE  = 1 << 1,

-        EXPANSION_DISABLED = 1 << 2

-    };

-

-    Token() : type(0), flags(0) { }

-

-    void reset();

-    bool equals(const Token& other) const;

-

-    // Returns true if this is the first token on line.

-    // It disregards any leading whitespace.

-    bool atStartOfLine() const { return (flags & AT_START_OF_LINE) != 0; }

-    void setAtStartOfLine(bool start);

-

-    bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; }

-    void setHasLeadingSpace(bool space);

-

-    bool expansionDisabled() const { return (flags & EXPANSION_DISABLED) != 0; }

-    void setExpansionDisabled(bool disable);

-

-    // Converts text into numeric value for CONST_INT and CONST_FLOAT token.

-    // Returns false if the parsed value cannot fit into an int or float.

-    bool iValue(int* value) const;

-    bool uValue(unsigned int* value) const;

-    bool fValue(float* value) const;

-

-    int type;

-    unsigned int flags;

-    SourceLocation location;

-    std::string text;

-};

-

-inline bool operator==(const Token& lhs, const Token& rhs)

-{

-    return lhs.equals(rhs);

-}

-

-inline bool operator!=(const Token& lhs, const Token& rhs)

-{

-    return !lhs.equals(rhs);

-}

-

-extern std::ostream& operator<<(std::ostream& out, const Token& token);

-

-}  // namepsace pp

-#endif  // COMPILER_PREPROCESSOR_TOKEN_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_TOKEN_H_
+#define COMPILER_PREPROCESSOR_TOKEN_H_
+
+#include <ostream>
+#include <string>
+
+#include "SourceLocation.h"
+
+namespace pp
+{
+
+struct Token
+{
+	enum Type
+	{
+		LAST = 0,  // EOF.
+
+		IDENTIFIER = 258,
+
+		CONST_INT,
+		CONST_FLOAT,
+
+		OP_INC,
+		OP_DEC,
+		OP_LEFT,
+		OP_RIGHT,
+		OP_LE,
+		OP_GE,
+		OP_EQ,
+		OP_NE,
+		OP_AND,
+		OP_XOR,
+		OP_OR,
+		OP_ADD_ASSIGN,
+		OP_SUB_ASSIGN,
+		OP_MUL_ASSIGN,
+		OP_DIV_ASSIGN,
+		OP_MOD_ASSIGN,
+		OP_LEFT_ASSIGN,
+		OP_RIGHT_ASSIGN,
+		OP_AND_ASSIGN,
+		OP_XOR_ASSIGN,
+		OP_OR_ASSIGN,
+
+		// Preprocessing token types.
+		// These types are used by the preprocessor internally.
+		// Preprocessor clients must not depend or check for them.
+		PP_HASH,
+		PP_NUMBER,
+		PP_OTHER
+	};
+	enum Flags
+	{
+		AT_START_OF_LINE   = 1 << 0,
+		HAS_LEADING_SPACE  = 1 << 1,
+		EXPANSION_DISABLED = 1 << 2
+	};
+
+	Token() : type(0), flags(0) { }
+
+	void reset();
+	bool equals(const Token& other) const;
+
+	// Returns true if this is the first token on line.
+	// It disregards any leading whitespace.
+	bool atStartOfLine() const { return (flags & AT_START_OF_LINE) != 0; }
+	void setAtStartOfLine(bool start);
+
+	bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; }
+	void setHasLeadingSpace(bool space);
+
+	bool expansionDisabled() const { return (flags & EXPANSION_DISABLED) != 0; }
+	void setExpansionDisabled(bool disable);
+
+	// Converts text into numeric value for CONST_INT and CONST_FLOAT token.
+	// Returns false if the parsed value cannot fit into an int or float.
+	bool iValue(int* value) const;
+	bool uValue(unsigned int* value) const;
+	bool fValue(float* value) const;
+
+	int type;
+	unsigned int flags;
+	SourceLocation location;
+	std::string text;
+};
+
+inline bool operator==(const Token& lhs, const Token& rhs)
+{
+	return lhs.equals(rhs);
+}
+
+inline bool operator!=(const Token& lhs, const Token& rhs)
+{
+	return !lhs.equals(rhs);
+}
+
+extern std::ostream& operator<<(std::ostream& out, const Token& token);
+
+}  // namepsace pp
+#endif  // COMPILER_PREPROCESSOR_TOKEN_H_
diff --git a/src/OpenGL/compiler/preprocessor/Tokenizer.cpp b/src/OpenGL/compiler/preprocessor/Tokenizer.cpp
index 02411ad..13e93ce 100644
--- a/src/OpenGL/compiler/preprocessor/Tokenizer.cpp
+++ b/src/OpenGL/compiler/preprocessor/Tokenizer.cpp
@@ -1,9 +1,17 @@
 #line 16 "./Tokenizer.l"
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 
@@ -532,11 +540,19 @@
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
 /*
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 This file contains the Lex specification for GLSL ES preprocessor.
 Based on Microsoft Visual Studio 2010 Preprocessor Grammar:
diff --git a/src/OpenGL/compiler/preprocessor/Tokenizer.h b/src/OpenGL/compiler/preprocessor/Tokenizer.h
index 6b40974..3bad966 100644
--- a/src/OpenGL/compiler/preprocessor/Tokenizer.h
+++ b/src/OpenGL/compiler/preprocessor/Tokenizer.h
@@ -1,60 +1,68 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-#ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_

-#define COMPILER_PREPROCESSOR_TOKENIZER_H_

-

-#include "Input.h"

-#include "Lexer.h"

-#include "pp_utils.h"

-

-#include <algorithm>

-

-namespace pp

-{

-

-class Diagnostics;

-

-class Tokenizer : public Lexer

-{

-  public:

-    struct Context

-    {

-        Diagnostics* diagnostics;

-

-        Input input;

-        // The location where yytext points to. Token location should track

-        // scanLoc instead of Input::mReadLoc because they may not be the same

-        // if text is buffered up in the scanner input buffer.

-        Input::Location scanLoc;

-

-        bool leadingSpace;

-        bool lineStart;

-    };

-    static const size_t kMaxTokenLength;

-

-    Tokenizer(Diagnostics* diagnostics);

-    ~Tokenizer();

-

-    bool init(int count, const char* const string[], const int length[]);

-

-    void setFileNumber(int file);

-    void setLineNumber(int line);

-

-    virtual void lex(Token* token);

-

-  private:

-    PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer);

-    bool initScanner();

-    void destroyScanner();

-

-    void* mHandle;  // Scanner handle.

-    Context mContext;  // Scanner extra.

-};

-

-}  // namespace pp

-#endif  // COMPILER_PREPROCESSOR_TOKENIZER_H_

-

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_
+#define COMPILER_PREPROCESSOR_TOKENIZER_H_
+
+#include "Input.h"
+#include "Lexer.h"
+#include "pp_utils.h"
+
+#include <algorithm>
+
+namespace pp
+{
+
+class Diagnostics;
+
+class Tokenizer : public Lexer
+{
+public:
+	struct Context
+	{
+		Diagnostics* diagnostics;
+
+		Input input;
+		// The location where yytext points to. Token location should track
+		// scanLoc instead of Input::mReadLoc because they may not be the same
+		// if text is buffered up in the scanner input buffer.
+		Input::Location scanLoc;
+
+		bool leadingSpace;
+		bool lineStart;
+	};
+	static const size_t kMaxTokenLength;
+
+	Tokenizer(Diagnostics* diagnostics);
+	~Tokenizer();
+
+	bool init(int count, const char* const string[], const int length[]);
+
+	void setFileNumber(int file);
+	void setLineNumber(int line);
+
+	virtual void lex(Token* token);
+
+private:
+	PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer);
+	bool initScanner();
+	void destroyScanner();
+
+	void* mHandle;  // Scanner handle.
+	Context mContext;  // Scanner extra.
+};
+
+}  // namespace pp
+#endif  // COMPILER_PREPROCESSOR_TOKENIZER_H_
+
diff --git a/src/OpenGL/compiler/preprocessor/Tokenizer.l b/src/OpenGL/compiler/preprocessor/Tokenizer.l
index 5e5f26d..094627e 100644
--- a/src/OpenGL/compiler/preprocessor/Tokenizer.l
+++ b/src/OpenGL/compiler/preprocessor/Tokenizer.l
@@ -1,9 +1,17 @@
 /*
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 This file contains the Lex specification for GLSL ES preprocessor.
 Based on Microsoft Visual Studio 2010 Preprocessor Grammar:
@@ -13,11 +21,19 @@
 */
 
 %top{
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
 }
@@ -78,8 +94,8 @@
 IDENTIFIER  [_a-zA-Z][_a-zA-Z0-9]*
 PUNCTUATOR  [][<>(){}.+-/*%^|&~=!:;,?]
 
-DECIMAL_CONSTANT      [1-9][0-9]*[uU]?

-OCTAL_CONSTANT        0[0-7]*[uU]?

+DECIMAL_CONSTANT      [1-9][0-9]*[uU]?
+OCTAL_CONSTANT        0[0-7]*[uU]?
 HEXADECIMAL_CONSTANT  0[xX][0-9a-fA-F]+[uU]?
 
 DIGIT                [0-9]
diff --git a/src/OpenGL/compiler/preprocessor/generate_parser.sh b/src/OpenGL/compiler/preprocessor/generate_parser.sh
index 14ffa6a..36bd84e 100644
--- a/src/OpenGL/compiler/preprocessor/generate_parser.sh
+++ b/src/OpenGL/compiler/preprocessor/generate_parser.sh
@@ -1,7 +1,17 @@
 #!/bin/bash
-# Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
+# 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.
 
 # Generates various components of GLSL ES preprocessor.
 
diff --git a/src/OpenGL/compiler/preprocessor/length_limits.h b/src/OpenGL/compiler/preprocessor/length_limits.h
index 889d468..1c91447 100644
--- a/src/OpenGL/compiler/preprocessor/length_limits.h
+++ b/src/OpenGL/compiler/preprocessor/length_limits.h
@@ -1,21 +1,29 @@
-//

-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-//

-// length_limits.h

-//

-

-#if !defined(__LENGTH_LIMITS_H)

-#define __LENGTH_LIMITS_H 1

-

-// These constants are factored out from the rest of the headers to

-// make it easier to reference them from the compiler sources.

-

-// These lengths do not include the NULL terminator.

-#define MAX_SYMBOL_NAME_LEN 256

-#define MAX_STRING_LEN 511

-

-#endif // !(defined(__LENGTH_LIMITS_H)

+// 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.
+
+//
+// length_limits.h
+//
+
+#if !defined(__LENGTH_LIMITS_H)
+#define __LENGTH_LIMITS_H 1
+
+// These constants are factored out from the rest of the headers to
+// make it easier to reference them from the compiler sources.
+
+// These lengths do not include the NULL terminator.
+#define MAX_SYMBOL_NAME_LEN 256
+#define MAX_STRING_LEN 511
+
+#endif // !(defined(__LENGTH_LIMITS_H)
diff --git a/src/OpenGL/compiler/preprocessor/numeric_lex.h b/src/OpenGL/compiler/preprocessor/numeric_lex.h
index 3cdf71f..f57410c 100644
--- a/src/OpenGL/compiler/preprocessor/numeric_lex.h
+++ b/src/OpenGL/compiler/preprocessor/numeric_lex.h
@@ -1,61 +1,69 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-// numeric_lex.h: Functions to extract numeric values from string.

-

-#ifndef COMPILER_PREPROCESSOR_NUMERIC_LEX_H_

-#define COMPILER_PREPROCESSOR_NUMERIC_LEX_H_

-

-#include <sstream>

-

-namespace pp {

-

-inline std::ios::fmtflags numeric_base_int(const std::string& str)

-{

-    if ((str.size() >= 2) &&

-        (str[0] == '0') &&

-        (str[1] == 'x' || str[1] == 'X'))

-    {

-        return std::ios::hex;

-    }

-    else if ((str.size() >= 1) && (str[0] == '0'))

-    {

-        return std::ios::oct;

-    }

-    return std::ios::dec;

-}

-

-// The following functions parse the given string to extract a numerical

-// value of the given type. These functions assume that the string is

-// of the correct form. They can only fail if the parsed value is too big,

-// in which case false is returned.

-

-template<typename IntType>

-bool numeric_lex_int(const std::string& str, IntType* value)

-{

-    std::istringstream stream(str);

-    // This should not be necessary, but MSVS has a buggy implementation.

-    // It returns incorrect results if the base is not specified.

-    stream.setf(numeric_base_int(str), std::ios::basefield);

-

-    stream >> (*value);

-    return !stream.fail();

-}

-

-template<typename FloatType>

-bool numeric_lex_float(const std::string& str, FloatType* value)

-{

-    std::istringstream stream(str);

-    // Force "C" locale so that decimal character is always '.', and

-    // not dependent on the current locale.

-    stream.imbue(std::locale::classic());

-

-    stream >> (*value);

-    return !stream.fail();

-}

-

-} // namespace pp.

-#endif // COMPILER_PREPROCESSOR_NUMERIC_LEX_H_

+// 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.
+
+// numeric_lex.h: Functions to extract numeric values from string.
+
+#ifndef COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
+#define COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
+
+#include <sstream>
+
+namespace pp {
+
+inline std::ios::fmtflags numeric_base_int(const std::string& str)
+{
+	if ((str.size() >= 2) &&
+		(str[0] == '0') &&
+		(str[1] == 'x' || str[1] == 'X'))
+	{
+		return std::ios::hex;
+	}
+	else if ((str.size() >= 1) && (str[0] == '0'))
+	{
+		return std::ios::oct;
+	}
+	return std::ios::dec;
+}
+
+// The following functions parse the given string to extract a numerical
+// value of the given type. These functions assume that the string is
+// of the correct form. They can only fail if the parsed value is too big,
+// in which case false is returned.
+
+template<typename IntType>
+bool numeric_lex_int(const std::string& str, IntType* value)
+{
+	std::istringstream stream(str);
+	// This should not be necessary, but MSVS has a buggy implementation.
+	// It returns incorrect results if the base is not specified.
+	stream.setf(numeric_base_int(str), std::ios::basefield);
+
+	stream >> (*value);
+	return !stream.fail();
+}
+
+template<typename FloatType>
+bool numeric_lex_float(const std::string& str, FloatType* value)
+{
+	std::istringstream stream(str);
+	// Force "C" locale so that decimal character is always '.', and
+	// not dependent on the current locale.
+	stream.imbue(std::locale::classic());
+
+	stream >> (*value);
+	return !stream.fail();
+}
+
+} // namespace pp.
+#endif // COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
diff --git a/src/OpenGL/compiler/preprocessor/pp_utils.h b/src/OpenGL/compiler/preprocessor/pp_utils.h
index 9fed659..d0ea4c4 100644
--- a/src/OpenGL/compiler/preprocessor/pp_utils.h
+++ b/src/OpenGL/compiler/preprocessor/pp_utils.h
@@ -1,18 +1,26 @@
-//

-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-//

-

-// pp_utils.h: Common preprocessor utilities

-

-#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_

-#define COMPILER_PREPROCESSOR_PPUTILS_H_

-

-// A macro to disallow the copy constructor and operator= functions

-// This must be used in the private: declarations for a class.

-#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \

-  TypeName(const TypeName&);               \

-  void operator=(const TypeName&)

-

-#endif // COMPILER_PREPROCESSOR_PPUTILS_H_

+// 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.
+
+// pp_utils.h: Common preprocessor utilities
+
+#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_
+#define COMPILER_PREPROCESSOR_PPUTILS_H_
+
+// A macro to disallow the copy constructor and operator= functions
+// This must be used in the private: declarations for a class.
+#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&);               \
+  void operator=(const TypeName&)
+
+#endif // COMPILER_PREPROCESSOR_PPUTILS_H_
diff --git a/src/OpenGL/compiler/util.cpp b/src/OpenGL/compiler/util.cpp
index e20068b..2905c1d 100644
--- a/src/OpenGL/compiler/util.cpp
+++ b/src/OpenGL/compiler/util.cpp
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include <limits>
 
diff --git a/src/OpenGL/compiler/util.h b/src/OpenGL/compiler/util.h
index 61442be..a5c4842 100644
--- a/src/OpenGL/compiler/util.h
+++ b/src/OpenGL/compiler/util.h
@@ -1,8 +1,16 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
 //
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef COMPILER_UTIL_H
 #define COMPILER_UTIL_H
diff --git a/src/OpenGL/libEGL/Config.cpp b/src/OpenGL/libEGL/Config.cpp
index 337ac9b..9a5839e 100644
--- a/src/OpenGL/libEGL/Config.cpp
+++ b/src/OpenGL/libEGL/Config.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    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.
 
 // Config.cpp: Implements the egl::Config class, describing the format, type
 // and size for an egl::Surface. Implements EGLConfig and related functionality.
@@ -31,96 +34,96 @@
 namespace egl
 {
 Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
-    : mDisplayFormat(displayFormat), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
+	: mDisplayFormat(displayFormat), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
 {
-    mBindToTextureRGB = EGL_FALSE;
-    mBindToTextureRGBA = EGL_FALSE;
+	mBindToTextureRGB = EGL_FALSE;
+	mBindToTextureRGBA = EGL_FALSE;
 
 	// Initialize to a high value to lower the preference of formats for which there's no native support
-    mNativeVisualID = 0x7FFFFFFF;
+	mNativeVisualID = 0x7FFFFFFF;
 
-    switch(renderTargetFormat)
-    {
-    case sw::FORMAT_A1R5G5B5:
-        mRedSize = 5;
-        mGreenSize = 5;
-        mBlueSize = 5;
-        mAlphaSize = 1;
-        break;
-    case sw::FORMAT_A2R10G10B10:
-        mRedSize = 10;
-        mGreenSize = 10;
-        mBlueSize = 10;
-        mAlphaSize = 2;
-        break;
-    case sw::FORMAT_A8R8G8B8:
-        mRedSize = 8;
-        mGreenSize = 8;
-        mBlueSize = 8;
-        mAlphaSize = 8;
-        mBindToTextureRGBA = EGL_TRUE;
-        #ifdef __ANDROID__
+	switch(renderTargetFormat)
+	{
+	case sw::FORMAT_A1R5G5B5:
+		mRedSize = 5;
+		mGreenSize = 5;
+		mBlueSize = 5;
+		mAlphaSize = 1;
+		break;
+	case sw::FORMAT_A2R10G10B10:
+		mRedSize = 10;
+		mGreenSize = 10;
+		mBlueSize = 10;
+		mAlphaSize = 2;
+		break;
+	case sw::FORMAT_A8R8G8B8:
+		mRedSize = 8;
+		mGreenSize = 8;
+		mBlueSize = 8;
+		mAlphaSize = 8;
+		mBindToTextureRGBA = EGL_TRUE;
+		#ifdef __ANDROID__
 			mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888;
 		#else
 			mNativeVisualID = 2;   // Arbitrary; prefer over ABGR
 		#endif
-        break;
+		break;
 	case sw::FORMAT_A8B8G8R8:
-        mRedSize = 8;
-        mGreenSize = 8;
-        mBlueSize = 8;
-        mAlphaSize = 8;
-        mBindToTextureRGBA = EGL_TRUE;
+		mRedSize = 8;
+		mGreenSize = 8;
+		mBlueSize = 8;
+		mAlphaSize = 8;
+		mBindToTextureRGBA = EGL_TRUE;
 		#ifdef __ANDROID__
 			mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888;
 		#endif
-        break;
-    case sw::FORMAT_R5G6B5:
-        mRedSize = 5;
-        mGreenSize = 6;
-        mBlueSize = 5;
-        mAlphaSize = 0;
-        #ifdef __ANDROID__
+		break;
+	case sw::FORMAT_R5G6B5:
+		mRedSize = 5;
+		mGreenSize = 6;
+		mBlueSize = 5;
+		mAlphaSize = 0;
+		#ifdef __ANDROID__
 			mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565;
 		#endif
-        break;
-    case sw::FORMAT_X8R8G8B8:
-        mRedSize = 8;
-        mGreenSize = 8;
-        mBlueSize = 8;
-        mAlphaSize = 0;
-        mBindToTextureRGB = EGL_TRUE;
+		break;
+	case sw::FORMAT_X8R8G8B8:
+		mRedSize = 8;
+		mGreenSize = 8;
+		mBlueSize = 8;
+		mAlphaSize = 0;
+		mBindToTextureRGB = EGL_TRUE;
 		#ifdef __ANDROID__
 			mNativeVisualID = 0x1FF;   // HAL_PIXEL_FORMAT_BGRX_8888
 		#else
 			mNativeVisualID = 1;   // Arbitrary; prefer over XBGR
 		#endif
-        break;
+		break;
 	case sw::FORMAT_X8B8G8R8:
-        mRedSize = 8;
-        mGreenSize = 8;
-        mBlueSize = 8;
-        mAlphaSize = 0;
-        mBindToTextureRGB = EGL_TRUE;
+		mRedSize = 8;
+		mGreenSize = 8;
+		mBlueSize = 8;
+		mAlphaSize = 0;
+		mBindToTextureRGB = EGL_TRUE;
 		#ifdef __ANDROID__
 			mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888;
 		#endif
-        break;
-    default:
-        UNREACHABLE(renderTargetFormat);
-    }
+		break;
+	default:
+		UNREACHABLE(renderTargetFormat);
+	}
 
-    mLuminanceSize = 0;
-    mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
-    mAlphaMaskSize = 0;
-    mColorBufferType = EGL_RGB_BUFFER;
-    mConfigCaveat = EGL_NONE;
-    mConfigID = 0;
-    mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
+	mLuminanceSize = 0;
+	mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
+	mAlphaMaskSize = 0;
+	mColorBufferType = EGL_RGB_BUFFER;
+	mConfigCaveat = EGL_NONE;
+	mConfigID = 0;
+	mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
 #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
-        | EGL_OPENGL_ES3_BIT
+		| EGL_OPENGL_ES3_BIT
 #endif
-        ;
+		;
 
 	switch(depthStencilFormat)
 	{
@@ -128,10 +131,10 @@
 		mDepthSize = 0;
 		mStencilSize = 0;
 		break;
-//  case sw::FORMAT_D16_LOCKABLE:
-//      mDepthSize = 16;
-//      mStencilSize = 0;
-//      break;
+//	case sw::FORMAT_D16_LOCKABLE:
+//		mDepthSize = 16;
+//		mStencilSize = 0;
+//		break;
 	case sw::FORMAT_D32:
 		mDepthSize = 32;
 		mStencilSize = 0;
@@ -156,39 +159,39 @@
 		mDepthSize = 16;
 		mStencilSize = 0;
 		break;
-//  case sw::FORMAT_D32F_LOCKABLE:
-//      mDepthSize = 32;
-//      mStencilSize = 0;
-//      break;
-//  case sw::FORMAT_D24FS8:
-//      mDepthSize = 24;
-//      mStencilSize = 8;
-//      break;
+//	case sw::FORMAT_D32F_LOCKABLE:
+//		mDepthSize = 32;
+//		mStencilSize = 0;
+//		break;
+//	case sw::FORMAT_D24FS8:
+//		mDepthSize = 24;
+//		mStencilSize = 8;
+//		break;
 	default:
 		UNREACHABLE(depthStencilFormat);
 	}
 
-    mLevel = 0;
-    mMatchNativePixmap = EGL_NONE;
-    mMaxPBufferWidth = 4096;
-    mMaxPBufferHeight = 4096;
-    mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
-    mMaxSwapInterval = maxInterval;
-    mMinSwapInterval = minInterval;
-    mNativeRenderable = EGL_FALSE;
-    mNativeVisualType = 0;
-    mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
+	mLevel = 0;
+	mMatchNativePixmap = EGL_NONE;
+	mMaxPBufferWidth = 4096;
+	mMaxPBufferHeight = 4096;
+	mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
+	mMaxSwapInterval = maxInterval;
+	mMinSwapInterval = minInterval;
+	mNativeRenderable = EGL_FALSE;
+	mNativeVisualType = 0;
+	mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
 #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
-        | EGL_OPENGL_ES3_BIT
+		| EGL_OPENGL_ES3_BIT
 #endif
-        ;
-    mSampleBuffers = (multiSample > 0) ? 1 : 0;
-    mSamples = multiSample;
-    mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
-    mTransparentType = EGL_NONE;
-    mTransparentRedValue = 0;
-    mTransparentGreenValue = 0;
-    mTransparentBlueValue = 0;
+		;
+	mSampleBuffers = (multiSample > 0) ? 1 : 0;
+	mSamples = multiSample;
+	mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+	mTransparentType = EGL_NONE;
+	mTransparentRedValue = 0;
+	mTransparentGreenValue = 0;
+	mTransparentBlueValue = 0;
 
 	mRecordableAndroid = EGL_TRUE;
 	mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE;
@@ -196,112 +199,112 @@
 
 EGLConfig Config::getHandle() const
 {
-    return (EGLConfig)(size_t)mConfigID;
+	return (EGLConfig)(size_t)mConfigID;
 }
 
 // This ordering determines the config ID
 bool CompareConfig::operator()(const Config &x, const Config &y) const
 {
-    #define SORT_SMALLER(attribute)                \
-        if(x.attribute != y.attribute)             \
-        {                                          \
-            return x.attribute < y.attribute;      \
-        }
+	#define SORT_SMALLER(attribute)                \
+		if(x.attribute != y.attribute)             \
+		{                                          \
+			return x.attribute < y.attribute;      \
+		}
 
-    META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
-    SORT_SMALLER(mConfigCaveat);
+	META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
+	SORT_SMALLER(mConfigCaveat);
 
-    META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
-    SORT_SMALLER(mColorBufferType);
+	META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
+	SORT_SMALLER(mColorBufferType);
 
 	SORT_SMALLER(mRedSize);
 	SORT_SMALLER(mGreenSize);
 	SORT_SMALLER(mBlueSize);
 	SORT_SMALLER(mAlphaSize);
-    
+
 	SORT_SMALLER(mBufferSize);
-    SORT_SMALLER(mSampleBuffers);
-    SORT_SMALLER(mSamples);
-    SORT_SMALLER(mDepthSize);
-    SORT_SMALLER(mStencilSize);
-    SORT_SMALLER(mAlphaMaskSize);
-    SORT_SMALLER(mNativeVisualType);
+	SORT_SMALLER(mSampleBuffers);
+	SORT_SMALLER(mSamples);
+	SORT_SMALLER(mDepthSize);
+	SORT_SMALLER(mStencilSize);
+	SORT_SMALLER(mAlphaMaskSize);
+	SORT_SMALLER(mNativeVisualType);
 	SORT_SMALLER(mNativeVisualID);
 
-    #undef SORT_SMALLER
+	#undef SORT_SMALLER
 
 	// Strict ordering requires sorting all non-equal fields above
 	assert(memcmp(&x, &y, sizeof(Config)) == 0);
 
-    return false;
+	return false;
 }
 
 // Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24.
 class SortConfig
 {
 public:
-    explicit SortConfig(const EGLint *attribList);
+	explicit SortConfig(const EGLint *attribList);
 
-    bool operator()(const Config *x, const Config *y) const;
+	bool operator()(const Config *x, const Config *y) const;
 
 private:
-    EGLint wantedComponentsSize(const Config *config) const;
+	EGLint wantedComponentsSize(const Config *config) const;
 
-    bool mWantRed;
-    bool mWantGreen;
-    bool mWantBlue;
-    bool mWantAlpha;
-    bool mWantLuminance;
+	bool mWantRed;
+	bool mWantGreen;
+	bool mWantBlue;
+	bool mWantAlpha;
+	bool mWantLuminance;
 };
 
 SortConfig::SortConfig(const EGLint *attribList)
-    : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
+	: mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
 {
 	// [EGL] section 3.4.1 page 24
-    // Sorting rule #3: by larger total number of color bits,
+	// Sorting rule #3: by larger total number of color bits,
 	// not considering components that are 0 or don't-care.
-    for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
-    {
-        if(attr[1] != 0 && attr[1] != EGL_DONT_CARE)
-        {
-            switch (attr[0])
-            {
-            case EGL_RED_SIZE:       mWantRed = true;       break;
-            case EGL_GREEN_SIZE:     mWantGreen = true;     break;
-            case EGL_BLUE_SIZE:      mWantBlue = true;      break;
-            case EGL_ALPHA_SIZE:     mWantAlpha = true;     break;
-            case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
-            }
-        }
-    }
+	for(const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
+	{
+		if(attr[1] != 0 && attr[1] != EGL_DONT_CARE)
+		{
+			switch(attr[0])
+			{
+			case EGL_RED_SIZE:       mWantRed = true;       break;
+			case EGL_GREEN_SIZE:     mWantGreen = true;     break;
+			case EGL_BLUE_SIZE:      mWantBlue = true;      break;
+			case EGL_ALPHA_SIZE:     mWantAlpha = true;     break;
+			case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
+			}
+		}
+	}
 }
 
 EGLint SortConfig::wantedComponentsSize(const Config *config) const
 {
-    EGLint total = 0;
+	EGLint total = 0;
 
-    if(mWantRed)       total += config->mRedSize;
-    if(mWantGreen)     total += config->mGreenSize;
-    if(mWantBlue)      total += config->mBlueSize;
-    if(mWantAlpha)     total += config->mAlphaSize;
-    if(mWantLuminance) total += config->mLuminanceSize;
+	if(mWantRed)       total += config->mRedSize;
+	if(mWantGreen)     total += config->mGreenSize;
+	if(mWantBlue)      total += config->mBlueSize;
+	if(mWantAlpha)     total += config->mAlphaSize;
+	if(mWantLuminance) total += config->mLuminanceSize;
 
-    return total;
+	return total;
 }
 
 bool SortConfig::operator()(const Config *x, const Config *y) const
 {
-    #define SORT_SMALLER(attribute)                \
-        if(x->attribute != y->attribute)           \
-        {                                          \
-            return x->attribute < y->attribute;    \
-        }
+	#define SORT_SMALLER(attribute)                \
+		if(x->attribute != y->attribute)           \
+		{                                          \
+			return x->attribute < y->attribute;    \
+		}
 
-    META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
-    SORT_SMALLER(mConfigCaveat);
+	META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
+	SORT_SMALLER(mConfigCaveat);
 
-    META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
-    SORT_SMALLER(mColorBufferType);
+	META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
+	SORT_SMALLER(mColorBufferType);
 
 	// By larger total number of color bits, only considering those that are requested to be > 0.
 	EGLint xComponentsSize = wantedComponentsSize(x);
@@ -311,18 +314,18 @@
 		return xComponentsSize > yComponentsSize;
 	}
 
-    SORT_SMALLER(mBufferSize);
-    SORT_SMALLER(mSampleBuffers);
-    SORT_SMALLER(mSamples);
-    SORT_SMALLER(mDepthSize);
-    SORT_SMALLER(mStencilSize);
-    SORT_SMALLER(mAlphaMaskSize);
-    SORT_SMALLER(mNativeVisualType);
-    SORT_SMALLER(mConfigID);
+	SORT_SMALLER(mBufferSize);
+	SORT_SMALLER(mSampleBuffers);
+	SORT_SMALLER(mSamples);
+	SORT_SMALLER(mDepthSize);
+	SORT_SMALLER(mStencilSize);
+	SORT_SMALLER(mAlphaMaskSize);
+	SORT_SMALLER(mNativeVisualType);
+	SORT_SMALLER(mConfigID);
 
-    #undef SORT_SMALLER
+	#undef SORT_SMALLER
 
-    return false;
+	return false;
 }
 
 ConfigSet::ConfigSet()
@@ -331,28 +334,28 @@
 
 void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
 {
-    Config config(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
+	Config config(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
 
-    mSet.insert(config);
+	mSet.insert(config);
 }
 
 size_t ConfigSet::size() const
 {
-    return mSet.size();
+	return mSet.size();
 }
 
 bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
 {
-    vector<const Config*> passed;
-    passed.reserve(mSet.size());
+	vector<const Config*> passed;
+	passed.reserve(mSet.size());
 
-    for(Iterator config = mSet.begin(); config != mSet.end(); config++)
-    {
-        bool match = true;
-        const EGLint *attribute = attribList;
+	for(Iterator config = mSet.begin(); config != mSet.end(); config++)
+	{
+		bool match = true;
+		const EGLint *attribute = attribList;
 
-        while(attribute[0] != EGL_NONE)
-        {
+		while(attribute[0] != EGL_NONE)
+		{
 			if(attribute[1] != EGL_DONT_CARE)
 			{
 				switch(attribute[0])
@@ -403,45 +406,45 @@
 				}
 			}
 
-            attribute += 2;
-        }
+			attribute += 2;
+		}
 
-        if(match)
-        {
-            passed.push_back(&*config);
-        }
-    }
+		if(match)
+		{
+			passed.push_back(&*config);
+		}
+	}
 
-    if(configs)
-    {
-        sort(passed.begin(), passed.end(), SortConfig(attribList));
+	if(configs)
+	{
+		sort(passed.begin(), passed.end(), SortConfig(attribList));
 
-        EGLint index;
-        for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
-        {
-            configs[index] = passed[index]->getHandle();
-        }
+		EGLint index;
+		for(index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
+		{
+			configs[index] = passed[index]->getHandle();
+		}
 
-        *numConfig = index;
-    }
-    else
-    {
-        *numConfig = static_cast<EGLint>(passed.size());
-    }
+		*numConfig = index;
+	}
+	else
+	{
+		*numConfig = static_cast<EGLint>(passed.size());
+	}
 
-    return true;
+	return true;
 }
 
 const egl::Config *ConfigSet::get(EGLConfig configHandle)
 {
-    for(Iterator config = mSet.begin(); config != mSet.end(); config++)
-    {
-        if(config->getHandle() == configHandle)
-        {
-            return &(*config);
-        }
-    }
+	for(Iterator config = mSet.begin(); config != mSet.end(); config++)
+	{
+		if(config->getHandle() == configHandle)
+		{
+			return &(*config);
+		}
+	}
 
-    return NULL;
+	return nullptr;
 }
 }
diff --git a/src/OpenGL/libEGL/Config.h b/src/OpenGL/libEGL/Config.h
index 0a6019c..d1c21e3 100644
--- a/src/OpenGL/libEGL/Config.h
+++ b/src/OpenGL/libEGL/Config.h
@@ -1,103 +1,106 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Config.h: Defines the egl::Config class, describing the format, type

-// and size for an egl::Surface. Implements EGLConfig and related functionality.

-// [EGL 1.4] section 3.4 page 15.

-

-#ifndef INCLUDE_CONFIG_H_

-#define INCLUDE_CONFIG_H_

-

-#include "Renderer/Surface.hpp"

-

-#include <EGL/egl.h>

-

-#include <set>

-

-namespace egl

-{

-class Display;

-

-class Config

-{

-public:

-    Config(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample);

-

-    EGLConfig getHandle() const;

-

-    const sw::Format mDisplayFormat;

-    const sw::Format mRenderTargetFormat;

-    const sw::Format mDepthStencilFormat;

-    const EGLint mMultiSample;

-

-    EGLint mBufferSize;              // Depth of the color buffer

-    EGLint mRedSize;                 // Bits of Red in the color buffer

-    EGLint mGreenSize;               // Bits of Green in the color buffer

-    EGLint mBlueSize;                // Bits of Blue in the color buffer

-    EGLint mLuminanceSize;           // Bits of Luminance in the color buffer

-    EGLint mAlphaSize;               // Bits of Alpha in the color buffer

-    EGLint mAlphaMaskSize;           // Bits of Alpha Mask in the mask buffer

-    EGLBoolean mBindToTextureRGB;    // True if bindable to RGB textures.

-    EGLBoolean mBindToTextureRGBA;   // True if bindable to RGBA textures.

-    EGLenum mColorBufferType;        // Color buffer type

-    EGLenum mConfigCaveat;           // Any caveats for the configuration

-    EGLint mConfigID;                // Unique EGLConfig identifier

-    EGLint mConformant;              // Whether contexts created with this config are conformant

-    EGLint mDepthSize;               // Bits of Z in the depth buffer

-    EGLint mLevel;                   // Frame buffer level

-    EGLBoolean mMatchNativePixmap;   // Match the native pixmap format

-    EGLint mMaxPBufferWidth;         // Maximum width of pbuffer

-    EGLint mMaxPBufferHeight;        // Maximum height of pbuffer

-    EGLint mMaxPBufferPixels;        // Maximum size of pbuffer

-    EGLint mMaxSwapInterval;         // Maximum swap interval

-    EGLint mMinSwapInterval;         // Minimum swap interval

-    EGLBoolean mNativeRenderable;    // EGL_TRUE if native rendering APIs can render to surface

-    EGLint mNativeVisualID;          // Handle of corresponding native visual

-    EGLint mNativeVisualType;        // Native visual type of the associated visual

-    EGLint mRenderableType;          // Which client rendering APIs are supported.

-    EGLint mSampleBuffers;           // Number of multisample buffers

-    EGLint mSamples;                 // Number of samples per pixel

-    EGLint mStencilSize;             // Bits of Stencil in the stencil buffer

-    EGLint mSurfaceType;             // Which types of EGL surfaces are supported.

-    EGLenum mTransparentType;        // Type of transparency supported

-    EGLint mTransparentRedValue;     // Transparent red value

-    EGLint mTransparentGreenValue;   // Transparent green value

-    EGLint mTransparentBlueValue;    // Transparent blue value

-

-	EGLBoolean mRecordableAndroid;          // EGL_ANDROID_recordable

-	EGLBoolean mFramebufferTargetAndroid;   // EGL_ANDROID_framebuffer_target

-};

-

-struct CompareConfig

-{

-    bool operator()(const Config &x, const Config &y) const;

-};

-

-class ConfigSet

-{

-    friend class Display;

-

-  public:

-    ConfigSet();

-

-    void add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample);

-    size_t size() const;

-    bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);

-    const egl::Config *get(EGLConfig configHandle);

-

-  private:

-    typedef std::set<Config, CompareConfig> Set;

-    typedef Set::iterator Iterator;

-    Set mSet;

-};

-}

-

-#endif   // INCLUDE_CONFIG_H_

+// 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.
+
+// Config.h: Defines the egl::Config class, describing the format, type
+// and size for an egl::Surface. Implements EGLConfig and related functionality.
+// [EGL 1.4] section 3.4 page 15.
+
+#ifndef INCLUDE_CONFIG_H_
+#define INCLUDE_CONFIG_H_
+
+#include "Renderer/Surface.hpp"
+
+#include <EGL/egl.h>
+
+#include <set>
+
+namespace egl
+{
+class Display;
+
+class Config
+{
+public:
+	Config(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample);
+
+	EGLConfig getHandle() const;
+
+	const sw::Format mDisplayFormat;
+	const sw::Format mRenderTargetFormat;
+	const sw::Format mDepthStencilFormat;
+	const EGLint mMultiSample;
+
+	EGLint mBufferSize;              // Depth of the color buffer
+	EGLint mRedSize;                 // Bits of Red in the color buffer
+	EGLint mGreenSize;               // Bits of Green in the color buffer
+	EGLint mBlueSize;                // Bits of Blue in the color buffer
+	EGLint mLuminanceSize;           // Bits of Luminance in the color buffer
+	EGLint mAlphaSize;               // Bits of Alpha in the color buffer
+	EGLint mAlphaMaskSize;           // Bits of Alpha Mask in the mask buffer
+	EGLBoolean mBindToTextureRGB;    // True if bindable to RGB textures.
+	EGLBoolean mBindToTextureRGBA;   // True if bindable to RGBA textures.
+	EGLenum mColorBufferType;        // Color buffer type
+	EGLenum mConfigCaveat;           // Any caveats for the configuration
+	EGLint mConfigID;                // Unique EGLConfig identifier
+	EGLint mConformant;              // Whether contexts created with this config are conformant
+	EGLint mDepthSize;               // Bits of Z in the depth buffer
+	EGLint mLevel;                   // Frame buffer level
+	EGLBoolean mMatchNativePixmap;   // Match the native pixmap format
+	EGLint mMaxPBufferWidth;         // Maximum width of pbuffer
+	EGLint mMaxPBufferHeight;        // Maximum height of pbuffer
+	EGLint mMaxPBufferPixels;        // Maximum size of pbuffer
+	EGLint mMaxSwapInterval;         // Maximum swap interval
+	EGLint mMinSwapInterval;         // Minimum swap interval
+	EGLBoolean mNativeRenderable;    // EGL_TRUE if native rendering APIs can render to surface
+	EGLint mNativeVisualID;          // Handle of corresponding native visual
+	EGLint mNativeVisualType;        // Native visual type of the associated visual
+	EGLint mRenderableType;          // Which client rendering APIs are supported.
+	EGLint mSampleBuffers;           // Number of multisample buffers
+	EGLint mSamples;                 // Number of samples per pixel
+	EGLint mStencilSize;             // Bits of Stencil in the stencil buffer
+	EGLint mSurfaceType;             // Which types of EGL surfaces are supported.
+	EGLenum mTransparentType;        // Type of transparency supported
+	EGLint mTransparentRedValue;     // Transparent red value
+	EGLint mTransparentGreenValue;   // Transparent green value
+	EGLint mTransparentBlueValue;    // Transparent blue value
+
+	EGLBoolean mRecordableAndroid;          // EGL_ANDROID_recordable
+	EGLBoolean mFramebufferTargetAndroid;   // EGL_ANDROID_framebuffer_target
+};
+
+struct CompareConfig
+{
+	bool operator()(const Config &x, const Config &y) const;
+};
+
+class ConfigSet
+{
+	friend class Display;
+
+public:
+	ConfigSet();
+
+	void add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample);
+	size_t size() const;
+	bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
+	const egl::Config *get(EGLConfig configHandle);
+
+private:
+	typedef std::set<Config, CompareConfig> Set;
+	typedef Set::iterator Iterator;
+	Set mSet;
+};
+}
+
+#endif   // INCLUDE_CONFIG_H_
diff --git a/src/OpenGL/libEGL/Context.hpp b/src/OpenGL/libEGL/Context.hpp
index 35d948a..20dcbe0 100644
--- a/src/OpenGL/libEGL/Context.hpp
+++ b/src/OpenGL/libEGL/Context.hpp
@@ -1,29 +1,29 @@
-#ifndef egl_Context_hpp

-#define egl_Context_hpp

-

-#include "common/Object.hpp"

-

-#include <EGL/egl.h>

-#include <GLES/gl.h>

-

-namespace egl

-{

-class Surface;

-class Image;

-

-class Context : public gl::Object

-{

-public:

-	virtual void makeCurrent(Surface *surface) = 0;

-	virtual void bindTexImage(Surface *surface) = 0;

-	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;

-	virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;

-	virtual int getClientVersion() const = 0;

-    virtual void finish() = 0;

-

-protected:

-	virtual ~Context() {};

-};

-}

-

-#endif   // egl_Context_hpp

+#ifndef egl_Context_hpp
+#define egl_Context_hpp
+
+#include "common/Object.hpp"
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+namespace egl
+{
+class Surface;
+class Image;
+
+class Context : public gl::Object
+{
+public:
+	virtual void makeCurrent(Surface *surface) = 0;
+	virtual void bindTexImage(Surface *surface) = 0;
+	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
+	virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
+	virtual int getClientVersion() const = 0;
+	virtual void finish() = 0;
+
+protected:
+	virtual ~Context() {};
+};
+}
+
+#endif   // egl_Context_hpp
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 06fb58d..799b072 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Display.cpp: Implements the egl::Display class, representing the abstract
 // display on which graphics are drawn. Implements EGLDisplay.
@@ -63,13 +66,13 @@
 
 Display::Display(void *nativeDisplay) : nativeDisplay(nativeDisplay)
 {
-    mMinSwapInterval = 1;
-    mMaxSwapInterval = 1;
+	mMinSwapInterval = 1;
+	mMaxSwapInterval = 1;
 }
 
 Display::~Display()
 {
-    terminate();
+	terminate();
 
 	#if defined(__linux__) && !defined(__ANDROID__)
 		if(nativeDisplay && libX11->XCloseDisplay)
@@ -82,10 +85,10 @@
 static void cpuid(int registers[4], int info)
 {
 	#if defined(_WIN32)
-        __cpuid(registers, info);
-    #else
-        __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
-    #endif
+		__cpuid(registers, info);
+	#else
+		__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
+	#endif
 }
 
 static bool detectSSE()
@@ -97,18 +100,18 @@
 
 bool Display::initialize()
 {
-    if(isInitialized())
-    {
-        return true;
-    }
+	if(isInitialized())
+	{
+		return true;
+	}
 
 	if(!detectSSE())
 	{
-        return false;
+		return false;
 	}
 
-    mMinSwapInterval = 0;
-    mMaxSwapInterval = 4;
+	mMinSwapInterval = 0;
+	mMaxSwapInterval = 4;
 
 	const int samples[] =
 	{
@@ -117,37 +120,37 @@
 		4
 	};
 
-    const sw::Format renderTargetFormats[] =
-    {
+	const sw::Format renderTargetFormats[] =
+	{
 	//	sw::FORMAT_A1R5G5B5,
-    //  sw::FORMAT_A2R10G10B10,   // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
-        sw::FORMAT_A8R8G8B8,
-        sw::FORMAT_A8B8G8R8,
-        sw::FORMAT_R5G6B5,
-    //  sw::FORMAT_X1R5G5B5,      // Has no compatible OpenGL ES renderbuffer format
-        sw::FORMAT_X8R8G8B8,
-        sw::FORMAT_X8B8G8R8
-    };
+	//  sw::FORMAT_A2R10G10B10,   // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
+		sw::FORMAT_A8R8G8B8,
+		sw::FORMAT_A8B8G8R8,
+		sw::FORMAT_R5G6B5,
+	//  sw::FORMAT_X1R5G5B5,      // Has no compatible OpenGL ES renderbuffer format
+		sw::FORMAT_X8R8G8B8,
+		sw::FORMAT_X8B8G8R8
+	};
 
-    const sw::Format depthStencilFormats[] =
-    {
-        sw::FORMAT_NULL,
-    //  sw::FORMAT_D16_LOCKABLE,
-        sw::FORMAT_D32,
-    //  sw::FORMAT_D15S1,
-        sw::FORMAT_D24S8,
-        sw::FORMAT_D24X8,
-    //  sw::FORMAT_D24X4S4,
-        sw::FORMAT_D16,
-    //  sw::FORMAT_D32F_LOCKABLE,
-    //  sw::FORMAT_D24FS8
-    };
+	const sw::Format depthStencilFormats[] =
+	{
+		sw::FORMAT_NULL,
+	//  sw::FORMAT_D16_LOCKABLE,
+		sw::FORMAT_D32,
+	//  sw::FORMAT_D15S1,
+		sw::FORMAT_D24S8,
+		sw::FORMAT_D24X8,
+	//  sw::FORMAT_D24X4S4,
+		sw::FORMAT_D16,
+	//  sw::FORMAT_D32F_LOCKABLE,
+	//  sw::FORMAT_D24FS8
+	};
 
 	sw::Format currentDisplayFormat = getDisplayFormat();
-    ConfigSet configSet;
+	ConfigSet configSet;
 
 	for(unsigned int samplesIndex = 0; samplesIndex < sizeof(samples) / sizeof(int); samplesIndex++)
-    {
+	{
 		for(unsigned int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(sw::Format); formatIndex++)
 		{
 			sw::Format renderTargetFormat = renderTargetFormats[formatIndex];
@@ -161,253 +164,253 @@
 		}
 	}
 
-    // Give the sorted configs a unique ID and store them internally
-    EGLint index = 1;
-    for(ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
-    {
-        Config configuration = *config;
-        configuration.mConfigID = index;
-        index++;
+	// Give the sorted configs a unique ID and store them internally
+	EGLint index = 1;
+	for(ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
+	{
+		Config configuration = *config;
+		configuration.mConfigID = index;
+		index++;
 
-        mConfigSet.mSet.insert(configuration);
-    }
+		mConfigSet.mSet.insert(configuration);
+	}
 
-    if(!isInitialized())
-    {
-        terminate();
+	if(!isInitialized())
+	{
+		terminate();
 
-        return false;
-    }
+		return false;
+	}
 
-    return true;
+	return true;
 }
 
 void Display::terminate()
 {
-    while(!mSurfaceSet.empty())
-    {
-        destroySurface(*mSurfaceSet.begin());
-    }
+	while(!mSurfaceSet.empty())
+	{
+		destroySurface(*mSurfaceSet.begin());
+	}
 
-    while(!mContextSet.empty())
-    {
-        destroyContext(*mContextSet.begin());
-    }
+	while(!mContextSet.empty())
+	{
+		destroyContext(*mContextSet.begin());
+	}
 }
 
 bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
 {
-    return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
+	return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
 }
 
 bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
 {
-    const egl::Config *configuration = mConfigSet.get(config);
+	const egl::Config *configuration = mConfigSet.get(config);
 
-    switch(attribute)
-    {
-    case EGL_BUFFER_SIZE:                *value = configuration->mBufferSize;               break;
-    case EGL_ALPHA_SIZE:                 *value = configuration->mAlphaSize;                break;
-    case EGL_BLUE_SIZE:                  *value = configuration->mBlueSize;                 break;
-    case EGL_GREEN_SIZE:                 *value = configuration->mGreenSize;                break;
-    case EGL_RED_SIZE:                   *value = configuration->mRedSize;                  break;
-    case EGL_DEPTH_SIZE:                 *value = configuration->mDepthSize;                break;
-    case EGL_STENCIL_SIZE:               *value = configuration->mStencilSize;              break;
-    case EGL_CONFIG_CAVEAT:              *value = configuration->mConfigCaveat;             break;
-    case EGL_CONFIG_ID:                  *value = configuration->mConfigID;                 break;
-    case EGL_LEVEL:                      *value = configuration->mLevel;                    break;
-    case EGL_NATIVE_RENDERABLE:          *value = configuration->mNativeRenderable;         break;
-    case EGL_NATIVE_VISUAL_ID:           *value = configuration->mNativeVisualID;           break;
-    case EGL_NATIVE_VISUAL_TYPE:         *value = configuration->mNativeVisualType;         break;
-    case EGL_SAMPLES:                    *value = configuration->mSamples;                  break;
-    case EGL_SAMPLE_BUFFERS:             *value = configuration->mSampleBuffers;            break;
-    case EGL_SURFACE_TYPE:               *value = configuration->mSurfaceType;              break;
-    case EGL_TRANSPARENT_TYPE:           *value = configuration->mTransparentType;          break;
-    case EGL_TRANSPARENT_BLUE_VALUE:     *value = configuration->mTransparentBlueValue;     break;
-    case EGL_TRANSPARENT_GREEN_VALUE:    *value = configuration->mTransparentGreenValue;    break;
-    case EGL_TRANSPARENT_RED_VALUE:      *value = configuration->mTransparentRedValue;      break;
-    case EGL_BIND_TO_TEXTURE_RGB:        *value = configuration->mBindToTextureRGB;         break;
-    case EGL_BIND_TO_TEXTURE_RGBA:       *value = configuration->mBindToTextureRGBA;        break;
-    case EGL_MIN_SWAP_INTERVAL:          *value = configuration->mMinSwapInterval;          break;
-    case EGL_MAX_SWAP_INTERVAL:          *value = configuration->mMaxSwapInterval;          break;
-    case EGL_LUMINANCE_SIZE:             *value = configuration->mLuminanceSize;            break;
-    case EGL_ALPHA_MASK_SIZE:            *value = configuration->mAlphaMaskSize;            break;
-    case EGL_COLOR_BUFFER_TYPE:          *value = configuration->mColorBufferType;          break;
-    case EGL_RENDERABLE_TYPE:            *value = configuration->mRenderableType;           break;
-    case EGL_MATCH_NATIVE_PIXMAP:        *value = EGL_FALSE; UNIMPLEMENTED();               break;
-    case EGL_CONFORMANT:                 *value = configuration->mConformant;               break;
-    case EGL_MAX_PBUFFER_WIDTH:          *value = configuration->mMaxPBufferWidth;          break;
-    case EGL_MAX_PBUFFER_HEIGHT:         *value = configuration->mMaxPBufferHeight;         break;
-    case EGL_MAX_PBUFFER_PIXELS:         *value = configuration->mMaxPBufferPixels;         break;
+	switch(attribute)
+	{
+	case EGL_BUFFER_SIZE:                *value = configuration->mBufferSize;               break;
+	case EGL_ALPHA_SIZE:                 *value = configuration->mAlphaSize;                break;
+	case EGL_BLUE_SIZE:                  *value = configuration->mBlueSize;                 break;
+	case EGL_GREEN_SIZE:                 *value = configuration->mGreenSize;                break;
+	case EGL_RED_SIZE:                   *value = configuration->mRedSize;                  break;
+	case EGL_DEPTH_SIZE:                 *value = configuration->mDepthSize;                break;
+	case EGL_STENCIL_SIZE:               *value = configuration->mStencilSize;              break;
+	case EGL_CONFIG_CAVEAT:              *value = configuration->mConfigCaveat;             break;
+	case EGL_CONFIG_ID:                  *value = configuration->mConfigID;                 break;
+	case EGL_LEVEL:                      *value = configuration->mLevel;                    break;
+	case EGL_NATIVE_RENDERABLE:          *value = configuration->mNativeRenderable;         break;
+	case EGL_NATIVE_VISUAL_ID:           *value = configuration->mNativeVisualID;           break;
+	case EGL_NATIVE_VISUAL_TYPE:         *value = configuration->mNativeVisualType;         break;
+	case EGL_SAMPLES:                    *value = configuration->mSamples;                  break;
+	case EGL_SAMPLE_BUFFERS:             *value = configuration->mSampleBuffers;            break;
+	case EGL_SURFACE_TYPE:               *value = configuration->mSurfaceType;              break;
+	case EGL_TRANSPARENT_TYPE:           *value = configuration->mTransparentType;          break;
+	case EGL_TRANSPARENT_BLUE_VALUE:     *value = configuration->mTransparentBlueValue;     break;
+	case EGL_TRANSPARENT_GREEN_VALUE:    *value = configuration->mTransparentGreenValue;    break;
+	case EGL_TRANSPARENT_RED_VALUE:      *value = configuration->mTransparentRedValue;      break;
+	case EGL_BIND_TO_TEXTURE_RGB:        *value = configuration->mBindToTextureRGB;         break;
+	case EGL_BIND_TO_TEXTURE_RGBA:       *value = configuration->mBindToTextureRGBA;        break;
+	case EGL_MIN_SWAP_INTERVAL:          *value = configuration->mMinSwapInterval;          break;
+	case EGL_MAX_SWAP_INTERVAL:          *value = configuration->mMaxSwapInterval;          break;
+	case EGL_LUMINANCE_SIZE:             *value = configuration->mLuminanceSize;            break;
+	case EGL_ALPHA_MASK_SIZE:            *value = configuration->mAlphaMaskSize;            break;
+	case EGL_COLOR_BUFFER_TYPE:          *value = configuration->mColorBufferType;          break;
+	case EGL_RENDERABLE_TYPE:            *value = configuration->mRenderableType;           break;
+	case EGL_MATCH_NATIVE_PIXMAP:        *value = EGL_FALSE; UNIMPLEMENTED();               break;
+	case EGL_CONFORMANT:                 *value = configuration->mConformant;               break;
+	case EGL_MAX_PBUFFER_WIDTH:          *value = configuration->mMaxPBufferWidth;          break;
+	case EGL_MAX_PBUFFER_HEIGHT:         *value = configuration->mMaxPBufferHeight;         break;
+	case EGL_MAX_PBUFFER_PIXELS:         *value = configuration->mMaxPBufferPixels;         break;
 	case EGL_RECORDABLE_ANDROID:         *value = configuration->mRecordableAndroid;        break;
 	case EGL_FRAMEBUFFER_TARGET_ANDROID: *value = configuration->mFramebufferTargetAndroid; break;
-    default:
-        return false;
-    }
+	default:
+		return false;
+	}
 
-    return true;
+	return true;
 }
 
 EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
 {
-    const Config *configuration = mConfigSet.get(config);
+	const Config *configuration = mConfigSet.get(config);
 
-    if(attribList)
-    {
-        while(*attribList != EGL_NONE)
-        {
-            switch (attribList[0])
-            {
-            case EGL_RENDER_BUFFER:
-                switch (attribList[1])
-                {
-                case EGL_BACK_BUFFER:
-                    break;
-                case EGL_SINGLE_BUFFER:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
-                default:
-                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                }
-                break;
-            case EGL_VG_COLORSPACE:
-                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-            case EGL_VG_ALPHA_FORMAT:
-                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-            default:
-                return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-            }
+	if(attribList)
+	{
+		while(*attribList != EGL_NONE)
+		{
+			switch(attribList[0])
+			{
+			case EGL_RENDER_BUFFER:
+				switch(attribList[1])
+				{
+				case EGL_BACK_BUFFER:
+					break;
+				case EGL_SINGLE_BUFFER:
+					return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
+				default:
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+				}
+				break;
+			case EGL_VG_COLORSPACE:
+				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+			case EGL_VG_ALPHA_FORMAT:
+				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+			default:
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+			}
 
-            attribList += 2;
-        }
-    }
+			attribList += 2;
+		}
+	}
 
-    if(hasExistingWindowSurface(window))
-    {
-        return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-    }
+	if(hasExistingWindowSurface(window))
+	{
+		return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+	}
 
-    Surface *surface = new WindowSurface(this, configuration, window);
+	Surface *surface = new WindowSurface(this, configuration, window);
 
-    if(!surface->initialize())
-    {
-        surface->release();
-        return EGL_NO_SURFACE;
-    }
+	if(!surface->initialize())
+	{
+		surface->release();
+		return EGL_NO_SURFACE;
+	}
 
 	surface->addRef();
-    mSurfaceSet.insert(surface);
+	mSurfaceSet.insert(surface);
 
-    return success(surface);
+	return success(surface);
 }
 
 EGLSurface Display::createPBufferSurface(EGLConfig config, const EGLint *attribList)
 {
-    EGLint width = 0, height = 0;
-    EGLenum textureFormat = EGL_NO_TEXTURE;
-    EGLenum textureTarget = EGL_NO_TEXTURE;
+	EGLint width = 0, height = 0;
+	EGLenum textureFormat = EGL_NO_TEXTURE;
+	EGLenum textureTarget = EGL_NO_TEXTURE;
 	EGLBoolean largestPBuffer = EGL_FALSE;
-    const Config *configuration = mConfigSet.get(config);
+	const Config *configuration = mConfigSet.get(config);
 
-    if(attribList)
-    {
-        while(*attribList != EGL_NONE)
-        {
-            switch(attribList[0])
-            {
-            case EGL_WIDTH:
-                width = attribList[1];
-                break;
-            case EGL_HEIGHT:
-                height = attribList[1];
-                break;
-            case EGL_LARGEST_PBUFFER:
-                largestPBuffer = attribList[1];
-                break;
-            case EGL_TEXTURE_FORMAT:
-                switch(attribList[1])
-                {
-                case EGL_NO_TEXTURE:
-                case EGL_TEXTURE_RGB:
-                case EGL_TEXTURE_RGBA:
-                    textureFormat = attribList[1];
-                    break;
-                default:
-                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                }
-                break;
-            case EGL_TEXTURE_TARGET:
-                switch(attribList[1])
-                {
-                case EGL_NO_TEXTURE:
-                case EGL_TEXTURE_2D:
-                    textureTarget = attribList[1];
-                    break;
-                default:
-                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                }
-                break;
-            case EGL_MIPMAP_TEXTURE:
-                if(attribList[1] != EGL_FALSE)
+	if(attribList)
+	{
+		while(*attribList != EGL_NONE)
+		{
+			switch(attribList[0])
+			{
+			case EGL_WIDTH:
+				width = attribList[1];
+				break;
+			case EGL_HEIGHT:
+				height = attribList[1];
+				break;
+			case EGL_LARGEST_PBUFFER:
+				largestPBuffer = attribList[1];
+				break;
+			case EGL_TEXTURE_FORMAT:
+				switch(attribList[1])
+				{
+				case EGL_NO_TEXTURE:
+				case EGL_TEXTURE_RGB:
+				case EGL_TEXTURE_RGBA:
+					textureFormat = attribList[1];
+					break;
+				default:
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+				}
+				break;
+			case EGL_TEXTURE_TARGET:
+				switch(attribList[1])
+				{
+				case EGL_NO_TEXTURE:
+				case EGL_TEXTURE_2D:
+					textureTarget = attribList[1];
+					break;
+				default:
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+				}
+				break;
+			case EGL_MIPMAP_TEXTURE:
+				if(attribList[1] != EGL_FALSE)
 				{
 					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
 				}
-                break;
-            case EGL_VG_COLORSPACE:
-                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-            case EGL_VG_ALPHA_FORMAT:
-                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-            default:
-                return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-            }
+				break;
+			case EGL_VG_COLORSPACE:
+				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+			case EGL_VG_ALPHA_FORMAT:
+				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+			default:
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+			}
 
-            attribList += 2;
-        }
-    }
+			attribList += 2;
+		}
+	}
 
-    if(width < 0 || height < 0)
-    {
-        return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
-    }
+	if(width < 0 || height < 0)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+	}
 
-    if(width == 0 || height == 0)
-    {
-        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-    }
+	if(width == 0 || height == 0)
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+	}
 
-    if((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
-       (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
-    {
-        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-    }
+	if((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
+	   (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
+	{
+		return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+	}
 
-    if(!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
-    {
-        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-    }
+	if(!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
+	{
+		return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+	}
 
-    if((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
-       (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
-    {
-        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-    }
+	if((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
+	   (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+	}
 
-    Surface *surface = new PBufferSurface(this, configuration, width, height, textureFormat, textureTarget, largestPBuffer);
+	Surface *surface = new PBufferSurface(this, configuration, width, height, textureFormat, textureTarget, largestPBuffer);
 
-    if(!surface->initialize())
-    {
-        surface->release();
-        return EGL_NO_SURFACE;
-    }
+	if(!surface->initialize())
+	{
+		surface->release();
+		return EGL_NO_SURFACE;
+	}
 
 	surface->addRef();
-    mSurfaceSet.insert(surface);
+	mSurfaceSet.insert(surface);
 
-    return success(surface);
+	return success(surface);
 }
 
 EGLContext Display::createContext(EGLConfig configHandle, const egl::Context *shareContext, EGLint clientVersion)
 {
-    const egl::Config *config = mConfigSet.get(configHandle);
+	const egl::Config *config = mConfigSet.get(configHandle);
 	egl::Context *context = 0;
 
 	if(clientVersion == 1 && config->mRenderableType & EGL_OPENGL_ES_BIT)
@@ -419,9 +422,9 @@
 	}
 	else if((clientVersion == 2 && config->mRenderableType & EGL_OPENGL_ES2_BIT)
 #ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
-	     || (clientVersion == 3 && config->mRenderableType & EGL_OPENGL_ES3_BIT)
+		 || (clientVersion == 3 && config->mRenderableType & EGL_OPENGL_ES3_BIT)
 #endif
-	        )
+			)
 	{
 		if(libGLESv2)
 		{
@@ -441,7 +444,7 @@
 	context->addRef();
 	mContextSet.insert(context);
 
-    return success(context);
+	return success(context);
 }
 
 EGLSyncKHR Display::createSync(Context *context)
@@ -456,7 +459,7 @@
 void Display::destroySurface(egl::Surface *surface)
 {
 	surface->release();
-    mSurfaceSet.erase(surface);
+	mSurfaceSet.erase(surface);
 
 	if(surface == getCurrentDrawSurface())
 	{
@@ -472,7 +475,7 @@
 void Display::destroyContext(egl::Context *context)
 {
 	context->release();
-    mContextSet.erase(context);
+	mContextSet.erase(context);
 
 	if(context == getCurrentContext())
 	{
@@ -491,29 +494,29 @@
 
 bool Display::isInitialized() const
 {
-    return mConfigSet.size() > 0;
+	return mConfigSet.size() > 0;
 }
 
 bool Display::isValidConfig(EGLConfig config)
 {
-    return mConfigSet.get(config) != nullptr;
+	return mConfigSet.get(config) != nullptr;
 }
 
 bool Display::isValidContext(egl::Context *context)
 {
-    return mContextSet.find(context) != mContextSet.end();
+	return mContextSet.find(context) != mContextSet.end();
 }
 
 bool Display::isValidSurface(egl::Surface *surface)
 {
-    return mSurfaceSet.find(surface) != mSurfaceSet.end();
+	return mSurfaceSet.find(surface) != mSurfaceSet.end();
 }
 
 bool Display::isValidWindow(EGLNativeWindowType window)
 {
-    #if defined(_WIN32)
-        return IsWindow(window) == TRUE;
-    #elif defined(__ANDROID__)
+	#if defined(_WIN32)
+		return IsWindow(window) == TRUE;
+	#elif defined(__ANDROID__)
 		if(!window)
 		{
 			ALOGE("%s called with window==NULL %s:%d", __FUNCTION__, __FILE__, __LINE__);
@@ -525,27 +528,27 @@
 			return false;
 		}
 		return true;
-    #elif defined(__linux__)
-        if(nativeDisplay)
-        {
-            XWindowAttributes windowAttributes;
-            Status status = libX11->XGetWindowAttributes((::Display*)nativeDisplay, window, &windowAttributes);
+	#elif defined(__linux__)
+		if(nativeDisplay)
+		{
+			XWindowAttributes windowAttributes;
+			Status status = libX11->XGetWindowAttributes((::Display*)nativeDisplay, window, &windowAttributes);
 
-            return status == True;
-        }
-    #elif defined(__APPLE__)
-        return sw::OSX::IsValidWindow(window);
-    #else
-        #error "Display::isValidWindow unimplemented for this platform"
-    #endif
+			return status == True;
+		}
+	#elif defined(__APPLE__)
+		return sw::OSX::IsValidWindow(window);
+	#else
+		#error "Display::isValidWindow unimplemented for this platform"
+	#endif
 
-    return false;
+	return false;
 }
 
 bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
 {
-    for(SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
-    {
+	for(SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+	{
 		if((*surface)->isWindowSurface())
 		{
 			if((*surface)->getWindowHandle() == window)
@@ -553,9 +556,9 @@
 				return true;
 			}
 		}
-    }
+	}
 
-    return false;
+	return false;
 }
 
 bool Display::isValidSync(FenceSync *sync)
@@ -565,12 +568,12 @@
 
 EGLint Display::getMinSwapInterval() const
 {
-    return mMinSwapInterval;
+	return mMinSwapInterval;
 }
 
 EGLint Display::getMaxSwapInterval() const
 {
-    return mMaxSwapInterval;
+	return mMaxSwapInterval;
 }
 
 void *Display::getNativeDisplay() const
@@ -654,28 +657,28 @@
 
 		// No framebuffer device found, or we're in user space
 		return sw::FORMAT_X8B8G8R8;
-    #elif defined(__linux__)
-        if(nativeDisplay)
-        {
-            Screen *screen = libX11->XDefaultScreenOfDisplay((::Display*)nativeDisplay);
-            unsigned int bpp = libX11->XPlanesOfScreen(screen);
+	#elif defined(__linux__)
+		if(nativeDisplay)
+		{
+			Screen *screen = libX11->XDefaultScreenOfDisplay((::Display*)nativeDisplay);
+			unsigned int bpp = libX11->XPlanesOfScreen(screen);
 
-            switch(bpp)
-            {
-            case 32: return sw::FORMAT_X8R8G8B8;
-            case 24: return sw::FORMAT_R8G8B8;
-            case 16: return sw::FORMAT_R5G6B5;
-            default: UNREACHABLE(bpp);   // Unexpected display mode color depth
-            }
-        }
-        else
-        {
-            return sw::FORMAT_X8R8G8B8;
-        }
-    #elif defined(__APPLE__)
-        return sw::FORMAT_A8B8G8R8;
-    #else
-        #error "Display::isValidWindow unimplemented for this platform"
+			switch(bpp)
+			{
+			case 32: return sw::FORMAT_X8R8G8B8;
+			case 24: return sw::FORMAT_R8G8B8;
+			case 16: return sw::FORMAT_R5G6B5;
+			default: UNREACHABLE(bpp);   // Unexpected display mode color depth
+			}
+		}
+		else
+		{
+			return sw::FORMAT_X8R8G8B8;
+		}
+	#elif defined(__APPLE__)
+		return sw::FORMAT_A8B8G8R8;
+	#else
+		#error "Display::isValidWindow unimplemented for this platform"
 	#endif
 
 	return sw::FORMAT_X8R8G8B8;
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h
index 3864770..14d0fe3 100644
--- a/src/OpenGL/libEGL/Display.h
+++ b/src/OpenGL/libEGL/Display.h
@@ -1,90 +1,93 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Display.h: Defines the egl::Display class, representing the abstract

-// display on which graphics are drawn. Implements EGLDisplay.

-// [EGL 1.4] section 2.1.2 page 3.

-

-#ifndef INCLUDE_DISPLAY_H_

-#define INCLUDE_DISPLAY_H_

-

-#include "Config.h"

-#include "Sync.hpp"

-

-#include <set>

-

-namespace egl

-{

-	class Surface;

-	class Context;

-

-	const EGLDisplay PRIMARY_DISPLAY = (EGLDisplay)1;

-	const EGLDisplay HEADLESS_DISPLAY = (EGLDisplay)0xFACE1E55;

-

-	class Display

-	{

-	public:

-		static Display *get(EGLDisplay dpy);

-

-		bool initialize();

-		void terminate();

-

-		bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);

-		bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);

-

-		EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);

-		EGLSurface createPBufferSurface(EGLConfig config, const EGLint *attribList);

-		EGLContext createContext(EGLConfig configHandle, const Context *shareContext, EGLint clientVersion);

-		EGLSyncKHR createSync(Context *context);

-

-		void destroySurface(Surface *surface);

-		void destroyContext(Context *context);

-		void destroySync(FenceSync *sync);

-

-		bool isInitialized() const;

-		bool isValidConfig(EGLConfig config);

-		bool isValidContext(Context *context);

-		bool isValidSurface(Surface *surface);

-		bool isValidWindow(EGLNativeWindowType window);

-		bool hasExistingWindowSurface(EGLNativeWindowType window);

-		bool isValidSync(FenceSync *sync);

-

-		EGLint getMinSwapInterval() const;

-		EGLint getMaxSwapInterval() const;

-

-		void *getNativeDisplay() const;

-		const char *getExtensionString() const;

-

-	private:

-		explicit Display(void *nativeDisplay);

-		~Display();

-

-		sw::Format getDisplayFormat() const;

-

-		void *const nativeDisplay;

-

-		EGLint mMaxSwapInterval;

-		EGLint mMinSwapInterval;

-

-		typedef std::set<Surface*> SurfaceSet;

-		SurfaceSet mSurfaceSet;

-

-		ConfigSet mConfigSet;

-

-		typedef std::set<Context*> ContextSet;

-		ContextSet mContextSet;

-

-		typedef std::set<FenceSync*> SyncSet;

-		SyncSet mSyncSet;

-	};

-}

-

-#endif   // INCLUDE_DISPLAY_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Display.h: Defines the egl::Display class, representing the abstract
+// display on which graphics are drawn. Implements EGLDisplay.
+// [EGL 1.4] section 2.1.2 page 3.
+
+#ifndef INCLUDE_DISPLAY_H_
+#define INCLUDE_DISPLAY_H_
+
+#include "Config.h"
+#include "Sync.hpp"
+
+#include <set>
+
+namespace egl
+{
+	class Surface;
+	class Context;
+
+	const EGLDisplay PRIMARY_DISPLAY = (EGLDisplay)1;
+	const EGLDisplay HEADLESS_DISPLAY = (EGLDisplay)0xFACE1E55;
+
+	class Display
+	{
+	public:
+		static Display *get(EGLDisplay dpy);
+
+		bool initialize();
+		void terminate();
+
+		bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
+		bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
+
+		EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
+		EGLSurface createPBufferSurface(EGLConfig config, const EGLint *attribList);
+		EGLContext createContext(EGLConfig configHandle, const Context *shareContext, EGLint clientVersion);
+		EGLSyncKHR createSync(Context *context);
+
+		void destroySurface(Surface *surface);
+		void destroyContext(Context *context);
+		void destroySync(FenceSync *sync);
+
+		bool isInitialized() const;
+		bool isValidConfig(EGLConfig config);
+		bool isValidContext(Context *context);
+		bool isValidSurface(Surface *surface);
+		bool isValidWindow(EGLNativeWindowType window);
+		bool hasExistingWindowSurface(EGLNativeWindowType window);
+		bool isValidSync(FenceSync *sync);
+
+		EGLint getMinSwapInterval() const;
+		EGLint getMaxSwapInterval() const;
+
+		void *getNativeDisplay() const;
+		const char *getExtensionString() const;
+
+	private:
+		explicit Display(void *nativeDisplay);
+		~Display();
+
+		sw::Format getDisplayFormat() const;
+
+		void *const nativeDisplay;
+
+		EGLint mMaxSwapInterval;
+		EGLint mMinSwapInterval;
+
+		typedef std::set<Surface*> SurfaceSet;
+		SurfaceSet mSurfaceSet;
+
+		ConfigSet mConfigSet;
+
+		typedef std::set<Context*> ContextSet;
+		ContextSet mContextSet;
+
+		typedef std::set<FenceSync*> SyncSet;
+		SyncSet mSyncSet;
+	};
+}
+
+#endif   // INCLUDE_DISPLAY_H_
diff --git a/src/OpenGL/libEGL/OSXUtils.hpp b/src/OpenGL/libEGL/OSXUtils.hpp
index 26f703a..3830b8b 100644
--- a/src/OpenGL/libEGL/OSXUtils.hpp
+++ b/src/OpenGL/libEGL/OSXUtils.hpp
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #ifndef	sw_OSXUtils_hpp
 #define	sw_OSXUtils_hpp
 
diff --git a/src/OpenGL/libEGL/OSXUtils.mm b/src/OpenGL/libEGL/OSXUtils.mm
index aaa6843..e346728 100644
--- a/src/OpenGL/libEGL/OSXUtils.mm
+++ b/src/OpenGL/libEGL/OSXUtils.mm
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #include "OSXUtils.hpp"
 
 #include "common/debug.h"
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index 345454f..b1e573b 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -1,373 +1,376 @@
-// 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.

-//

-

-// Surface.cpp: Implements the egl::Surface class, representing a drawing surface

-// such as the client area of a window, including any back buffers.

-// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

-

-#include "Surface.h"

-

-#include "main.h"

-#include "Display.h"

-#include "Texture.hpp"

-#include "common/Image.hpp"

-#include "Context.hpp"

-#include "common/debug.h"

-#include "Main/FrameBuffer.hpp"

-

-#if defined(__linux__) && !defined(__ANDROID__)

-#include "Main/libX11.hpp"

-#elif defined(_WIN32)

-#include <tchar.h>

-#elif defined(__APPLE__)

-#include "OSXUtils.hpp"

-#endif

-

-#include <algorithm>

-

-namespace egl

-{

-

-Surface::Surface(const Display *display, const Config *config) : display(display), config(config)

-{

-	backBuffer = nullptr;

-    depthStencil = nullptr;

-    texture = nullptr;

-

-	width = 0;

-	height = 0;

-	largestPBuffer = EGL_FALSE;

-    pixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio

-    renderBuffer = EGL_BACK_BUFFER;

-    swapBehavior = EGL_BUFFER_PRESERVED;

-	textureFormat = EGL_NO_TEXTURE;

-    textureTarget = EGL_NO_TEXTURE;

-    swapInterval = -1;

-    setSwapInterval(1);

-}

-

-Surface::~Surface()

-{

-    Surface::deleteResources();

-}

-

-bool Surface::initialize()

-{

-	ASSERT(!backBuffer && !depthStencil);

-

-	if(libGLES_CM)

-	{

-		backBuffer = libGLES_CM->createBackBuffer(width, height, config);

-	}

-	else if(libGLESv2)

-	{

-		backBuffer = libGLESv2->createBackBuffer(width, height, config);

-	}

-

-    if(!backBuffer)

-    {

-        ERR("Could not create back buffer");

-        deleteResources();

-        return error(EGL_BAD_ALLOC, false);

-    }

-

-    if(config->mDepthStencilFormat != sw::FORMAT_NULL)

-    {

-		if(libGLES_CM)

-		{

-			depthStencil = libGLES_CM->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);

-		}

-		else if(libGLESv2)

-		{

-			depthStencil = libGLESv2->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);

-		}

-

-		if(!depthStencil)

-		{

-			ERR("Could not create depth/stencil buffer for surface");

-			deleteResources();

-			return error(EGL_BAD_ALLOC, false);

-		}

-    }

-

-	return true;

-}

-

-void Surface::deleteResources()

-{

-    if(depthStencil)

-    {

-        depthStencil->release();

-        depthStencil = nullptr;

-    }

-

-    if(texture)

-    {

-        texture->releaseTexImage();

-        texture = nullptr;

-    }

-

-	if(backBuffer)

-	{

-		backBuffer->release();

-		backBuffer = nullptr;

-	}

-}

-

-egl::Image *Surface::getRenderTarget()

-{

-    if(backBuffer)

-    {

-        backBuffer->addRef();

-    }

-

-    return backBuffer;

-}

-

-egl::Image *Surface::getDepthStencil()

-{

-    if(depthStencil)

-    {

-        depthStencil->addRef();

-    }

-

-    return depthStencil;

-}

-

-void Surface::setSwapBehavior(EGLenum swapBehavior)

-{

-	this->swapBehavior = swapBehavior;

-}

-

-void Surface::setSwapInterval(EGLint interval)

-{

-    if(swapInterval == interval)

-    {

-        return;

-    }

-

-    swapInterval = interval;

-    swapInterval = std::max(swapInterval, display->getMinSwapInterval());

-    swapInterval = std::min(swapInterval, display->getMaxSwapInterval());

-}

-

-EGLint Surface::getConfigID() const

-{

-    return config->mConfigID;

-}

-

-EGLenum Surface::getSurfaceType() const

-{

-    return config->mSurfaceType;

-}

-

-sw::Format Surface::getInternalFormat() const

-{

-    return config->mRenderTargetFormat;

-}

-

-EGLint Surface::getWidth() const

-{

-    return width;

-}

-

-EGLint Surface::getHeight() const

-{

-    return height;

-}

-

-EGLint Surface::getPixelAspectRatio() const

-{

-    return pixelAspectRatio;

-}

-

-EGLenum Surface::getRenderBuffer() const

-{

-    return renderBuffer;

-}

-

-EGLenum Surface::getSwapBehavior() const

-{

-    return swapBehavior;

-}

-

-EGLenum Surface::getTextureFormat() const

-{

-    return textureFormat;

-}

-

-EGLenum Surface::getTextureTarget() const

-{

-    return textureTarget;

-}

-

-EGLBoolean Surface::getLargestPBuffer() const

-{

-	return largestPBuffer;

-}

-

-void Surface::setBoundTexture(egl::Texture *texture)

-{

-    this->texture = texture;

-}

-

-egl::Texture *Surface::getBoundTexture() const

-{

-    return texture;

-}

-

-WindowSurface::WindowSurface(Display *display, const Config *config, EGLNativeWindowType window)

-    : Surface(display, config), window(window)

-{

-    frameBuffer = nullptr;

-}

-

-WindowSurface::~WindowSurface()

-{

-	WindowSurface::deleteResources();

-}

-

-bool WindowSurface::initialize()

-{

-    ASSERT(!frameBuffer && !backBuffer && !depthStencil);

-

-	return checkForResize();

-}

-

-void WindowSurface::swap()

-{

-	if(backBuffer && frameBuffer)

-    {

-		void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-		frameBuffer->flip(source, backBuffer->sw::Surface::getInternalFormat(), backBuffer->getInternalPitchB());

-		backBuffer->unlockInternal();

-

-        checkForResize();

-	}

-}

-

-EGLNativeWindowType WindowSurface::getWindowHandle() const

-{

-    return window;

-}

-

-bool WindowSurface::checkForResize()

-{

-    #if defined(_WIN32)

-		RECT client;

-		if(!GetClientRect(window, &client))

-		{

-			ASSERT(false);

-			return false;

-		}

-

-		int windowWidth = client.right - client.left;

-		int windowHeight = client.bottom - client.top;

-	#elif defined(__ANDROID__)

-		int windowWidth;  window->query(window, NATIVE_WINDOW_WIDTH, &windowWidth);

-		int windowHeight; window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);

-	#elif defined(__linux__)

-		XWindowAttributes windowAttributes;

-		libX11->XGetWindowAttributes((::Display*)display->getNativeDisplay(), window, &windowAttributes);

-

-		int windowWidth = windowAttributes.width;

-		int windowHeight = windowAttributes.height;

-	#elif defined(__APPLE__)

-		int windowWidth;

-		int windowHeight;

-		sw::OSX::GetNativeWindowSize(window, windowWidth, windowHeight);

-	#else

-		#error "WindowSurface::checkForResize unimplemented for this platform"

-	#endif

-

-    if((windowWidth != width) || (windowHeight != height))

-    {

-        bool success = reset(windowWidth, windowHeight);

-

-        if(getCurrentDrawSurface() == this)

-        {

-			getCurrentContext()->makeCurrent(this);

-        }

-

-        return success;

-    }

-

-    return true;   // Success

-}

-

-void WindowSurface::deleteResources()

-{

-	delete frameBuffer;

-	frameBuffer = nullptr;

-

-	Surface::deleteResources();

-}

-

-bool WindowSurface::reset(int backBufferWidth, int backBufferHeight)

-{

-	width = backBufferWidth;

-    height = backBufferHeight;

-

-    deleteResources();

-

-    if(window)

-    {

-		if(libGLES_CM)

-		{

-			frameBuffer = libGLES_CM->createFrameBuffer(display->getNativeDisplay(), window, width, height);

-		}

-		else if(libGLESv2)

-		{

-			frameBuffer = libGLESv2->createFrameBuffer(display->getNativeDisplay(), window, width, height);

-		}

-

-		if(!frameBuffer)

-		{

-			ERR("Could not create frame buffer");

-			deleteResources();

-			return error(EGL_BAD_ALLOC, false);

-		}

-    }

-

-	return Surface::initialize();

-}

-

-PBufferSurface::PBufferSurface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType, EGLBoolean largestPBuffer)

-    : Surface(display, config)

-{

-	this->width = width;

-	this->height = height;

-	this->largestPBuffer = largestPBuffer;

-}

-

-PBufferSurface::~PBufferSurface()

-{

-	PBufferSurface::deleteResources();

-}

-

-void PBufferSurface::swap()

-{

-	// No effect

-}

-

-EGLNativeWindowType PBufferSurface::getWindowHandle() const

-{

-	UNREACHABLE(-1);   // Should not be called. Only WindowSurface has a window handle.

-

-    return 0;

-}

-

-void PBufferSurface::deleteResources()

-{

-	Surface::deleteResources();

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
+// such as the client area of a window, including any back buffers.
+// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
+
+#include "Surface.h"
+
+#include "main.h"
+#include "Display.h"
+#include "Texture.hpp"
+#include "common/Image.hpp"
+#include "Context.hpp"
+#include "common/debug.h"
+#include "Main/FrameBuffer.hpp"
+
+#if defined(__linux__) && !defined(__ANDROID__)
+#include "Main/libX11.hpp"
+#elif defined(_WIN32)
+#include <tchar.h>
+#elif defined(__APPLE__)
+#include "OSXUtils.hpp"
+#endif
+
+#include <algorithm>
+
+namespace egl
+{
+
+Surface::Surface(const Display *display, const Config *config) : display(display), config(config)
+{
+	backBuffer = nullptr;
+	depthStencil = nullptr;
+	texture = nullptr;
+
+	width = 0;
+	height = 0;
+	largestPBuffer = EGL_FALSE;
+	pixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
+	renderBuffer = EGL_BACK_BUFFER;
+	swapBehavior = EGL_BUFFER_PRESERVED;
+	textureFormat = EGL_NO_TEXTURE;
+	textureTarget = EGL_NO_TEXTURE;
+	swapInterval = -1;
+	setSwapInterval(1);
+}
+
+Surface::~Surface()
+{
+	Surface::deleteResources();
+}
+
+bool Surface::initialize()
+{
+	ASSERT(!backBuffer && !depthStencil);
+
+	if(libGLES_CM)
+	{
+		backBuffer = libGLES_CM->createBackBuffer(width, height, config);
+	}
+	else if(libGLESv2)
+	{
+		backBuffer = libGLESv2->createBackBuffer(width, height, config);
+	}
+
+	if(!backBuffer)
+	{
+		ERR("Could not create back buffer");
+		deleteResources();
+		return error(EGL_BAD_ALLOC, false);
+	}
+
+	if(config->mDepthStencilFormat != sw::FORMAT_NULL)
+	{
+		if(libGLES_CM)
+		{
+			depthStencil = libGLES_CM->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);
+		}
+		else if(libGLESv2)
+		{
+			depthStencil = libGLESv2->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);
+		}
+
+		if(!depthStencil)
+		{
+			ERR("Could not create depth/stencil buffer for surface");
+			deleteResources();
+			return error(EGL_BAD_ALLOC, false);
+		}
+	}
+
+	return true;
+}
+
+void Surface::deleteResources()
+{
+	if(depthStencil)
+	{
+		depthStencil->release();
+		depthStencil = nullptr;
+	}
+
+	if(texture)
+	{
+		texture->releaseTexImage();
+		texture = nullptr;
+	}
+
+	if(backBuffer)
+	{
+		backBuffer->release();
+		backBuffer = nullptr;
+	}
+}
+
+egl::Image *Surface::getRenderTarget()
+{
+	if(backBuffer)
+	{
+		backBuffer->addRef();
+	}
+
+	return backBuffer;
+}
+
+egl::Image *Surface::getDepthStencil()
+{
+	if(depthStencil)
+	{
+		depthStencil->addRef();
+	}
+
+	return depthStencil;
+}
+
+void Surface::setSwapBehavior(EGLenum swapBehavior)
+{
+	this->swapBehavior = swapBehavior;
+}
+
+void Surface::setSwapInterval(EGLint interval)
+{
+	if(swapInterval == interval)
+	{
+		return;
+	}
+
+	swapInterval = interval;
+	swapInterval = std::max(swapInterval, display->getMinSwapInterval());
+	swapInterval = std::min(swapInterval, display->getMaxSwapInterval());
+}
+
+EGLint Surface::getConfigID() const
+{
+	return config->mConfigID;
+}
+
+EGLenum Surface::getSurfaceType() const
+{
+	return config->mSurfaceType;
+}
+
+sw::Format Surface::getInternalFormat() const
+{
+	return config->mRenderTargetFormat;
+}
+
+EGLint Surface::getWidth() const
+{
+	return width;
+}
+
+EGLint Surface::getHeight() const
+{
+	return height;
+}
+
+EGLint Surface::getPixelAspectRatio() const
+{
+	return pixelAspectRatio;
+}
+
+EGLenum Surface::getRenderBuffer() const
+{
+	return renderBuffer;
+}
+
+EGLenum Surface::getSwapBehavior() const
+{
+	return swapBehavior;
+}
+
+EGLenum Surface::getTextureFormat() const
+{
+	return textureFormat;
+}
+
+EGLenum Surface::getTextureTarget() const
+{
+	return textureTarget;
+}
+
+EGLBoolean Surface::getLargestPBuffer() const
+{
+	return largestPBuffer;
+}
+
+void Surface::setBoundTexture(egl::Texture *texture)
+{
+	this->texture = texture;
+}
+
+egl::Texture *Surface::getBoundTexture() const
+{
+	return texture;
+}
+
+WindowSurface::WindowSurface(Display *display, const Config *config, EGLNativeWindowType window)
+	: Surface(display, config), window(window)
+{
+	frameBuffer = nullptr;
+}
+
+WindowSurface::~WindowSurface()
+{
+	WindowSurface::deleteResources();
+}
+
+bool WindowSurface::initialize()
+{
+	ASSERT(!frameBuffer && !backBuffer && !depthStencil);
+
+	return checkForResize();
+}
+
+void WindowSurface::swap()
+{
+	if(backBuffer && frameBuffer)
+	{
+		void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+		frameBuffer->flip(source, backBuffer->sw::Surface::getInternalFormat(), backBuffer->getInternalPitchB());
+		backBuffer->unlockInternal();
+
+		checkForResize();
+	}
+}
+
+EGLNativeWindowType WindowSurface::getWindowHandle() const
+{
+	return window;
+}
+
+bool WindowSurface::checkForResize()
+{
+	#if defined(_WIN32)
+		RECT client;
+		if(!GetClientRect(window, &client))
+		{
+			ASSERT(false);
+			return false;
+		}
+
+		int windowWidth = client.right - client.left;
+		int windowHeight = client.bottom - client.top;
+	#elif defined(__ANDROID__)
+		int windowWidth;  window->query(window, NATIVE_WINDOW_WIDTH, &windowWidth);
+		int windowHeight; window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);
+	#elif defined(__linux__)
+		XWindowAttributes windowAttributes;
+		libX11->XGetWindowAttributes((::Display*)display->getNativeDisplay(), window, &windowAttributes);
+
+		int windowWidth = windowAttributes.width;
+		int windowHeight = windowAttributes.height;
+	#elif defined(__APPLE__)
+		int windowWidth;
+		int windowHeight;
+		sw::OSX::GetNativeWindowSize(window, windowWidth, windowHeight);
+	#else
+		#error "WindowSurface::checkForResize unimplemented for this platform"
+	#endif
+
+	if((windowWidth != width) || (windowHeight != height))
+	{
+		bool success = reset(windowWidth, windowHeight);
+
+		if(getCurrentDrawSurface() == this)
+		{
+			getCurrentContext()->makeCurrent(this);
+		}
+
+		return success;
+	}
+
+	return true;   // Success
+}
+
+void WindowSurface::deleteResources()
+{
+	delete frameBuffer;
+	frameBuffer = nullptr;
+
+	Surface::deleteResources();
+}
+
+bool WindowSurface::reset(int backBufferWidth, int backBufferHeight)
+{
+	width = backBufferWidth;
+	height = backBufferHeight;
+
+	deleteResources();
+
+	if(window)
+	{
+		if(libGLES_CM)
+		{
+			frameBuffer = libGLES_CM->createFrameBuffer(display->getNativeDisplay(), window, width, height);
+		}
+		else if(libGLESv2)
+		{
+			frameBuffer = libGLESv2->createFrameBuffer(display->getNativeDisplay(), window, width, height);
+		}
+
+		if(!frameBuffer)
+		{
+			ERR("Could not create frame buffer");
+			deleteResources();
+			return error(EGL_BAD_ALLOC, false);
+		}
+	}
+
+	return Surface::initialize();
+}
+
+PBufferSurface::PBufferSurface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType, EGLBoolean largestPBuffer)
+	: Surface(display, config)
+{
+	this->width = width;
+	this->height = height;
+	this->largestPBuffer = largestPBuffer;
+}
+
+PBufferSurface::~PBufferSurface()
+{
+	PBufferSurface::deleteResources();
+}
+
+void PBufferSurface::swap()
+{
+	// No effect
+}
+
+EGLNativeWindowType PBufferSurface::getWindowHandle() const
+{
+	UNREACHABLE(-1);   // Should not be called. Only WindowSurface has a window handle.
+
+	return 0;
+}
+
+void PBufferSurface::deleteResources()
+{
+	Surface::deleteResources();
+}
+
+}
diff --git a/src/OpenGL/libEGL/Surface.h b/src/OpenGL/libEGL/Surface.h
index 55589d2..f086823 100644
--- a/src/OpenGL/libEGL/Surface.h
+++ b/src/OpenGL/libEGL/Surface.h
@@ -1,134 +1,137 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Surface.h: Defines the egl::Surface class, representing a drawing surface

-// such as the client area of a window, including any back buffers.

-// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

-

-#ifndef INCLUDE_SURFACE_H_

-#define INCLUDE_SURFACE_H_

-

-#include "Main/FrameBuffer.hpp"

-#include "common/Object.hpp"

-

-#include <EGL/egl.h>

-

-namespace egl

-{

-class Display;

-class Config;

-class Texture;

-class Image;

-

-class Surface : public gl::Object

-{

-public:

-	virtual bool initialize();

-    virtual void swap() = 0;

-

-    virtual egl::Image *getRenderTarget();

-    virtual egl::Image *getDepthStencil();

-

-	void setSwapBehavior(EGLenum swapBehavior);

-    void setSwapInterval(EGLint interval);

-

-    virtual EGLint getConfigID() const;

-	virtual EGLenum getSurfaceType() const;

-	virtual sw::Format getInternalFormat() const;

-

-    virtual EGLint getWidth() const;

-    virtual EGLint getHeight() const;

-    virtual EGLint getPixelAspectRatio() const;

-    virtual EGLenum getRenderBuffer() const;

-    virtual EGLenum getSwapBehavior() const;

-    virtual EGLenum getTextureFormat() const;

-    virtual EGLenum getTextureTarget() const;

-	virtual EGLBoolean getLargestPBuffer() const;

-	virtual EGLNativeWindowType getWindowHandle() const = 0;

-

-    virtual void setBoundTexture(egl::Texture *texture);

-    virtual egl::Texture *getBoundTexture() const;

-

-	virtual bool isWindowSurface() const { return false; }

-	virtual bool isPBufferSurface() const { return false; }

-

-protected:

-	Surface(const Display *display, const Config *config);

-

-	virtual ~Surface();

-

-    virtual void deleteResources();

-

-    const Display *const display;

-    Image *depthStencil;

-	Image *backBuffer;

-	Texture *texture;

-

-	bool reset(int backbufferWidth, int backbufferHeight);

-

-	const Config *const config;    // EGL config surface was created with

-	EGLint height;                 // Height of surface

-	EGLint width;                  // Width of surface

-//  EGLint horizontalResolution;   // Horizontal dot pitch

-//  EGLint verticalResolution;     // Vertical dot pitch

-	EGLBoolean largestPBuffer;     // If true, create largest pbuffer possible

-//  EGLBoolean mipmapTexture;      // True if texture has mipmaps

-//  EGLint mipmapLevel;            // Mipmap level to render to

-//  EGLenum multisampleResolve;    // Multisample resolve behavior

-	EGLint pixelAspectRatio;       // Display aspect ratio

-	EGLenum renderBuffer;          // Render buffer

-	EGLenum swapBehavior;          // Buffer swap behavior

-	EGLenum textureFormat;         // Format of texture: RGB, RGBA, or no texture

-	EGLenum textureTarget;         // Type of texture: 2D or no texture

-//  EGLenum vgAlphaFormat;         // Alpha format for OpenVG

-//  EGLenum vgColorSpace;          // Color space for OpenVG

-	EGLint swapInterval;

-};

-

-class WindowSurface : public Surface

-{

-public:

-	WindowSurface(Display *display, const egl::Config *config, EGLNativeWindowType window);

-	~WindowSurface() override;

-

-	bool initialize() override;

-

-	bool isWindowSurface() const override { return true; }

-	void swap() override;

-

-	EGLNativeWindowType getWindowHandle() const override;

-

-private:

-	void deleteResources() override;

-	bool checkForResize();

-	bool reset(int backBufferWidth, int backBufferHeight);

-

-	const EGLNativeWindowType window;

-	sw::FrameBuffer *frameBuffer;

-};

-

-class PBufferSurface : public Surface

-{

-public:

-	PBufferSurface(Display *display, const egl::Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget, EGLBoolean largestPBuffer);

-	~PBufferSurface() override;

-

-	bool isPBufferSurface() const override { return true; }

-	void swap() override;

-

-	EGLNativeWindowType getWindowHandle() const override;

-

-private:

-	void deleteResources() override;

-};

-}

-

-#endif   // INCLUDE_SURFACE_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Surface.h: Defines the egl::Surface class, representing a drawing surface
+// such as the client area of a window, including any back buffers.
+// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
+
+#ifndef INCLUDE_SURFACE_H_
+#define INCLUDE_SURFACE_H_
+
+#include "Main/FrameBuffer.hpp"
+#include "common/Object.hpp"
+
+#include <EGL/egl.h>
+
+namespace egl
+{
+class Display;
+class Config;
+class Texture;
+class Image;
+
+class Surface : public gl::Object
+{
+public:
+	virtual bool initialize();
+	virtual void swap() = 0;
+
+	virtual egl::Image *getRenderTarget();
+	virtual egl::Image *getDepthStencil();
+
+	void setSwapBehavior(EGLenum swapBehavior);
+	void setSwapInterval(EGLint interval);
+
+	virtual EGLint getConfigID() const;
+	virtual EGLenum getSurfaceType() const;
+	virtual sw::Format getInternalFormat() const;
+
+	virtual EGLint getWidth() const;
+	virtual EGLint getHeight() const;
+	virtual EGLint getPixelAspectRatio() const;
+	virtual EGLenum getRenderBuffer() const;
+	virtual EGLenum getSwapBehavior() const;
+	virtual EGLenum getTextureFormat() const;
+	virtual EGLenum getTextureTarget() const;
+	virtual EGLBoolean getLargestPBuffer() const;
+	virtual EGLNativeWindowType getWindowHandle() const = 0;
+
+	virtual void setBoundTexture(egl::Texture *texture);
+	virtual egl::Texture *getBoundTexture() const;
+
+	virtual bool isWindowSurface() const { return false; }
+	virtual bool isPBufferSurface() const { return false; }
+
+protected:
+	Surface(const Display *display, const Config *config);
+
+	virtual ~Surface();
+
+	virtual void deleteResources();
+
+	const Display *const display;
+	Image *depthStencil;
+	Image *backBuffer;
+	Texture *texture;
+
+	bool reset(int backbufferWidth, int backbufferHeight);
+
+	const Config *const config;    // EGL config surface was created with
+	EGLint height;                 // Height of surface
+	EGLint width;                  // Width of surface
+//  EGLint horizontalResolution;   // Horizontal dot pitch
+//  EGLint verticalResolution;     // Vertical dot pitch
+	EGLBoolean largestPBuffer;     // If true, create largest pbuffer possible
+//  EGLBoolean mipmapTexture;      // True if texture has mipmaps
+//  EGLint mipmapLevel;            // Mipmap level to render to
+//  EGLenum multisampleResolve;    // Multisample resolve behavior
+	EGLint pixelAspectRatio;       // Display aspect ratio
+	EGLenum renderBuffer;          // Render buffer
+	EGLenum swapBehavior;          // Buffer swap behavior
+	EGLenum textureFormat;         // Format of texture: RGB, RGBA, or no texture
+	EGLenum textureTarget;         // Type of texture: 2D or no texture
+//  EGLenum vgAlphaFormat;         // Alpha format for OpenVG
+//  EGLenum vgColorSpace;          // Color space for OpenVG
+	EGLint swapInterval;
+};
+
+class WindowSurface : public Surface
+{
+public:
+	WindowSurface(Display *display, const egl::Config *config, EGLNativeWindowType window);
+	~WindowSurface() override;
+
+	bool initialize() override;
+
+	bool isWindowSurface() const override { return true; }
+	void swap() override;
+
+	EGLNativeWindowType getWindowHandle() const override;
+
+private:
+	void deleteResources() override;
+	bool checkForResize();
+	bool reset(int backBufferWidth, int backBufferHeight);
+
+	const EGLNativeWindowType window;
+	sw::FrameBuffer *frameBuffer;
+};
+
+class PBufferSurface : public Surface
+{
+public:
+	PBufferSurface(Display *display, const egl::Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget, EGLBoolean largestPBuffer);
+	~PBufferSurface() override;
+
+	bool isPBufferSurface() const override { return true; }
+	void swap() override;
+
+	EGLNativeWindowType getWindowHandle() const override;
+
+private:
+	void deleteResources() override;
+};
+}
+
+#endif   // INCLUDE_SURFACE_H_
diff --git a/src/OpenGL/libEGL/Sync.hpp b/src/OpenGL/libEGL/Sync.hpp
index c1756ec..847cb70 100644
--- a/src/OpenGL/libEGL/Sync.hpp
+++ b/src/OpenGL/libEGL/Sync.hpp
@@ -1,50 +1,53 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Sync.hpp: Defines sync objects for the EGL_KHR_fence_sync extension.

-

-#ifndef LIBEGL_SYNC_H_

-#define LIBEGL_SYNC_H_

-

-#include "Context.hpp"

-

-#include <EGL/eglext.h>

-

-namespace egl

-{

-

-class FenceSync

-{

-public:

-	explicit FenceSync(Context *context) : context(context)

-	{

-		status = EGL_UNSIGNALED_KHR;

-		context->addRef();

-	}

-

-	~FenceSync()

-	{

-		context->release();

-		context = nullptr;

-	}

-

-	void wait() { context->finish(); signal(); }

-	void signal() { status = EGL_SIGNALED_KHR; }

-	bool isSignaled() const { return status == EGL_SIGNALED_KHR; }

-

-private:

-	EGLint status;

-	Context *context;

-};

-

-}

-

-#endif   // LIBEGL_SYNC_H_

+// 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.
+
+// Sync.hpp: Defines sync objects for the EGL_KHR_fence_sync extension.
+
+#ifndef LIBEGL_SYNC_H_
+#define LIBEGL_SYNC_H_
+
+#include "Context.hpp"
+
+#include <EGL/eglext.h>
+
+namespace egl
+{
+
+class FenceSync
+{
+public:
+	explicit FenceSync(Context *context) : context(context)
+	{
+		status = EGL_UNSIGNALED_KHR;
+		context->addRef();
+	}
+
+	~FenceSync()
+	{
+		context->release();
+		context = nullptr;
+	}
+
+	void wait() { context->finish(); signal(); }
+	void signal() { status = EGL_SIGNALED_KHR; }
+	bool isSignaled() const { return status == EGL_SIGNALED_KHR; }
+
+private:
+	EGLint status;
+	Context *context;
+};
+
+}
+
+#endif   // LIBEGL_SYNC_H_
diff --git a/src/OpenGL/libEGL/Texture.hpp b/src/OpenGL/libEGL/Texture.hpp
index 3805d97..266f0a6 100644
--- a/src/OpenGL/libEGL/Texture.hpp
+++ b/src/OpenGL/libEGL/Texture.hpp
@@ -1,39 +1,39 @@
-#ifndef egl_Texture_hpp

-#define egl_Texture_hpp

-

-#include "common/Object.hpp"

-

-namespace sw

-{

-	class Resource;

-}

-

-namespace egl

-{

-class Texture : public gl::NamedObject

-{

-public:

-	Texture(GLuint name) : NamedObject(name) {}

-

-	virtual void releaseTexImage() = 0;

-	virtual sw::Resource *getResource() const = 0;

-

-	virtual void sweep() = 0;   // Garbage collect if no external references

-

-	void release() override

-	{

-		int refs = dereference();

-

-		if(refs > 0)

-		{

-			sweep();

-		}

-		else

-		{

-			delete this;

-		}

-	}

-};

-}

-

-#endif   // egl_Texture_hpp

+#ifndef egl_Texture_hpp
+#define egl_Texture_hpp
+
+#include "common/Object.hpp"
+
+namespace sw
+{
+	class Resource;
+}
+
+namespace egl
+{
+class Texture : public gl::NamedObject
+{
+public:
+	Texture(GLuint name) : NamedObject(name) {}
+
+	virtual void releaseTexImage() = 0;
+	virtual sw::Resource *getResource() const = 0;
+
+	virtual void sweep() = 0;   // Garbage collect if no external references
+
+	void release() override
+	{
+		int refs = dereference();
+
+		if(refs > 0)
+		{
+			sweep();
+		}
+		else
+		{
+			delete this;
+		}
+	}
+};
+}
+
+#endif   // egl_Texture_hpp
diff --git a/src/OpenGL/libEGL/exports.map b/src/OpenGL/libEGL/exports.map
index e41ac1e..487457e 100644
--- a/src/OpenGL/libEGL/exports.map
+++ b/src/OpenGL/libEGL/exports.map
@@ -1,54 +1,54 @@
-{

-global:

-	eglBindAPI;

-	eglBindTexImage;

-	eglChooseConfig;

-	eglCopyBuffers;

-	eglCreateContext;

-	eglCreatePbufferFromClientBuffer;

-	eglCreatePbufferSurface;

-	eglCreatePixmapSurface;

-	eglCreateWindowSurface;

-	eglDestroyContext;

-	eglDestroySurface;

-	eglGetConfigAttrib;

-	eglGetConfigs;

-	eglGetCurrentContext;

-	eglGetCurrentDisplay;

-	eglGetCurrentSurface;

-	eglGetDisplay;

-	eglGetError;

-	eglGetProcAddress;

-	eglInitialize;

-	eglMakeCurrent;

-	eglQueryAPI;

-	eglQueryContext;

-	eglQueryString;

-	eglQuerySurface;

-	eglReleaseTexImage;

-	eglReleaseThread;

-	eglSurfaceAttrib;

-	eglSwapBuffers;

-	eglSwapInterval;

-	eglTerminate;

-	eglWaitClient;

-	eglWaitGL;

-	eglWaitNative;

-

-	# Extensions

-	eglCreateImageKHR;

-	eglDestroyImageKHR;

-	eglGetPlatformDisplayEXT;

-	eglCreatePlatformWindowSurfaceEXT;

-	eglCreatePlatformPixmapSurfaceEXT;

-	eglCreateSyncKHR;

-	eglDestroySyncKHR;

-	eglClientWaitSyncKHR;

-	eglGetSyncAttribKHR;

-

-	libEGL_swiftshader;

-

-local:

-    *;

-};

-

+{
+global:
+	eglBindAPI;
+	eglBindTexImage;
+	eglChooseConfig;
+	eglCopyBuffers;
+	eglCreateContext;
+	eglCreatePbufferFromClientBuffer;
+	eglCreatePbufferSurface;
+	eglCreatePixmapSurface;
+	eglCreateWindowSurface;
+	eglDestroyContext;
+	eglDestroySurface;
+	eglGetConfigAttrib;
+	eglGetConfigs;
+	eglGetCurrentContext;
+	eglGetCurrentDisplay;
+	eglGetCurrentSurface;
+	eglGetDisplay;
+	eglGetError;
+	eglGetProcAddress;
+	eglInitialize;
+	eglMakeCurrent;
+	eglQueryAPI;
+	eglQueryContext;
+	eglQueryString;
+	eglQuerySurface;
+	eglReleaseTexImage;
+	eglReleaseThread;
+	eglSurfaceAttrib;
+	eglSwapBuffers;
+	eglSwapInterval;
+	eglTerminate;
+	eglWaitClient;
+	eglWaitGL;
+	eglWaitNative;
+
+	# Extensions
+	eglCreateImageKHR;
+	eglDestroyImageKHR;
+	eglGetPlatformDisplayEXT;
+	eglCreatePlatformWindowSurfaceEXT;
+	eglCreatePlatformPixmapSurfaceEXT;
+	eglCreateSyncKHR;
+	eglDestroySyncKHR;
+	eglClientWaitSyncKHR;
+	eglGetSyncAttribKHR;
+
+	libEGL_swiftshader;
+
+local:
+    *;
+};
+
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index b626562..7a801d9 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -1,1187 +1,1190 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// libEGL.cpp: Implements the exported EGL functions.

-

-#include "main.h"

-#include "Display.h"

-#include "Surface.h"

-#include "Texture.hpp"

-#include "Context.hpp"

-#include "common/Image.hpp"

-#include "common/debug.h"

-#include "Common/Version.h"

-

-#if defined(__ANDROID__)

-#include <system/window.h>

-#elif defined(__linux__)

-#include "Main/libX11.hpp"

-#endif

-

-#include <string.h>

-

-using namespace egl;

-

-static bool validateDisplay(egl::Display *display)

-{

-	if(display == EGL_NO_DISPLAY)

-	{

-		return error(EGL_BAD_DISPLAY, false);

-	}

-

-	if(!display->isInitialized())

-	{

-		return error(EGL_NOT_INITIALIZED, false);

-	}

-

-	return true;

-}

-

-static bool validateConfig(egl::Display *display, EGLConfig config)

-{

-	if(!validateDisplay(display))

-	{

-		return false;

-	}

-

-	if(!display->isValidConfig(config))

-	{

-		return error(EGL_BAD_CONFIG, false);

-	}

-

-	return true;

-}

-

-static bool validateContext(egl::Display *display, egl::Context *context)

-{

-	if(!validateDisplay(display))

-	{

-		return false;

-	}

-

-	if(!display->isValidContext(context))

-	{

-		return error(EGL_BAD_CONTEXT, false);

-	}

-

-	return true;

-}

-

-static bool validateSurface(egl::Display *display, egl::Surface *surface)

-{

-	if(!validateDisplay(display))

-	{

-		return false;

-	}

-

-	if(!display->isValidSurface(surface))

-	{

-		return error(EGL_BAD_SURFACE, false);

-	}

-

-	return true;

-}

-

-namespace egl

-{

-EGLint GetError(void)

-{

-	TRACE("()");

-

-	EGLint error = egl::getCurrentError();

-

-	if(error != EGL_SUCCESS)

-	{

-		egl::setCurrentError(EGL_SUCCESS);

-	}

-

-	return error;

-}

-

-EGLDisplay GetDisplay(EGLNativeDisplayType display_id)

-{

-	TRACE("(EGLNativeDisplayType display_id = %p)", display_id);

-

-	if(display_id != EGL_DEFAULT_DISPLAY)

-	{

-		// FIXME: Check if display_id is the default display

-	}

-

-	#if defined(__linux__) && !defined(__ANDROID__)

-		if(!libX11)

-		{

-			return success(HEADLESS_DISPLAY);

-		}

-	#endif

-

-	return success(PRIMARY_DISPLAY);   // We only support the default display

-}

-

-EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLint *major = %p, EGLint *minor = %p)",

-		  dpy, major, minor);

-

-	if(dpy == EGL_NO_DISPLAY)

-	{

-		return error(EGL_BAD_DISPLAY, EGL_FALSE);

-	}

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!display->initialize())

-	{

-		return error(EGL_NOT_INITIALIZED, EGL_FALSE);

-	}

-

-	if(major) *major = 1;

-	if(minor) *minor = 4;

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean Terminate(EGLDisplay dpy)

-{

-	TRACE("(EGLDisplay dpy = %p)", dpy);

-

-	if(dpy == EGL_NO_DISPLAY)

-	{

-		return error(EGL_BAD_DISPLAY, EGL_FALSE);

-	}

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	display->terminate();

-

-	return success(EGL_TRUE);

-}

-

-const char *QueryString(EGLDisplay dpy, EGLint name)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);

-

-	#if defined(__linux__) && !defined(__ANDROID__)

-		if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)

-		{

-			return success("EGL_KHR_platform_gbm "

-			               "EGL_KHR_platform_x11 "

-			               "EGL_EXT_client_extensions "

-			               "EGL_EXT_platform_base");

-		}

-	#endif

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateDisplay(display))

-	{

-		return NULL;

-	}

-

-	switch(name)

-	{

-	case EGL_CLIENT_APIS:

-		return success("OpenGL_ES");

-	case EGL_EXTENSIONS:

-		return success("EGL_KHR_gl_texture_2D_image "

-		               "EGL_KHR_gl_texture_cubemap_image "

-		               "EGL_KHR_gl_renderbuffer_image "

-		               "EGL_KHR_fence_sync "

-		               "EGL_KHR_image_base "

-		               "EGL_ANDROID_framebuffer_target "

-		               "EGL_ANDROID_recordable");

-	case EGL_VENDOR:

-		return success("TransGaming Inc.");

-	case EGL_VERSION:

-		return success("1.4 SwiftShader " VERSION_STRING);

-	}

-

-	return error(EGL_BAD_PARAMETER, (const char*)NULL);

-}

-

-EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "

-		  "EGLint config_size = %d, EGLint *num_config = %p)",

-		  dpy, configs, config_size, num_config);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateDisplay(display))

-	{

-		return EGL_FALSE;

-	}

-

-	if(!num_config)

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	const EGLint attribList[] = {EGL_NONE};

-

-	if(!display->getConfigs(configs, attribList, config_size, num_config))

-	{

-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "

-		  "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",

-		  dpy, attrib_list, configs, config_size, num_config);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateDisplay(display))

-	{

-		return EGL_FALSE;

-	}

-

-	if(!num_config)

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	const EGLint attribList[] = {EGL_NONE};

-

-	if(!attrib_list)

-	{

-		attrib_list = attribList;

-	}

-

-	if(!display->getConfigs(configs, attrib_list, config_size, num_config))

-	{

-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",

-		  dpy, config, attribute, value);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateConfig(display, config))

-	{

-		return EGL_FALSE;

-	}

-

-	if(!display->getConfigAttrib(config, attribute, value))

-	{

-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "

-		  "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateConfig(display, config))

-	{

-		return EGL_NO_SURFACE;

-	}

-

-	if(!display->isValidWindow(window))

-	{

-		return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);

-	}

-

-	return display->createWindowSurface(window, config, attrib_list);

-}

-

-EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",

-		  dpy, config, attrib_list);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateConfig(display, config))

-	{

-		return EGL_NO_SURFACE;

-	}

-

-	return display->createPBufferSurface(config, attrib_list);

-}

-

-EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "

-		  "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateConfig(display, config))

-	{

-		return EGL_NO_SURFACE;

-	}

-

-	UNIMPLEMENTED();   // FIXME

-

-	return success(EGL_NO_SURFACE);

-}

-

-EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

-

-	if(!validateSurface(display, eglSurface))

-	{

-		return EGL_FALSE;

-	}

-

-	if(surface == EGL_NO_SURFACE)

-	{

-		return error(EGL_BAD_SURFACE, EGL_FALSE);

-	}

-

-	display->destroySurface((egl::Surface*)surface);

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",

-		  dpy, surface, attribute, value);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Surface *eglSurface = (egl::Surface*)surface;

-

-	if(!validateSurface(display, eglSurface))

-	{

-		return EGL_FALSE;

-	}

-

-	if(surface == EGL_NO_SURFACE)

-	{

-		return error(EGL_BAD_SURFACE, EGL_FALSE);

-	}

-

-	switch(attribute)

-	{

-	case EGL_VG_ALPHA_FORMAT:

-		UNIMPLEMENTED();   // FIXME

-		break;

-	case EGL_VG_COLORSPACE:

-		UNIMPLEMENTED();   // FIXME

-		break;

-	case EGL_CONFIG_ID:

-		*value = eglSurface->getConfigID();

-		break;

-	case EGL_HEIGHT:

-		*value = eglSurface->getHeight();

-		break;

-	case EGL_HORIZONTAL_RESOLUTION:

-		UNIMPLEMENTED();   // FIXME

-		break;

-	case EGL_LARGEST_PBUFFER:

-		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.

-		{

-			*value = eglSurface->getLargestPBuffer();

-		}

-		break;

-	case EGL_MIPMAP_TEXTURE:

-		UNIMPLEMENTED();   // FIXME

-		break;

-	case EGL_MIPMAP_LEVEL:

-		UNIMPLEMENTED();   // FIXME

-		break;

-	case EGL_MULTISAMPLE_RESOLVE:

-		UNIMPLEMENTED();   // FIXME

-		break;

-	case EGL_PIXEL_ASPECT_RATIO:

-		*value = eglSurface->getPixelAspectRatio();

-		break;

-	case EGL_RENDER_BUFFER:

-		*value = eglSurface->getRenderBuffer();

-		break;

-	case EGL_SWAP_BEHAVIOR:

-		*value = eglSurface->getSwapBehavior();

-		break;

-	case EGL_TEXTURE_FORMAT:

-		*value = eglSurface->getTextureFormat();

-		break;

-	case EGL_TEXTURE_TARGET:

-		*value = eglSurface->getTextureTarget();

-		break;

-	case EGL_VERTICAL_RESOLUTION:

-		UNIMPLEMENTED();   // FIXME

-		break;

-	case EGL_WIDTH:

-		*value = eglSurface->getWidth();

-		break;

-	default:

-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean BindAPI(EGLenum api)

-{

-	TRACE("(EGLenum api = 0x%X)", api);

-

-	switch(api)

-	{

-	case EGL_OPENGL_API:

-	case EGL_OPENVG_API:

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation

-	case EGL_OPENGL_ES_API:

-		break;

-	default:

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	egl::setCurrentAPI(api);

-

-	return success(EGL_TRUE);

-}

-

-EGLenum QueryAPI(void)

-{

-	TRACE("()");

-

-	EGLenum API = egl::getCurrentAPI();

-

-	return success(API);

-}

-

-EGLBoolean WaitClient(void)

-{

-	TRACE("()");

-

-	UNIMPLEMENTED();   // FIXME

-

-	return success(EGL_FALSE);

-}

-

-EGLBoolean ReleaseThread(void)

-{

-	TRACE("()");

-

-	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);

-

-	return success(EGL_TRUE);

-}

-

-EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "

-		  "EGLConfig config = %p, const EGLint *attrib_list = %p)",

-		  dpy, buftype, buffer, config, attrib_list);

-

-	UNIMPLEMENTED();

-

-	return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);

-}

-

-EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",

-		  dpy, surface, attribute, value);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

-

-	if(!validateSurface(display, eglSurface))

-	{

-		return EGL_FALSE;

-	}

-

-	switch(attribute)

-	{

-	case EGL_SWAP_BEHAVIOR:

-		if(value == EGL_BUFFER_PRESERVED)

-		{

-			if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))

-			{

-				return error(EGL_BAD_MATCH, EGL_FALSE);

-			}

-		}

-		else if(value != EGL_BUFFER_DESTROYED)

-		{

-			return error(EGL_BAD_PARAMETER, EGL_FALSE);

-		}

-		eglSurface->setSwapBehavior(value);

-		break;

-	default:

-		UNIMPLEMENTED();   // FIXME

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

-

-	if(!validateSurface(display, eglSurface))

-	{

-		return EGL_FALSE;

-	}

-

-	if(buffer != EGL_BACK_BUFFER)

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())

-	{

-		return error(EGL_BAD_SURFACE, EGL_FALSE);

-	}

-

-	if(eglSurface->getBoundTexture())

-	{

-		return error(EGL_BAD_ACCESS, EGL_FALSE);

-	}

-

-	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)

-	{

-		return error(EGL_BAD_MATCH, EGL_FALSE);

-	}

-

-	egl::Context *context = egl::getCurrentContext();

-

-	if(context)

-	{

-		context->bindTexImage(eglSurface);

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

-

-	if(!validateSurface(display, eglSurface))

-	{

-		return EGL_FALSE;

-	}

-

-	if(buffer != EGL_BACK_BUFFER)

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())

-	{

-		return error(EGL_BAD_SURFACE, EGL_FALSE);

-	}

-

-	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)

-	{

-		return error(EGL_BAD_MATCH, EGL_FALSE);

-	}

-

-	egl::Texture *texture = eglSurface->getBoundTexture();

-

-	if(texture)

-	{

-		texture->releaseTexImage();

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Context *context = egl::getCurrentContext();

-

-	if(!validateContext(display, context))

-	{

-		return EGL_FALSE;

-	}

-

-	egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());

-

-	if(!draw_surface)

-	{

-		return error(EGL_BAD_SURFACE, EGL_FALSE);

-	}

-

-	draw_surface->setSwapInterval(interval);

-

-	return success(EGL_TRUE);

-}

-

-EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "

-		  "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);

-

-	EGLint clientVersion = 1;

-	if(attrib_list)

-	{

-		for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)

-		{

-			if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)

-			{

-				clientVersion = attribute[1];

-			}

-			else

-			{

-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);

-			}

-		}

-	}

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Context *shareContext = static_cast<egl::Context*>(share_context);

-

-	if(!validateConfig(display, config))

-	{

-		return EGL_NO_CONTEXT;

-	}

-

-	if(shareContext && shareContext->getClientVersion() != clientVersion)

-	{

-		return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);

-	}

-

-	return display->createContext(config, shareContext, clientVersion);

-}

-

-EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Context *context = static_cast<egl::Context*>(ctx);

-

-	if(!validateContext(display, context))

-	{

-		return EGL_FALSE;

-	}

-

-	if(ctx == EGL_NO_CONTEXT)

-	{

-		return error(EGL_BAD_CONTEXT, EGL_FALSE);

-	}

-

-	display->destroyContext(context);

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",

-		  dpy, draw, read, ctx);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Context *context = static_cast<egl::Context*>(ctx);

-	egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);

-	egl::Surface *readSurface = static_cast<egl::Surface*>(read);

-

-	if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)

-	{

-		if(!validateDisplay(display))

-		{

-			return EGL_FALSE;

-		}

-	}

-

-	if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))

-	{

-		return error(EGL_BAD_MATCH, EGL_FALSE);

-	}

-

-	if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))

-	{

-		return EGL_FALSE;

-	}

-

-	if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||

-	   (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))

-	{

-		return EGL_FALSE;

-	}

-

-	if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))

-	{

-		return error(EGL_BAD_MATCH, EGL_FALSE);

-	}

-

-	if(draw != read)

-	{

-		UNIMPLEMENTED();   // FIXME

-	}

-

-	egl::setCurrentDisplay(dpy);

-	egl::setCurrentDrawSurface(drawSurface);

-	egl::setCurrentReadSurface(readSurface);

-	egl::setCurrentContext(context);

-

-	if(context)

-	{

-		context->makeCurrent(drawSurface);

-	}

-

-	return success(EGL_TRUE);

-}

-

-EGLContext GetCurrentContext(void)

-{

-	TRACE("()");

-

-	EGLContext context = egl::getCurrentContext();

-

-	return success(context);

-}

-

-EGLSurface GetCurrentSurface(EGLint readdraw)

-{

-	TRACE("(EGLint readdraw = %d)", readdraw);

-

-	if(readdraw == EGL_READ)

-	{

-		EGLSurface read = egl::getCurrentReadSurface();

-		return success(read);

-	}

-	else if(readdraw == EGL_DRAW)

-	{

-		EGLSurface draw = egl::getCurrentDrawSurface();

-		return success(draw);

-	}

-	else

-	{

-		return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);

-	}

-}

-

-EGLDisplay GetCurrentDisplay(void)

-{

-	TRACE("()");

-

-	return success(egl::getCurrentDisplay());

-}

-

-EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",

-		  dpy, ctx, attribute, value);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Context *context = static_cast<egl::Context*>(ctx);

-

-	if(!validateContext(display, context))

-	{

-		return EGL_FALSE;

-	}

-

-	UNIMPLEMENTED();   // FIXME

-

-	return success(0);

-}

-

-EGLBoolean WaitGL(void)

-{

-	TRACE("()");

-

-	UNIMPLEMENTED();   // FIXME

-

-	return success(EGL_FALSE);

-}

-

-EGLBoolean WaitNative(EGLint engine)

-{

-	TRACE("(EGLint engine = %d)", engine);

-

-	UNIMPLEMENTED();   // FIXME

-

-	return success(EGL_FALSE);

-}

-

-EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Surface *eglSurface = (egl::Surface*)surface;

-

-	if(!validateSurface(display, eglSurface))

-	{

-		return EGL_FALSE;

-	}

-

-	if(surface == EGL_NO_SURFACE)

-	{

-		return error(EGL_BAD_SURFACE, EGL_FALSE);

-	}

-

-	eglSurface->swap();

-

-	return success(EGL_TRUE);

-}

-

-EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

-

-	if(!validateSurface(display, eglSurface))

-	{

-		return EGL_FALSE;

-	}

-

-	UNIMPLEMENTED();   // FIXME

-

-	return success(EGL_FALSE);

-}

-

-EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLint attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);

-

-	egl::Display *display = egl::Display::get(dpy);

-	egl::Context *context = static_cast<egl::Context*>(ctx);

-

-	if(!validateDisplay(display))

-	{

-		return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);

-	}

-

-	if(context != EGL_NO_CONTEXT && !display->isValidContext(context))

-	{

-		return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);

-	}

-

-	EGLenum imagePreserved = EGL_FALSE;

-	GLuint textureLevel = 0;

-	if(attrib_list)

-	{

-		for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)

-		{

-			if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)

-			{

-				imagePreserved = attribute[1];

-			}

-			else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)

-			{

-				textureLevel = attribute[1];

-			}

-			else

-			{

-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);

-			}

-		}

-	}

-

-	#if defined(__ANDROID__)

-		if(target == EGL_NATIVE_BUFFER_ANDROID)

-		{

-			ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(buffer);

-

-			if(!nativeBuffer || GLPixelFormatFromAndroid(nativeBuffer->format) == GL_NONE)

-			{

-				ALOGW("%s badness unsupported HAL format=%x", __FUNCTION__, nativeBuffer ? nativeBuffer->format : 0);

-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);

-			}

-

-			return success(new AndroidNativeImage(nativeBuffer));

-		}

-	#endif

-

-	GLuint name = reinterpret_cast<intptr_t>(buffer);

-

-	if(name == 0)

-	{

-		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);

-	}

-

-	EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);

-

-	if(validationResult != EGL_SUCCESS)

-	{

-		return error(validationResult, EGL_NO_IMAGE_KHR);

-	}

-

-	egl::Image *image = context->createSharedImage(target, name, textureLevel);

-

-	if(!image)

-	{

-		return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);

-	}

-

-	if(image->getDepth() > 1)

-	{

-		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);

-	}

-

-	return success((EGLImageKHR)image);

-}

-

-EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateDisplay(display))

-	{

-		return error(EGL_BAD_DISPLAY, EGL_FALSE);

-	}

-

-	if(!image)

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	egl::Image *glImage = static_cast<egl::Image*>(image);

-	glImage->destroyShared();

-

-	return success(EGL_TRUE);

-}

-

-EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)

-{

-	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);

-

-	switch(platform)

-	{

-	#if defined(__linux__) && !defined(__ANDROID__)

-	case EGL_PLATFORM_X11_EXT: break;

-	case EGL_PLATFORM_GBM_KHR: break;

-	#endif

-	default:

-		return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);

-	}

-

-	#if defined(__linux__) && !defined(__ANDROID__)

-		if(platform == EGL_PLATFORM_X11_EXT)

-		{

-			if(!libX11)

-			{

-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);

-			}

-

-			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)

-			{

-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented

-			}

-		}

-		else if(platform == EGL_PLATFORM_GBM_KHR)

-		{

-			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)

-			{

-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented

-			}

-

-			return success(HEADLESS_DISPLAY);

-		}

-	#endif

-

-	return success(PRIMARY_DISPLAY);   // We only support the default display

-}

-

-EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)

-{

-	return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);

-}

-

-EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)

-{

-	return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);

-}

-

-EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);

-

-	egl::Display *display = egl::Display::get(dpy);

-

-	if(!validateDisplay(display))

-	{

-		return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);

-	}

-

-	if(type != EGL_SYNC_FENCE_KHR)

-	{

-		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);

-	}

-

-	if(attrib_list && attrib_list[0] != EGL_NONE)

-	{

-		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);

-	}

-

-	egl::Context *context = egl::getCurrentContext();

-

-	if(!validateContext(display, context))

-	{

-		return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);

-	}

-

-	EGLSyncKHR sync = display->createSync(context);

-

-	return success(sync);

-}

-

-EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);

-

-	egl::Display *display = egl::Display::get(dpy);

-	FenceSync *eglSync = static_cast<FenceSync*>(sync);

-

-	if(!validateDisplay(display))

-	{

-		return error(EGL_BAD_DISPLAY, EGL_FALSE);

-	}

-

-	if(!display->isValidSync(eglSync))

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	display->destroySync(eglSync);

-

-	return success(EGL_TRUE);

-}

-

-EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);

-

-	egl::Display *display = egl::Display::get(dpy);

-	FenceSync *eglSync = static_cast<FenceSync*>(sync);

-

-	if(!validateDisplay(display))

-	{

-		return error(EGL_BAD_DISPLAY, EGL_FALSE);

-	}

-

-	if(!display->isValidSync(eglSync))

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	(void)flags;

-	(void)timeout;

-

-	if(!eglSync->isSignaled())

-	{

-		eglSync->wait();

-	}

-

-	return success(EGL_CONDITION_SATISFIED_KHR);

-}

-

-EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)

-{

-	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);

-

-	egl::Display *display = egl::Display::get(dpy);

-	FenceSync *eglSync = static_cast<FenceSync*>(sync);

-

-	if(!validateDisplay(display))

-	{

-		return error(EGL_BAD_DISPLAY, EGL_FALSE);

-	}

-

-	if(!display->isValidSync(eglSync))

-	{

-		return error(EGL_BAD_PARAMETER, EGL_FALSE);

-	}

-

-	switch(attribute)

-	{

-	case EGL_SYNC_TYPE_KHR:

-		*value = EGL_SYNC_FENCE_KHR;

-		return success(EGL_TRUE);

-	case EGL_SYNC_STATUS_KHR:

-		eglSync->wait();   // TODO: Don't block. Just poll based on sw::Query.

-		*value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;

-		return success(EGL_TRUE);

-	case EGL_SYNC_CONDITION_KHR:

-		*value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;

-		return success(EGL_TRUE);

-	default:

-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);

-	}

-}

-

-__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)

-{

-	TRACE("(const char *procname = \"%s\")", procname);

-

-	struct Extension

-	{

-		const char *name;

-		__eglMustCastToProperFunctionPointerType address;

-	};

-

-	static const Extension eglExtensions[] =

-	{

-		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}

-

-		EXTENSION(eglCreateImageKHR),

-		EXTENSION(eglDestroyImageKHR),

-		EXTENSION(eglGetPlatformDisplayEXT),

-		EXTENSION(eglCreatePlatformWindowSurfaceEXT),

-		EXTENSION(eglCreatePlatformPixmapSurfaceEXT),

-		EXTENSION(eglCreateSyncKHR),

-		EXTENSION(eglDestroySyncKHR),

-		EXTENSION(eglClientWaitSyncKHR),

-		EXTENSION(eglGetSyncAttribKHR),

-

-		#undef EXTENSION

-	};

-

-	for(unsigned int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)

-	{

-		if(strcmp(procname, eglExtensions[ext].name) == 0)

-		{

-			return success((__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address);

-		}

-	}

-

-	if(libGLESv2)

-	{

-		__eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);

-		if(proc) return success(proc);

-	}

-

-	if(libGLES_CM)

-	{

-		__eglMustCastToProperFunctionPointerType proc =  libGLES_CM->es1GetProcAddress(procname);

-		if(proc) return success(proc);

-	}

-

-	return success((__eglMustCastToProperFunctionPointerType)NULL);

-}

-}

+// 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.
+
+// libEGL.cpp: Implements the exported EGL functions.
+
+#include "main.h"
+#include "Display.h"
+#include "Surface.h"
+#include "Texture.hpp"
+#include "Context.hpp"
+#include "common/Image.hpp"
+#include "common/debug.h"
+#include "Common/Version.h"
+
+#if defined(__ANDROID__)
+#include <system/window.h>
+#elif defined(__linux__)
+#include "Main/libX11.hpp"
+#endif
+
+#include <string.h>
+
+using namespace egl;
+
+static bool validateDisplay(egl::Display *display)
+{
+	if(display == EGL_NO_DISPLAY)
+	{
+		return error(EGL_BAD_DISPLAY, false);
+	}
+
+	if(!display->isInitialized())
+	{
+		return error(EGL_NOT_INITIALIZED, false);
+	}
+
+	return true;
+}
+
+static bool validateConfig(egl::Display *display, EGLConfig config)
+{
+	if(!validateDisplay(display))
+	{
+		return false;
+	}
+
+	if(!display->isValidConfig(config))
+	{
+		return error(EGL_BAD_CONFIG, false);
+	}
+
+	return true;
+}
+
+static bool validateContext(egl::Display *display, egl::Context *context)
+{
+	if(!validateDisplay(display))
+	{
+		return false;
+	}
+
+	if(!display->isValidContext(context))
+	{
+		return error(EGL_BAD_CONTEXT, false);
+	}
+
+	return true;
+}
+
+static bool validateSurface(egl::Display *display, egl::Surface *surface)
+{
+	if(!validateDisplay(display))
+	{
+		return false;
+	}
+
+	if(!display->isValidSurface(surface))
+	{
+		return error(EGL_BAD_SURFACE, false);
+	}
+
+	return true;
+}
+
+namespace egl
+{
+EGLint GetError(void)
+{
+	TRACE("()");
+
+	EGLint error = egl::getCurrentError();
+
+	if(error != EGL_SUCCESS)
+	{
+		egl::setCurrentError(EGL_SUCCESS);
+	}
+
+	return error;
+}
+
+EGLDisplay GetDisplay(EGLNativeDisplayType display_id)
+{
+	TRACE("(EGLNativeDisplayType display_id = %p)", display_id);
+
+	if(display_id != EGL_DEFAULT_DISPLAY)
+	{
+		// FIXME: Check if display_id is the default display
+	}
+
+	#if defined(__linux__) && !defined(__ANDROID__)
+		if(!libX11)
+		{
+			return success(HEADLESS_DISPLAY);
+		}
+	#endif
+
+	return success(PRIMARY_DISPLAY);   // We only support the default display
+}
+
+EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLint *major = %p, EGLint *minor = %p)",
+		  dpy, major, minor);
+
+	if(dpy == EGL_NO_DISPLAY)
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!display->initialize())
+	{
+		return error(EGL_NOT_INITIALIZED, EGL_FALSE);
+	}
+
+	if(major) *major = 1;
+	if(minor) *minor = 4;
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean Terminate(EGLDisplay dpy)
+{
+	TRACE("(EGLDisplay dpy = %p)", dpy);
+
+	if(dpy == EGL_NO_DISPLAY)
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	display->terminate();
+
+	return success(EGL_TRUE);
+}
+
+const char *QueryString(EGLDisplay dpy, EGLint name)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);
+
+	#if defined(__linux__) && !defined(__ANDROID__)
+		if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
+		{
+			return success("EGL_KHR_platform_gbm "
+			               "EGL_KHR_platform_x11 "
+			               "EGL_EXT_client_extensions "
+			               "EGL_EXT_platform_base");
+		}
+	#endif
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return nullptr;
+	}
+
+	switch(name)
+	{
+	case EGL_CLIENT_APIS:
+		return success("OpenGL_ES");
+	case EGL_EXTENSIONS:
+		return success("EGL_KHR_gl_texture_2D_image "
+		               "EGL_KHR_gl_texture_cubemap_image "
+		               "EGL_KHR_gl_renderbuffer_image "
+		               "EGL_KHR_fence_sync "
+		               "EGL_KHR_image_base "
+		               "EGL_ANDROID_framebuffer_target "
+		               "EGL_ANDROID_recordable");
+	case EGL_VENDOR:
+		return success("Google Inc.");
+	case EGL_VERSION:
+		return success("1.4 SwiftShader " VERSION_STRING);
+	}
+
+	return error(EGL_BAD_PARAMETER, (const char*)nullptr);
+}
+
+EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "
+	      "EGLint config_size = %d, EGLint *num_config = %p)",
+	      dpy, configs, config_size, num_config);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return EGL_FALSE;
+	}
+
+	if(!num_config)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	const EGLint attribList[] = {EGL_NONE};
+
+	if(!display->getConfigs(configs, attribList, config_size, num_config))
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "
+	      "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",
+	      dpy, attrib_list, configs, config_size, num_config);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return EGL_FALSE;
+	}
+
+	if(!num_config)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	const EGLint attribList[] = {EGL_NONE};
+
+	if(!attrib_list)
+	{
+		attrib_list = attribList;
+	}
+
+	if(!display->getConfigs(configs, attrib_list, config_size, num_config))
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",
+	      dpy, config, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_FALSE;
+	}
+
+	if(!display->getConfigAttrib(config, attribute, value))
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_SURFACE;
+	}
+
+	if(!display->isValidWindow(window))
+	{
+		return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+	}
+
+	return display->createWindowSurface(window, config, attrib_list);
+}
+
+EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",
+	      dpy, config, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_SURFACE;
+	}
+
+	return display->createPBufferSurface(config, attrib_list);
+}
+
+EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_SURFACE;
+	}
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_NO_SURFACE);
+}
+
+EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(surface == EGL_NO_SURFACE)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	display->destroySurface((egl::Surface*)surface);
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",
+	      dpy, surface, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = (egl::Surface*)surface;
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(surface == EGL_NO_SURFACE)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	switch(attribute)
+	{
+	case EGL_VG_ALPHA_FORMAT:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_VG_COLORSPACE:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_CONFIG_ID:
+		*value = eglSurface->getConfigID();
+		break;
+	case EGL_HEIGHT:
+		*value = eglSurface->getHeight();
+		break;
+	case EGL_HORIZONTAL_RESOLUTION:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_LARGEST_PBUFFER:
+		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
+		{
+			*value = eglSurface->getLargestPBuffer();
+		}
+		break;
+	case EGL_MIPMAP_TEXTURE:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_MIPMAP_LEVEL:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_MULTISAMPLE_RESOLVE:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_PIXEL_ASPECT_RATIO:
+		*value = eglSurface->getPixelAspectRatio();
+		break;
+	case EGL_RENDER_BUFFER:
+		*value = eglSurface->getRenderBuffer();
+		break;
+	case EGL_SWAP_BEHAVIOR:
+		*value = eglSurface->getSwapBehavior();
+		break;
+	case EGL_TEXTURE_FORMAT:
+		*value = eglSurface->getTextureFormat();
+		break;
+	case EGL_TEXTURE_TARGET:
+		*value = eglSurface->getTextureTarget();
+		break;
+	case EGL_VERTICAL_RESOLUTION:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_WIDTH:
+		*value = eglSurface->getWidth();
+		break;
+	default:
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean BindAPI(EGLenum api)
+{
+	TRACE("(EGLenum api = 0x%X)", api);
+
+	switch(api)
+	{
+	case EGL_OPENGL_API:
+	case EGL_OPENVG_API:
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
+	case EGL_OPENGL_ES_API:
+		break;
+	default:
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	egl::setCurrentAPI(api);
+
+	return success(EGL_TRUE);
+}
+
+EGLenum QueryAPI(void)
+{
+	TRACE("()");
+
+	EGLenum API = egl::getCurrentAPI();
+
+	return success(API);
+}
+
+EGLBoolean WaitClient(void)
+{
+	TRACE("()");
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLBoolean ReleaseThread(void)
+{
+	TRACE("()");
+
+	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+
+	return success(EGL_TRUE);
+}
+
+EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "
+	      "EGLConfig config = %p, const EGLint *attrib_list = %p)",
+	      dpy, buftype, buffer, config, attrib_list);
+
+	UNIMPLEMENTED();
+
+	return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+}
+
+EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",
+	      dpy, surface, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	switch(attribute)
+	{
+	case EGL_SWAP_BEHAVIOR:
+		if(value == EGL_BUFFER_PRESERVED)
+		{
+			if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
+			{
+				return error(EGL_BAD_MATCH, EGL_FALSE);
+			}
+		}
+		else if(value != EGL_BUFFER_DESTROYED)
+		{
+			return error(EGL_BAD_PARAMETER, EGL_FALSE);
+		}
+		eglSurface->setSwapBehavior(value);
+		break;
+	default:
+		UNIMPLEMENTED();   // FIXME
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(buffer != EGL_BACK_BUFFER)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	if(eglSurface->getBoundTexture())
+	{
+		return error(EGL_BAD_ACCESS, EGL_FALSE);
+	}
+
+	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	egl::Context *context = egl::getCurrentContext();
+
+	if(context)
+	{
+		context->bindTexImage(eglSurface);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(buffer != EGL_BACK_BUFFER)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	egl::Texture *texture = eglSurface->getBoundTexture();
+
+	if(texture)
+	{
+		texture->releaseTexImage();
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = egl::getCurrentContext();
+
+	if(!validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
+
+	if(!draw_surface)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	draw_surface->setSwapInterval(interval);
+
+	return success(EGL_TRUE);
+}
+
+EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);
+
+	EGLint clientVersion = 1;
+	if(attrib_list)
+	{
+		for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+		{
+			if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
+			{
+				clientVersion = attribute[1];
+			}
+			else
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+			}
+		}
+	}
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *shareContext = static_cast<egl::Context*>(share_context);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_CONTEXT;
+	}
+
+	if(shareContext && shareContext->getClientVersion() != clientVersion)
+	{
+		return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+	}
+
+	return display->createContext(config, shareContext, clientVersion);
+}
+
+EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+
+	if(!validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	if(ctx == EGL_NO_CONTEXT)
+	{
+		return error(EGL_BAD_CONTEXT, EGL_FALSE);
+	}
+
+	display->destroyContext(context);
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",
+	      dpy, draw, read, ctx);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+	egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);
+	egl::Surface *readSurface = static_cast<egl::Surface*>(read);
+
+	if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)
+	{
+		if(!validateDisplay(display))
+		{
+			return EGL_FALSE;
+		}
+	}
+
+	if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||
+	   (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))
+	{
+		return EGL_FALSE;
+	}
+
+	if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	if(draw != read)
+	{
+		UNIMPLEMENTED();   // FIXME
+	}
+
+	egl::setCurrentDisplay(dpy);
+	egl::setCurrentDrawSurface(drawSurface);
+	egl::setCurrentReadSurface(readSurface);
+	egl::setCurrentContext(context);
+
+	if(context)
+	{
+		context->makeCurrent(drawSurface);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLContext GetCurrentContext(void)
+{
+	TRACE("()");
+
+	EGLContext context = egl::getCurrentContext();
+
+	return success(context);
+}
+
+EGLSurface GetCurrentSurface(EGLint readdraw)
+{
+	TRACE("(EGLint readdraw = %d)", readdraw);
+
+	if(readdraw == EGL_READ)
+	{
+		EGLSurface read = egl::getCurrentReadSurface();
+		return success(read);
+	}
+	else if(readdraw == EGL_DRAW)
+	{
+		EGLSurface draw = egl::getCurrentDrawSurface();
+		return success(draw);
+	}
+	else
+	{
+		return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+	}
+}
+
+EGLDisplay GetCurrentDisplay(void)
+{
+	TRACE("()");
+
+	return success(egl::getCurrentDisplay());
+}
+
+EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",
+	      dpy, ctx, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+
+	if(!validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(0);
+}
+
+EGLBoolean WaitGL(void)
+{
+	TRACE("()");
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLBoolean WaitNative(EGLint engine)
+{
+	TRACE("(EGLint engine = %d)", engine);
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = (egl::Surface*)surface;
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(surface == EGL_NO_SURFACE)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	eglSurface->swap();
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLint attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
+	}
+
+	if(context != EGL_NO_CONTEXT && !display->isValidContext(context))
+	{
+		return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
+	}
+
+	EGLenum imagePreserved = EGL_FALSE;
+	GLuint textureLevel = 0;
+	if(attrib_list)
+	{
+		for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+		{
+			if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
+			{
+				imagePreserved = attribute[1];
+			}
+			else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
+			{
+				textureLevel = attribute[1];
+			}
+			else
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
+			}
+		}
+	}
+
+	#if defined(__ANDROID__)
+		if(target == EGL_NATIVE_BUFFER_ANDROID)
+		{
+			ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+
+			if(!nativeBuffer || GLPixelFormatFromAndroid(nativeBuffer->format) == GL_NONE)
+			{
+				ALOGW("%s badness unsupported HAL format=%x", __FUNCTION__, nativeBuffer ? nativeBuffer->format : 0);
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
+			}
+
+			return success(new AndroidNativeImage(nativeBuffer));
+		}
+	#endif
+
+	GLuint name = reinterpret_cast<intptr_t>(buffer);
+
+	if(name == 0)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+	}
+
+	EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
+
+	if(validationResult != EGL_SUCCESS)
+	{
+		return error(validationResult, EGL_NO_IMAGE_KHR);
+	}
+
+	egl::Image *image = context->createSharedImage(target, name, textureLevel);
+
+	if(!image)
+	{
+		return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
+	}
+
+	if(image->getDepth() > 1)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+	}
+
+	return success((EGLImageKHR)image);
+}
+
+EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!image)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	egl::Image *glImage = static_cast<egl::Image*>(image);
+	glImage->destroyShared();
+
+	return success(EGL_TRUE);
+}
+
+EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+{
+	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
+
+	switch(platform)
+	{
+	#if defined(__linux__) && !defined(__ANDROID__)
+	case EGL_PLATFORM_X11_EXT: break;
+	case EGL_PLATFORM_GBM_KHR: break;
+	#endif
+	default:
+		return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
+	}
+
+	#if defined(__linux__) && !defined(__ANDROID__)
+		if(platform == EGL_PLATFORM_X11_EXT)
+		{
+			if(!libX11)
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);
+			}
+
+			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented
+			}
+		}
+		else if(platform == EGL_PLATFORM_GBM_KHR)
+		{
+			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented
+			}
+
+			return success(HEADLESS_DISPLAY);
+		}
+	#endif
+
+	return success(PRIMARY_DISPLAY);   // We only support the default display
+}
+
+EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
+{
+	return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);
+}
+
+EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
+{
+	return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
+}
+
+EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);
+	}
+
+	if(type != EGL_SYNC_FENCE_KHR)
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+	}
+
+	if(attrib_list && attrib_list[0] != EGL_NONE)
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+	}
+
+	egl::Context *context = egl::getCurrentContext();
+
+	if(!validateContext(display, context))
+	{
+		return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
+	}
+
+	EGLSyncKHR sync = display->createSync(context);
+
+	return success(sync);
+}
+
+EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
+
+	egl::Display *display = egl::Display::get(dpy);
+	FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!display->isValidSync(eglSync))
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	display->destroySync(eglSync);
+
+	return success(EGL_TRUE);
+}
+
+EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);
+
+	egl::Display *display = egl::Display::get(dpy);
+	FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!display->isValidSync(eglSync))
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	(void)flags;
+	(void)timeout;
+
+	if(!eglSync->isSignaled())
+	{
+		eglSync->wait();
+	}
+
+	return success(EGL_CONDITION_SATISFIED_KHR);
+}
+
+EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!display->isValidSync(eglSync))
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	switch(attribute)
+	{
+	case EGL_SYNC_TYPE_KHR:
+		*value = EGL_SYNC_FENCE_KHR;
+		return success(EGL_TRUE);
+	case EGL_SYNC_STATUS_KHR:
+		eglSync->wait();   // TODO: Don't block. Just poll based on sw::Query.
+		*value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;
+		return success(EGL_TRUE);
+	case EGL_SYNC_CONDITION_KHR:
+		*value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
+		return success(EGL_TRUE);
+	default:
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+}
+
+__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
+{
+	TRACE("(const char *procname = \"%s\")", procname);
+
+	struct Extension
+	{
+		const char *name;
+		__eglMustCastToProperFunctionPointerType address;
+	};
+
+	static const Extension eglExtensions[] =
+	{
+		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+		EXTENSION(eglCreateImageKHR),
+		EXTENSION(eglDestroyImageKHR),
+		EXTENSION(eglGetPlatformDisplayEXT),
+		EXTENSION(eglCreatePlatformWindowSurfaceEXT),
+		EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
+		EXTENSION(eglCreateSyncKHR),
+		EXTENSION(eglDestroySyncKHR),
+		EXTENSION(eglClientWaitSyncKHR),
+		EXTENSION(eglGetSyncAttribKHR),
+
+		#undef EXTENSION
+	};
+
+	for(unsigned int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
+	{
+		if(strcmp(procname, eglExtensions[ext].name) == 0)
+		{
+			return success((__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address);
+		}
+	}
+
+	if(libGLESv2)
+	{
+		__eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);
+		if(proc) return success(proc);
+	}
+
+	if(libGLES_CM)
+	{
+		__eglMustCastToProperFunctionPointerType proc =  libGLES_CM->es1GetProcAddress(procname);
+		if(proc) return success(proc);
+	}
+
+	return success((__eglMustCastToProperFunctionPointerType)NULL);
+}
+}
diff --git a/src/OpenGL/libEGL/libEGL.def b/src/OpenGL/libEGL/libEGL.def
index 972d87c..525099e 100644
--- a/src/OpenGL/libEGL/libEGL.def
+++ b/src/OpenGL/libEGL/libEGL.def
@@ -39,8 +39,8 @@
 	eglCreateImageKHR

 	eglDestroyImageKHR

 	eglGetPlatformDisplayEXT

-    eglCreatePlatformWindowSurfaceEXT

-    eglCreatePlatformPixmapSurfaceEXT

+	eglCreatePlatformWindowSurfaceEXT

+	eglCreatePlatformPixmapSurfaceEXT

 	eglCreateSyncKHR

 	eglDestroySyncKHR

 	eglClientWaitSyncKHR

diff --git a/src/OpenGL/libEGL/libEGL.hpp b/src/OpenGL/libEGL/libEGL.hpp
index 0cfbf9b..719117b 100644
--- a/src/OpenGL/libEGL/libEGL.hpp
+++ b/src/OpenGL/libEGL/libEGL.hpp
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #ifndef libEGL_hpp
 #define libEGL_hpp
 
diff --git a/src/OpenGL/libEGL/libEGL.rc b/src/OpenGL/libEGL/libEGL.rc
index 69bf3c9..708e6dc 100644
--- a/src/OpenGL/libEGL/libEGL.rc
+++ b/src/OpenGL/libEGL/libEGL.rc
@@ -26,18 +26,18 @@
 // TEXTINCLUDE

 //

 

-1 TEXTINCLUDE 

+1 TEXTINCLUDE

 BEGIN

     "resource.h\0"

 END

 

-2 TEXTINCLUDE 

+2 TEXTINCLUDE

 BEGIN

     "#include ""afxres.h""\r\n"

     "#include ""../common/version.h""\0"

 END

 

-3 TEXTINCLUDE 

+3 TEXTINCLUDE

 BEGIN

     "\r\n"

     "\0"

@@ -75,7 +75,7 @@
 			#endif

             VALUE "FileVersion", VERSION_STRING

             VALUE "InternalName", "libEGL"

-            VALUE "LegalCopyright", "Copyright (C) 2012 TransGaming Inc."

+            VALUE "LegalCopyright", "Copyright (C) 2016 Google Inc."

             VALUE "OriginalFilename", "libEGL.dll"

             VALUE "PrivateBuild", VERSION_STRING

             VALUE "ProductName", "SwiftShader libEGL Dynamic Link Library"

diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index 334246c..6cae329 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -1,640 +1,643 @@
-// 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.

-//

-

-// main.cpp: DLL entry point and management of thread-local data.

-

-#include "main.h"

-

-#include "libEGL.hpp"

-#include "Context.hpp"

-#include "Surface.h"

-

-#include "resource.h"

-#include "Common/Thread.hpp"

-#include "Common/SharedLibrary.hpp"

-#include "common/debug.h"

-

-#include <EGL/eglext.h>

-

-static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;

-

-#if !defined(_MSC_VER)

-#define CONSTRUCTOR __attribute__((constructor))

-#define DESTRUCTOR __attribute__((destructor))

-#else

-#define CONSTRUCTOR

-#define DESTRUCTOR

-#endif

-

-static void eglAttachThread()

-{

-    TRACE("()");

-

-    egl::Current *current = new egl::Current;

-

-    if(current)

-    {

-        sw::Thread::setLocalStorage(currentTLS, current);

-

-        current->error = EGL_SUCCESS;

-        current->API = EGL_OPENGL_ES_API;

-		current->display = EGL_NO_DISPLAY;

-		current->context = nullptr;

-		current->drawSurface = nullptr;

-        current->readSurface = nullptr;

-	}

-}

-

-static void eglDetachThread()

-{

-    TRACE("()");

-

-	egl::Current *current = (egl::Current*)sw::Thread::getLocalStorage(currentTLS);

-

-	if(current)

-	{

-        delete current;

-	}

-}

-

-CONSTRUCTOR static void eglAttachProcess()

-{

-    TRACE("()");

-

-	#if !defined(ANGLE_DISABLE_TRACE) && defined(TRACE_OUTPUT_FILE)

-        FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");

-

-        if(debug)

-        {

-            fclose(debug);

-            debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase

-            fclose(debug);

-        }

-	#endif

-

-    currentTLS = sw::Thread::allocateLocalStorageKey();

-

-    if(currentTLS == TLS_OUT_OF_INDEXES)

-    {

-        return;

-    }

-

-	eglAttachThread();

-}

-

-DESTRUCTOR static void eglDetachProcess()

-{

-    TRACE("()");

-

-	eglDetachThread();

-	sw::Thread::freeLocalStorageKey(currentTLS);

-}

-

-#if defined(_WIN32)

-static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

-{

-	RECT rect;

-

-    switch(uMsg)

-    {

-    case WM_INITDIALOG:

-		GetWindowRect(GetDesktopWindow(), &rect);

-		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);

-		SetTimer(hwnd, 1, 100, NULL);

-		return TRUE;

-    case WM_COMMAND:

-        if(LOWORD(wParam) == IDCANCEL)

-		{

-			EndDialog(hwnd, 0);

-		}

-        break;

-    case WM_TIMER:

-		if(IsDebuggerPresent())

-		{

-			EndDialog(hwnd, 0);

-		}

-    }

-

-    return FALSE;

-}

-

-static void WaitForDebugger(HINSTANCE instance)

-{

-    if(!IsDebuggerPresent())

-    {

-        HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);

-		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);

-		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);

-    }

-}

-

-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)

-{

-    switch(reason)

-    {

-    case DLL_PROCESS_ATTACH:

-		#ifndef NDEBUG

-			WaitForDebugger(instance);

-		#endif

-        eglAttachProcess();

-        break;

-    case DLL_THREAD_ATTACH:

-        eglAttachThread();

-        break;

-    case DLL_THREAD_DETACH:

-        eglDetachThread();

-        break;

-    case DLL_PROCESS_DETACH:

-        eglDetachProcess();

-        break;

-    default:

-        break;

-    }

-

-    return TRUE;

-}

-#endif

-

-namespace egl

-{

-static Current *eglGetCurrent(void)

-{

-	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);

-

-	if(!current)

-	{

-		eglAttachThread();

-	}

-

-	return (Current*)sw::Thread::getLocalStorage(currentTLS);

-}

-

-void setCurrentError(EGLint error)

-{

-    Current *current = eglGetCurrent();

-

-    current->error = error;

-}

-

-EGLint getCurrentError()

-{

-    Current *current = eglGetCurrent();

-

-    return current->error;

-}

-

-void setCurrentAPI(EGLenum API)

-{

-    Current *current = eglGetCurrent();

-

-    current->API = API;

-}

-

-EGLenum getCurrentAPI()

-{

-    Current *current = eglGetCurrent();

-

-    return current->API;

-}

-

-void setCurrentDisplay(EGLDisplay dpy)

-{

-    Current *current = eglGetCurrent();

-

-    current->display = dpy;

-}

-

-EGLDisplay getCurrentDisplay()

-{

-    Current *current = eglGetCurrent();

-

-    return current->display;

-}

-

-void setCurrentContext(egl::Context *ctx)

-{

-    Current *current = eglGetCurrent();

-

-	if(ctx)

-	{

-		ctx->addRef();

-	}

-

-	if(current->context)

-	{

-		current->context->release();

-	}

-

-    current->context = ctx;

-}

-

-egl::Context *getCurrentContext()

-{

-    Current *current = eglGetCurrent();

-

-    return current->context;

-}

-

-void setCurrentDrawSurface(egl::Surface *surface)

-{

-    Current *current = eglGetCurrent();

-

-	if(surface)

-	{

-		surface->addRef();

-	}

-

-	if(current->drawSurface)

-	{

-		current->drawSurface->release();

-	}

-

-    current->drawSurface = surface;

-}

-

-egl::Surface *getCurrentDrawSurface()

-{

-    Current *current = eglGetCurrent();

-

-    return current->drawSurface;

-}

-

-void setCurrentReadSurface(egl::Surface *surface)

-{

-    Current *current = eglGetCurrent();

-

-	if(surface)

-	{

-		surface->addRef();

-	}

-

-	if(current->readSurface)

-	{

-		current->readSurface->release();

-	}

-

-    current->readSurface = surface;

-}

-

-egl::Surface *getCurrentReadSurface()

-{

-    Current *current = eglGetCurrent();

-

-    return current->readSurface;

-}

-

-void error(EGLint errorCode)

-{

-    egl::setCurrentError(errorCode);

-

-	if(errorCode != EGL_SUCCESS)

-	{

-		switch(errorCode)

-		{

-		case EGL_NOT_INITIALIZED:     TRACE("\t! Error generated: not initialized\n");     break;

-		case EGL_BAD_ACCESS:          TRACE("\t! Error generated: bad access\n");          break;

-		case EGL_BAD_ALLOC:           TRACE("\t! Error generated: bad alloc\n");           break;

-		case EGL_BAD_ATTRIBUTE:       TRACE("\t! Error generated: bad attribute\n");       break;

-		case EGL_BAD_CONFIG:          TRACE("\t! Error generated: bad config\n");          break;

-		case EGL_BAD_CONTEXT:         TRACE("\t! Error generated: bad context\n");         break;

-		case EGL_BAD_CURRENT_SURFACE: TRACE("\t! Error generated: bad current surface\n"); break;

-		case EGL_BAD_DISPLAY:         TRACE("\t! Error generated: bad display\n");         break;

-		case EGL_BAD_MATCH:           TRACE("\t! Error generated: bad match\n");           break;

-		case EGL_BAD_NATIVE_PIXMAP:   TRACE("\t! Error generated: bad native pixmap\n");   break;

-		case EGL_BAD_NATIVE_WINDOW:   TRACE("\t! Error generated: bad native window\n");   break;

-		case EGL_BAD_PARAMETER:       TRACE("\t! Error generated: bad parameter\n");       break;

-		case EGL_BAD_SURFACE:         TRACE("\t! Error generated: bad surface\n");         break;

-		case EGL_CONTEXT_LOST:        TRACE("\t! Error generated: context lost\n");        break;

-		default:                      TRACE("\t! Error generated: <0x%X>\n", errorCode);   break;

-		}

-	}

-}

-}

-

-namespace egl

-{

-EGLint GetError(void);

-EGLDisplay GetDisplay(EGLNativeDisplayType display_id);

-EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor);

-EGLBoolean Terminate(EGLDisplay dpy);

-const char *QueryString(EGLDisplay dpy, EGLint name);

-EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);

-EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);

-EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);

-EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list);

-EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);

-EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);

-EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface);

-EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);

-EGLBoolean BindAPI(EGLenum api);

-EGLenum QueryAPI(void);

-EGLBoolean WaitClient(void);

-EGLBoolean ReleaseThread(void);

-EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);

-EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);

-EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);

-EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);

-EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval);

-EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);

-EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx);

-EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);

-EGLContext GetCurrentContext(void);

-EGLSurface GetCurrentSurface(EGLint readdraw);

-EGLDisplay GetCurrentDisplay(void);

-EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);

-EGLBoolean WaitGL(void);

-EGLBoolean WaitNative(EGLint engine);

-EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface);

-EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);

-EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);

-EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image);

-EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list);

-EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);

-EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);

-EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);

-EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);

-EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);

-EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);

-__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname);

-}

-

-extern "C"

-{

-EGLAPI EGLint EGLAPIENTRY eglGetError(void)

-{

-	return egl::GetError();

-}

-

-EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)

-{

-	return egl::GetDisplay(display_id);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)

-{

-	return egl::Initialize(dpy, major, minor);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)

-{

-	return egl::Terminate(dpy);

-}

-

-EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)

-{

-	return egl::QueryString(dpy, name);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	return egl::GetConfigs(dpy, configs, config_size, num_config);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	return egl::ChooseConfig(dpy, attrib_list, configs, config_size, num_config);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)

-{

-	return egl::GetConfigAttrib(dpy, config, attribute, value);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)

-{

-	return egl::CreateWindowSurface(dpy, config, window, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)

-{

-	return egl::CreatePbufferSurface(dpy, config, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)

-{

-	return egl::CreatePixmapSurface(dpy, config, pixmap, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)

-{

-	return egl::DestroySurface(dpy, surface);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)

-{

-	return egl::QuerySurface(dpy, surface, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)

-{

-	return egl::BindAPI(api);

-}

-

-EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)

-{

-	return egl::QueryAPI();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)

-{

-	return egl::WaitClient();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)

-{

-	return egl::ReleaseThread();

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)

-{

-	return egl::CreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)

-{

-	return egl::SurfaceAttrib(dpy, surface, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	return egl::BindTexImage(dpy, surface, buffer);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	return egl::ReleaseTexImage(dpy, surface, buffer);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)

-{

-	return egl::SwapInterval(dpy, interval);

-}

-

-EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)

-{

-	return egl::CreateContext(dpy, config, share_context, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)

-{

-	return egl::DestroyContext(dpy, ctx);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)

-{

-	return egl::MakeCurrent(dpy, draw, read, ctx);

-}

-

-EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)

-{

-	return egl::GetCurrentContext();

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)

-{

-	return egl::GetCurrentSurface(readdraw);

-}

-

-EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)

-{

-	return egl::GetCurrentDisplay();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)

-{

-	return egl::QueryContext(dpy, ctx, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)

-{

-	return egl::WaitClient();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)

-{

-	return egl::WaitNative(engine);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)

-{

-	return egl::SwapBuffers(dpy, surface);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)

-{

-	return egl::CopyBuffers(dpy, surface, target);

-}

-

-EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)

-{

-	return egl::CreateImageKHR(dpy, ctx, target, buffer, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)

-{

-	return egl::DestroyImageKHR(dpy, image);

-}

-

-EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)

-{

-	return egl::GetPlatformDisplayEXT(platform, native_display, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)

-{

-	return egl::CreatePlatformWindowSurfaceEXT(dpy, config, native_window, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)

-{

-	return egl::CreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap, attrib_list);

-}

-

-EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)

-{

-	return egl::CreateSyncKHR(dpy, type, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)

-{

-	return egl::DestroySyncKHR(dpy, sync);

-}

-

-EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)

-{

-	return egl::ClientWaitSyncKHR(dpy, sync, flags, timeout);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)

-{

-	return egl::GetSyncAttribKHR(dpy, sync, attribute, value);

-}

-

-EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)

-{

-	return egl::GetProcAddress(procname);

-}

-}

-

-LibEGLexports::LibEGLexports()

-{

-	this->eglGetError = egl::GetError;

-	this->eglGetDisplay = egl::GetDisplay;

-	this->eglInitialize = egl::Initialize;

-	this->eglTerminate = egl::Terminate;

-	this->eglQueryString = egl::QueryString;

-	this->eglGetConfigs = egl::GetConfigs;

-	this->eglChooseConfig = egl::ChooseConfig;

-	this->eglGetConfigAttrib = egl::GetConfigAttrib;

-	this->eglCreateWindowSurface = egl::CreateWindowSurface;

-	this->eglCreatePbufferSurface = egl::CreatePbufferSurface;

-	this->eglCreatePixmapSurface = egl::CreatePixmapSurface;

-	this->eglDestroySurface = egl::DestroySurface;

-	this->eglQuerySurface = egl::QuerySurface;

-	this->eglBindAPI = egl::BindAPI;

-	this->eglQueryAPI = egl::QueryAPI;

-	this->eglWaitClient = egl::WaitClient;

-	this->eglReleaseThread = egl::ReleaseThread;

-	this->eglCreatePbufferFromClientBuffer = egl::CreatePbufferFromClientBuffer;

-	this->eglSurfaceAttrib = egl::SurfaceAttrib;

-	this->eglBindTexImage = egl::BindTexImage;

-	this->eglReleaseTexImage = egl::ReleaseTexImage;

-	this->eglSwapInterval = egl::SwapInterval;

-	this->eglCreateContext = egl::CreateContext;

-	this->eglDestroyContext = egl::DestroyContext;

-	this->eglMakeCurrent = egl::MakeCurrent;

-	this->eglGetCurrentContext = egl::GetCurrentContext;

-	this->eglGetCurrentSurface = egl::GetCurrentSurface;

-	this->eglGetCurrentDisplay = egl::GetCurrentDisplay;

-	this->eglQueryContext = egl::QueryContext;

-	this->eglWaitGL = egl::WaitGL;

-	this->eglWaitNative = egl::WaitNative;

-	this->eglSwapBuffers = egl::SwapBuffers;

-	this->eglCopyBuffers = egl::CopyBuffers;

-	this->eglCreateImageKHR = egl::CreateImageKHR;

-	this->eglDestroyImageKHR = egl::DestroyImageKHR;

-	this->eglGetProcAddress = egl::GetProcAddress;

-	this->eglCreateSyncKHR = egl::CreateSyncKHR;

-	this->eglDestroySyncKHR = egl::DestroySyncKHR;

-	this->eglClientWaitSyncKHR = egl::ClientWaitSyncKHR;

-	this->eglGetSyncAttribKHR = egl::GetSyncAttribKHR;

-

-	this->clientGetCurrentContext = egl::getCurrentContext;

-}

-

-extern "C" EGLAPI LibEGLexports *libEGL_swiftshader()

-{

-	static LibEGLexports libEGL;

-	return &libEGL;

-}

-

-LibGLES_CM libGLES_CM;

-LibGLESv2 libGLESv2;

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// main.cpp: DLL entry point and management of thread-local data.
+
+#include "main.h"
+
+#include "libEGL.hpp"
+#include "Context.hpp"
+#include "Surface.h"
+
+#include "resource.h"
+#include "Common/Thread.hpp"
+#include "Common/SharedLibrary.hpp"
+#include "common/debug.h"
+
+#include <EGL/eglext.h>
+
+static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
+
+#if !defined(_MSC_VER)
+#define CONSTRUCTOR __attribute__((constructor))
+#define DESTRUCTOR __attribute__((destructor))
+#else
+#define CONSTRUCTOR
+#define DESTRUCTOR
+#endif
+
+static void eglAttachThread()
+{
+	TRACE("()");
+
+	egl::Current *current = new egl::Current;
+
+	if(current)
+	{
+		sw::Thread::setLocalStorage(currentTLS, current);
+
+		current->error = EGL_SUCCESS;
+		current->API = EGL_OPENGL_ES_API;
+		current->display = EGL_NO_DISPLAY;
+		current->context = nullptr;
+		current->drawSurface = nullptr;
+		current->readSurface = nullptr;
+	}
+}
+
+static void eglDetachThread()
+{
+	TRACE("()");
+
+	egl::Current *current = (egl::Current*)sw::Thread::getLocalStorage(currentTLS);
+
+	if(current)
+	{
+		delete current;
+	}
+}
+
+CONSTRUCTOR static void eglAttachProcess()
+{
+	TRACE("()");
+
+	#if !defined(ANGLE_DISABLE_TRACE) && defined(TRACE_OUTPUT_FILE)
+		FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
+
+		if(debug)
+		{
+			fclose(debug);
+			debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
+			fclose(debug);
+		}
+	#endif
+
+	currentTLS = sw::Thread::allocateLocalStorageKey();
+
+	if(currentTLS == TLS_OUT_OF_INDEXES)
+	{
+		return;
+	}
+
+	eglAttachThread();
+}
+
+DESTRUCTOR static void eglDetachProcess()
+{
+	TRACE("()");
+
+	eglDetachThread();
+	sw::Thread::freeLocalStorageKey(currentTLS);
+}
+
+#if defined(_WIN32)
+static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	RECT rect;
+
+	switch(uMsg)
+	{
+	case WM_INITDIALOG:
+		GetWindowRect(GetDesktopWindow(), &rect);
+		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
+		SetTimer(hwnd, 1, 100, NULL);
+		return TRUE;
+	case WM_COMMAND:
+		if(LOWORD(wParam) == IDCANCEL)
+		{
+			EndDialog(hwnd, 0);
+		}
+		break;
+	case WM_TIMER:
+		if(IsDebuggerPresent())
+		{
+			EndDialog(hwnd, 0);
+		}
+	}
+
+	return FALSE;
+}
+
+static void WaitForDebugger(HINSTANCE instance)
+{
+	if(!IsDebuggerPresent())
+	{
+		HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
+		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
+		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
+	}
+}
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+	switch(reason)
+	{
+	case DLL_PROCESS_ATTACH:
+		#ifndef NDEBUG
+			WaitForDebugger(instance);
+		#endif
+		eglAttachProcess();
+		break;
+	case DLL_THREAD_ATTACH:
+		eglAttachThread();
+		break;
+	case DLL_THREAD_DETACH:
+		eglDetachThread();
+		break;
+	case DLL_PROCESS_DETACH:
+		eglDetachProcess();
+		break;
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+#endif
+
+namespace egl
+{
+static Current *eglGetCurrent(void)
+{
+	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
+
+	if(!current)
+	{
+		eglAttachThread();
+	}
+
+	return (Current*)sw::Thread::getLocalStorage(currentTLS);
+}
+
+void setCurrentError(EGLint error)
+{
+	Current *current = eglGetCurrent();
+
+	current->error = error;
+}
+
+EGLint getCurrentError()
+{
+	Current *current = eglGetCurrent();
+
+	return current->error;
+}
+
+void setCurrentAPI(EGLenum API)
+{
+	Current *current = eglGetCurrent();
+
+	current->API = API;
+}
+
+EGLenum getCurrentAPI()
+{
+	Current *current = eglGetCurrent();
+
+	return current->API;
+}
+
+void setCurrentDisplay(EGLDisplay dpy)
+{
+	Current *current = eglGetCurrent();
+
+	current->display = dpy;
+}
+
+EGLDisplay getCurrentDisplay()
+{
+	Current *current = eglGetCurrent();
+
+	return current->display;
+}
+
+void setCurrentContext(egl::Context *ctx)
+{
+	Current *current = eglGetCurrent();
+
+	if(ctx)
+	{
+		ctx->addRef();
+	}
+
+	if(current->context)
+	{
+		current->context->release();
+	}
+
+	current->context = ctx;
+}
+
+egl::Context *getCurrentContext()
+{
+	Current *current = eglGetCurrent();
+
+	return current->context;
+}
+
+void setCurrentDrawSurface(egl::Surface *surface)
+{
+	Current *current = eglGetCurrent();
+
+	if(surface)
+	{
+		surface->addRef();
+	}
+
+	if(current->drawSurface)
+	{
+		current->drawSurface->release();
+	}
+
+	current->drawSurface = surface;
+}
+
+egl::Surface *getCurrentDrawSurface()
+{
+	Current *current = eglGetCurrent();
+
+	return current->drawSurface;
+}
+
+void setCurrentReadSurface(egl::Surface *surface)
+{
+	Current *current = eglGetCurrent();
+
+	if(surface)
+	{
+		surface->addRef();
+	}
+
+	if(current->readSurface)
+	{
+		current->readSurface->release();
+	}
+
+	current->readSurface = surface;
+}
+
+egl::Surface *getCurrentReadSurface()
+{
+	Current *current = eglGetCurrent();
+
+	return current->readSurface;
+}
+
+void error(EGLint errorCode)
+{
+	egl::setCurrentError(errorCode);
+
+	if(errorCode != EGL_SUCCESS)
+	{
+		switch(errorCode)
+		{
+		case EGL_NOT_INITIALIZED:     TRACE("\t! Error generated: not initialized\n");     break;
+		case EGL_BAD_ACCESS:          TRACE("\t! Error generated: bad access\n");          break;
+		case EGL_BAD_ALLOC:           TRACE("\t! Error generated: bad alloc\n");           break;
+		case EGL_BAD_ATTRIBUTE:       TRACE("\t! Error generated: bad attribute\n");       break;
+		case EGL_BAD_CONFIG:          TRACE("\t! Error generated: bad config\n");          break;
+		case EGL_BAD_CONTEXT:         TRACE("\t! Error generated: bad context\n");         break;
+		case EGL_BAD_CURRENT_SURFACE: TRACE("\t! Error generated: bad current surface\n"); break;
+		case EGL_BAD_DISPLAY:         TRACE("\t! Error generated: bad display\n");         break;
+		case EGL_BAD_MATCH:           TRACE("\t! Error generated: bad match\n");           break;
+		case EGL_BAD_NATIVE_PIXMAP:   TRACE("\t! Error generated: bad native pixmap\n");   break;
+		case EGL_BAD_NATIVE_WINDOW:   TRACE("\t! Error generated: bad native window\n");   break;
+		case EGL_BAD_PARAMETER:       TRACE("\t! Error generated: bad parameter\n");       break;
+		case EGL_BAD_SURFACE:         TRACE("\t! Error generated: bad surface\n");         break;
+		case EGL_CONTEXT_LOST:        TRACE("\t! Error generated: context lost\n");        break;
+		default:                      TRACE("\t! Error generated: <0x%X>\n", errorCode);   break;
+		}
+	}
+}
+}
+
+namespace egl
+{
+EGLint GetError(void);
+EGLDisplay GetDisplay(EGLNativeDisplayType display_id);
+EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLBoolean Terminate(EGLDisplay dpy);
+const char *QueryString(EGLDisplay dpy, EGLint name);
+EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list);
+EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface);
+EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+EGLBoolean BindAPI(EGLenum api);
+EGLenum QueryAPI(void);
+EGLBoolean WaitClient(void);
+EGLBoolean ReleaseThread(void);
+EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval);
+EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx);
+EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLContext GetCurrentContext(void);
+EGLSurface GetCurrentSurface(EGLint readdraw);
+EGLDisplay GetCurrentDisplay(void);
+EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+EGLBoolean WaitGL(void);
+EGLBoolean WaitNative(EGLint engine);
+EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface);
+EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image);
+EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list);
+EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
+EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname);
+}
+
+extern "C"
+{
+EGLAPI EGLint EGLAPIENTRY eglGetError(void)
+{
+	return egl::GetError();
+}
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
+{
+	return egl::GetDisplay(display_id);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+	return egl::Initialize(dpy, major, minor);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
+{
+	return egl::Terminate(dpy);
+}
+
+EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
+{
+	return egl::QueryString(dpy, name);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	return egl::GetConfigs(dpy, configs, config_size, num_config);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	return egl::ChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+	return egl::GetConfigAttrib(dpy, config, attribute, value);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
+{
+	return egl::CreateWindowSurface(dpy, config, window, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+	return egl::CreatePbufferSurface(dpy, config, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+	return egl::CreatePixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+	return egl::DestroySurface(dpy, surface);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+	return egl::QuerySurface(dpy, surface, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
+{
+	return egl::BindAPI(api);
+}
+
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)
+{
+	return egl::QueryAPI();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)
+{
+	return egl::WaitClient();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)
+{
+	return egl::ReleaseThread();
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+	return egl::CreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+	return egl::SurfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	return egl::BindTexImage(dpy, surface, buffer);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	return egl::ReleaseTexImage(dpy, surface, buffer);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+	return egl::SwapInterval(dpy, interval);
+}
+
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+	return egl::CreateContext(dpy, config, share_context, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+	return egl::DestroyContext(dpy, ctx);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+	return egl::MakeCurrent(dpy, draw, read, ctx);
+}
+
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)
+{
+	return egl::GetCurrentContext();
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
+{
+	return egl::GetCurrentSurface(readdraw);
+}
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
+{
+	return egl::GetCurrentDisplay();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+	return egl::QueryContext(dpy, ctx, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
+{
+	return egl::WaitClient();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
+{
+	return egl::WaitNative(engine);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+	return egl::SwapBuffers(dpy, surface);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+	return egl::CopyBuffers(dpy, surface, target);
+}
+
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+	return egl::CreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+	return egl::DestroyImageKHR(dpy, image);
+}
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+{
+	return egl::GetPlatformDisplayEXT(platform, native_display, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
+{
+	return egl::CreatePlatformWindowSurfaceEXT(dpy, config, native_window, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
+{
+	return egl::CreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap, attrib_list);
+}
+
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+	return egl::CreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+	return egl::DestroySyncKHR(dpy, sync);
+}
+
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+	return egl::ClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+	return egl::GetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
+{
+	return egl::GetProcAddress(procname);
+}
+}
+
+LibEGLexports::LibEGLexports()
+{
+	this->eglGetError = egl::GetError;
+	this->eglGetDisplay = egl::GetDisplay;
+	this->eglInitialize = egl::Initialize;
+	this->eglTerminate = egl::Terminate;
+	this->eglQueryString = egl::QueryString;
+	this->eglGetConfigs = egl::GetConfigs;
+	this->eglChooseConfig = egl::ChooseConfig;
+	this->eglGetConfigAttrib = egl::GetConfigAttrib;
+	this->eglCreateWindowSurface = egl::CreateWindowSurface;
+	this->eglCreatePbufferSurface = egl::CreatePbufferSurface;
+	this->eglCreatePixmapSurface = egl::CreatePixmapSurface;
+	this->eglDestroySurface = egl::DestroySurface;
+	this->eglQuerySurface = egl::QuerySurface;
+	this->eglBindAPI = egl::BindAPI;
+	this->eglQueryAPI = egl::QueryAPI;
+	this->eglWaitClient = egl::WaitClient;
+	this->eglReleaseThread = egl::ReleaseThread;
+	this->eglCreatePbufferFromClientBuffer = egl::CreatePbufferFromClientBuffer;
+	this->eglSurfaceAttrib = egl::SurfaceAttrib;
+	this->eglBindTexImage = egl::BindTexImage;
+	this->eglReleaseTexImage = egl::ReleaseTexImage;
+	this->eglSwapInterval = egl::SwapInterval;
+	this->eglCreateContext = egl::CreateContext;
+	this->eglDestroyContext = egl::DestroyContext;
+	this->eglMakeCurrent = egl::MakeCurrent;
+	this->eglGetCurrentContext = egl::GetCurrentContext;
+	this->eglGetCurrentSurface = egl::GetCurrentSurface;
+	this->eglGetCurrentDisplay = egl::GetCurrentDisplay;
+	this->eglQueryContext = egl::QueryContext;
+	this->eglWaitGL = egl::WaitGL;
+	this->eglWaitNative = egl::WaitNative;
+	this->eglSwapBuffers = egl::SwapBuffers;
+	this->eglCopyBuffers = egl::CopyBuffers;
+	this->eglCreateImageKHR = egl::CreateImageKHR;
+	this->eglDestroyImageKHR = egl::DestroyImageKHR;
+	this->eglGetProcAddress = egl::GetProcAddress;
+	this->eglCreateSyncKHR = egl::CreateSyncKHR;
+	this->eglDestroySyncKHR = egl::DestroySyncKHR;
+	this->eglClientWaitSyncKHR = egl::ClientWaitSyncKHR;
+	this->eglGetSyncAttribKHR = egl::GetSyncAttribKHR;
+
+	this->clientGetCurrentContext = egl::getCurrentContext;
+}
+
+extern "C" EGLAPI LibEGLexports *libEGL_swiftshader()
+{
+	static LibEGLexports libEGL;
+	return &libEGL;
+}
+
+LibGLES_CM libGLES_CM;
+LibGLESv2 libGLESv2;
diff --git a/src/OpenGL/libEGL/main.h b/src/OpenGL/libEGL/main.h
index 8bdfcb2..f604a59 100644
--- a/src/OpenGL/libEGL/main.h
+++ b/src/OpenGL/libEGL/main.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // main.h: Management of thread-local data.
 
diff --git a/src/OpenGL/libEGL/resource.h b/src/OpenGL/libEGL/resource.h
index b60570a..62eff14 100644
--- a/src/OpenGL/libEGL/resource.h
+++ b/src/OpenGL/libEGL/resource.h
@@ -1,17 +1,17 @@
-//{{NO_DEPENDENCIES}}

-// Microsoft Visual C++ generated include file.

-// Used by libEGL.rc

-//

-#define IDD_DIALOG1                     101

-#define IDC_STATIC                      -1

-

-// Next default values for new objects

-// 

-#ifdef APSTUDIO_INVOKED

-#ifndef APSTUDIO_READONLY_SYMBOLS

-#define _APS_NEXT_RESOURCE_VALUE        102

-#define _APS_NEXT_COMMAND_VALUE         40001

-#define _APS_NEXT_CONTROL_VALUE         1001

-#define _APS_NEXT_SYMED_VALUE           101

-#endif

-#endif

+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by libEGL.rc
+//
+#define IDD_DIALOG1                     101
+#define IDC_STATIC                      -1
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1001
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/src/OpenGL/libGL/Buffer.cpp b/src/OpenGL/libGL/Buffer.cpp
index f4d7a52..19942f8 100644
--- a/src/OpenGL/libGL/Buffer.cpp
+++ b/src/OpenGL/libGL/Buffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Buffer.cpp: Implements the Buffer class, representing storage of vertex and/or
 // index data. Implements GL buffer objects and related functionality.
@@ -23,14 +26,14 @@
 
 Buffer::Buffer(GLuint name) : NamedObject(name)
 {
-    mContents = 0;
-    mSize = 0;
-    mUsage = GL_DYNAMIC_DRAW;
+	mContents = 0;
+	mSize = 0;
+	mUsage = GL_DYNAMIC_DRAW;
 }
 
 Buffer::~Buffer()
 {
-    if(mContents)
+	if(mContents)
 	{
 		mContents->destruct();
 	}
diff --git a/src/OpenGL/libGL/Buffer.h b/src/OpenGL/libGL/Buffer.h
index 976e9f5..db9c9ce 100644
--- a/src/OpenGL/libGL/Buffer.h
+++ b/src/OpenGL/libGL/Buffer.h
@@ -1,55 +1,58 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Buffer.h: Defines the Buffer class, representing storage of vertex and/or

-// index data. Implements GL buffer objects and related functionality.

-

-#ifndef LIBGL_BUFFER_H_

-#define LIBGL_BUFFER_H_

-

-#include "common/Object.hpp"

-#include "Common/Resource.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#include <cstddef>

-#include <vector>

-

-namespace gl

-{

-class Buffer : public NamedObject

-{

-  public:

-    explicit Buffer(GLuint name);

-

-    virtual ~Buffer();

-

-    void bufferData(const void *data, GLsizeiptr size, GLenum usage);

-    void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);

-

-	const void *data() { return mContents ? mContents->data() : 0; }

-    size_t size() const { return mSize; }

-    GLenum usage() const { return mUsage; }

-

-	sw::Resource *getResource();

-

-  private:

-    sw::Resource *mContents;

-    size_t mSize;

-    GLenum mUsage;

-};

-

-}

-

-#endif   // LIBGL_BUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Buffer.h: Defines the Buffer class, representing storage of vertex and/or
+// index data. Implements GL buffer objects and related functionality.
+
+#ifndef LIBGL_BUFFER_H_
+#define LIBGL_BUFFER_H_
+
+#include "common/Object.hpp"
+#include "Common/Resource.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#include <cstddef>
+#include <vector>
+
+namespace gl
+{
+class Buffer : public NamedObject
+{
+public:
+	explicit Buffer(GLuint name);
+
+	virtual ~Buffer();
+
+	void bufferData(const void *data, GLsizeiptr size, GLenum usage);
+	void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
+
+	const void *data() { return mContents ? mContents->data() : 0; }
+	size_t size() const { return mSize; }
+	GLenum usage() const { return mUsage; }
+
+	sw::Resource *getResource();
+
+private:
+	sw::Resource *mContents;
+	size_t mSize;
+	GLenum mUsage;
+};
+
+}
+
+#endif   // LIBGL_BUFFER_H_
diff --git a/src/OpenGL/libGL/Context.cpp b/src/OpenGL/libGL/Context.cpp
index e886392..64f3f68 100644
--- a/src/OpenGL/libGL/Context.cpp
+++ b/src/OpenGL/libGL/Context.cpp
@@ -1,3618 +1,3619 @@
-// 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.

-//

-

-// Context.cpp: Implements the gl::Context class, managing all GL state and performing

-// rendering operations.

-

-#include "Context.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "ResourceManager.h"

-#include "Buffer.h"

-#include "Fence.h"

-#include "Framebuffer.h"

-#include "Program.h"

-#include "Query.h"

-#include "Renderbuffer.h"

-#include "Shader.h"

-#include "Texture.h"

-#include "VertexDataManager.h"

-#include "IndexDataManager.h"

-#include "Display.h"

-#include "Surface.h"

-#include "Common/Half.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-Context::Context(const Context *shareContext)

-    : modelView(32),

-      projection(2)

-{

-	sw::Context *context = new sw::Context();

-	device = new gl::Device(context);

-

-    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);

-

-    mState.depthClearValue = 1.0f;

-    mState.stencilClearValue = 0;

-

-    mState.cullFaceEnabled = false;

-    mState.cullMode = GL_BACK;

-    mState.frontFace = GL_CCW;

-    mState.depthTestEnabled = false;

-    mState.depthFunc = GL_LESS;

-    mState.blendEnabled = false;

-    mState.sourceBlendRGB = GL_ONE;

-    mState.sourceBlendAlpha = GL_ONE;

-    mState.destBlendRGB = GL_ZERO;

-    mState.destBlendAlpha = GL_ZERO;

-    mState.blendEquationRGB = GL_FUNC_ADD;

-    mState.blendEquationAlpha = GL_FUNC_ADD;

-    mState.blendColor.red = 0;

-    mState.blendColor.green = 0;

-    mState.blendColor.blue = 0;

-    mState.blendColor.alpha = 0;

-    mState.stencilTestEnabled = false;

-    mState.stencilFunc = GL_ALWAYS;

-    mState.stencilRef = 0;

-    mState.stencilMask = -1;

-    mState.stencilWritemask = -1;

-    mState.stencilBackFunc = GL_ALWAYS;

-    mState.stencilBackRef = 0;

-    mState.stencilBackMask = - 1;

-    mState.stencilBackWritemask = -1;

-    mState.stencilFail = GL_KEEP;

-    mState.stencilPassDepthFail = GL_KEEP;

-    mState.stencilPassDepthPass = GL_KEEP;

-    mState.stencilBackFail = GL_KEEP;

-    mState.stencilBackPassDepthFail = GL_KEEP;

-    mState.stencilBackPassDepthPass = GL_KEEP;

-    mState.polygonOffsetFillEnabled = false;

-    mState.polygonOffsetFactor = 0.0f;

-    mState.polygonOffsetUnits = 0.0f;

-    mState.sampleAlphaToCoverageEnabled = false;

-    mState.sampleCoverageEnabled = false;

-    mState.sampleCoverageValue = 1.0f;

-    mState.sampleCoverageInvert = false;

-    mState.scissorTestEnabled = false;

-    mState.ditherEnabled = true;

-    mState.generateMipmapHint = GL_DONT_CARE;

-    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;

-	mState.colorLogicOpEnabled = false;

-	mState.logicalOperation = GL_COPY;

-

-    mState.lineWidth = 1.0f;

-

-    mState.viewportX = 0;

-    mState.viewportY = 0;

-    mState.viewportWidth = 0;

-    mState.viewportHeight = 0;

-    mState.zNear = 0.0f;

-    mState.zFar = 1.0f;

-

-    mState.scissorX = 0;

-    mState.scissorY = 0;

-    mState.scissorWidth = 0;

-    mState.scissorHeight = 0;

-

-    mState.colorMaskRed = true;

-    mState.colorMaskGreen = true;

-    mState.colorMaskBlue = true;

-    mState.colorMaskAlpha = true;

-    mState.depthMask = true;

-

-    if(shareContext)

-    {

-        mResourceManager = shareContext->mResourceManager;

-        mResourceManager->addRef();

-    }

-    else

-    {

-        mResourceManager = new ResourceManager();

-    }

-

-    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional

-    // and cube map texture state vectors respectively associated with them.

-    // In order that access to these initial textures not be lost, they are treated as texture

-    // objects all of whose names are 0.

-

-    mTexture2DZero = new Texture2D(0);

-    mProxyTexture2DZero = new Texture2D(0);

-    mTextureCubeMapZero = new TextureCubeMap(0);

-

-    mState.activeSampler = 0;

-    bindArrayBuffer(0);

-    bindElementArrayBuffer(0);

-    bindTextureCubeMap(0);

-    bindTexture2D(0);

-    bindReadFramebuffer(0);

-    bindDrawFramebuffer(0);

-    bindRenderbuffer(0);

-

-    mState.currentProgram = 0;

-

-    mState.packAlignment = 4;

-    mState.unpackAlignment = 4;

-

-    mVertexDataManager = nullptr;

-    mIndexDataManager = nullptr;

-

-    mInvalidEnum = false;

-    mInvalidValue = false;

-    mInvalidOperation = false;

-    mOutOfMemory = false;

-    mInvalidFramebufferOperation = false;

-

-    mHasBeenCurrent = false;

-

-    markAllStateDirty();

-

-    matrixMode = GL_MODELVIEW;

-

-	listMode = 0;

-	//memset(displayList, 0, sizeof(displayList));

-	listIndex = 0;

-    list = 0;

-	firstFreeIndex = 1;

-

-	clientTexture = GL_TEXTURE0;

-

-    drawing = false;

-    drawMode = 0;   // FIXME

-

-    mState.vertexAttribute[sw::Color0].mCurrentValue[0] = 1.0f;

-    mState.vertexAttribute[sw::Color0].mCurrentValue[1] = 1.0f;

-    mState.vertexAttribute[sw::Color0].mCurrentValue[2] = 1.0f;

-    mState.vertexAttribute[sw::Color0].mCurrentValue[3] = 1.0f;

-    mState.vertexAttribute[sw::Normal].mCurrentValue[0] = 0.0f;

-    mState.vertexAttribute[sw::Normal].mCurrentValue[1] = 0.0f;

-    mState.vertexAttribute[sw::Normal].mCurrentValue[2] = 1.0f;

-    mState.vertexAttribute[sw::Normal].mCurrentValue[3] = 0.0f;

-    mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0] = 0.0f;

-    mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1] = 0.0f;

-    mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2] = 0.0f;

-    mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3] = 1.0f;

-	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0] = 0.0f;

-    mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1] = 0.0f;

-    mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2] = 0.0f;

-    mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3] = 1.0f;

-

-    for(int i = 0; i < 8; i++)

-    {

-        envEnable[i] = true;

-    }

-}

-

-Context::~Context()

-{

-    if(mState.currentProgram != 0)

-    {

-        Program *programObject = mResourceManager->getProgram(mState.currentProgram);

-        if(programObject)

-        {

-            programObject->release();

-        }

-        mState.currentProgram = 0;

-    }

-

-    while(!mFramebufferNameSpace.empty())

-    {

-        deleteFramebuffer(mFramebufferNameSpace.firstName());

-    }

-

-    while(!mFenceNameSpace.empty())

-    {

-        deleteFence(mFenceNameSpace.firstName());

-    }

-

-	while(!mQueryNameSpace.empty())

-    {

-        deleteQuery(mQueryNameSpace.firstName());

-    }

-

-    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-    {

-        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)

-        {

-            mState.samplerTexture[type][sampler] = nullptr;

-        }

-    }

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        mState.vertexAttribute[i].mBoundBuffer = nullptr;

-    }

-

-	for(int i = 0; i < QUERY_TYPE_COUNT; i++)

-    {

-        mState.activeQuery[i] = nullptr;

-    }

-

-    mState.arrayBuffer = nullptr;

-    mState.elementArrayBuffer = nullptr;

-    mState.renderbuffer = nullptr;

-

-    mTexture2DZero = nullptr;

-	mProxyTexture2DZero = nullptr;

-    mTextureCubeMapZero = nullptr;

-

-    delete mVertexDataManager;

-    delete mIndexDataManager;

-

-    mResourceManager->release();

-	delete device;

-}

-

-void Context::makeCurrent(Surface *surface)

-{

-    if(!mHasBeenCurrent)

-    {

-        mVertexDataManager = new VertexDataManager(this);

-        mIndexDataManager = new IndexDataManager();

-

-        mState.viewportX = 0;

-        mState.viewportY = 0;

-        mState.viewportWidth = surface->getWidth();

-        mState.viewportHeight = surface->getHeight();

-

-        mState.scissorX = 0;

-        mState.scissorY = 0;

-        mState.scissorWidth = surface->getWidth();

-        mState.scissorHeight = surface->getHeight();

-

-        mHasBeenCurrent = true;

-    }

-

-    // Wrap the existing resources into GL objects and assign them to the '0' names

-    Image *defaultRenderTarget = surface->getRenderTarget();

-    Image *depthStencil = surface->getDepthStencil();

-

-    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);

-    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);

-    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);

-

-    setFramebufferZero(framebufferZero);

-

-    if(defaultRenderTarget)

-    {

-        defaultRenderTarget->release();

-    }

-

-    if(depthStencil)

-    {

-        depthStencil->release();

-    }

-

-    markAllStateDirty();

-}

-

-// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.

-void Context::markAllStateDirty()

-{

-    mAppliedProgramSerial = 0;

-

-    mDepthStateDirty = true;

-    mMaskStateDirty = true;

-    mBlendStateDirty = true;

-    mStencilStateDirty = true;

-    mPolygonOffsetStateDirty = true;

-    mSampleStateDirty = true;

-    mDitherStateDirty = true;

-    mFrontFaceDirty = true;

-	mColorLogicOperatorDirty = true;

-}

-

-void Context::setClearColor(float red, float green, float blue, float alpha)

-{

-    mState.colorClearValue.red = red;

-    mState.colorClearValue.green = green;

-    mState.colorClearValue.blue = blue;

-    mState.colorClearValue.alpha = alpha;

-}

-

-void Context::setClearDepth(float depth)

-{

-    mState.depthClearValue = depth;

-}

-

-void Context::setClearStencil(int stencil)

-{

-    mState.stencilClearValue = stencil;

-}

-

-void Context::setCullFaceEnabled(bool enabled)

-{

-    mState.cullFaceEnabled = enabled;

-}

-

-bool Context::isCullFaceEnabled() const

-{

-    return mState.cullFaceEnabled;

-}

-

-void Context::setCullMode(GLenum mode)

-{

-   mState.cullMode = mode;

-}

-

-void Context::setFrontFace(GLenum front)

-{

-    if(mState.frontFace != front)

-    {

-        mState.frontFace = front;

-        mFrontFaceDirty = true;

-    }

-}

-

-void Context::setDepthTestEnabled(bool enabled)

-{

-    if(mState.depthTestEnabled != enabled)

-    {

-        mState.depthTestEnabled = enabled;

-        mDepthStateDirty = true;

-    }

-}

-

-bool Context::isDepthTestEnabled() const

-{

-    return mState.depthTestEnabled;

-}

-

-void Context::setDepthFunc(GLenum depthFunc)

-{

-    if(mState.depthFunc != depthFunc)

-    {

-        mState.depthFunc = depthFunc;

-        mDepthStateDirty = true;

-    }

-}

-

-void Context::setDepthRange(float zNear, float zFar)

-{

-    mState.zNear = zNear;

-    mState.zFar = zFar;

-}

-

-void Context::setBlendEnabled(bool enabled)

-{

-    if(mState.blendEnabled != enabled)

-    {

-        mState.blendEnabled = enabled;

-        mBlendStateDirty = true;

-    }

-}

-

-bool Context::isBlendEnabled() const

-{

-    return mState.blendEnabled;

-}

-

-void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)

-{

-    if(mState.sourceBlendRGB != sourceRGB ||

-       mState.sourceBlendAlpha != sourceAlpha ||

-       mState.destBlendRGB != destRGB ||

-       mState.destBlendAlpha != destAlpha)

-    {

-        mState.sourceBlendRGB = sourceRGB;

-        mState.destBlendRGB = destRGB;

-        mState.sourceBlendAlpha = sourceAlpha;

-        mState.destBlendAlpha = destAlpha;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setBlendColor(float red, float green, float blue, float alpha)

-{

-    if(mState.blendColor.red != red ||

-       mState.blendColor.green != green ||

-       mState.blendColor.blue != blue ||

-       mState.blendColor.alpha != alpha)

-    {

-        mState.blendColor.red = red;

-        mState.blendColor.green = green;

-        mState.blendColor.blue = blue;

-        mState.blendColor.alpha = alpha;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)

-{

-    if(mState.blendEquationRGB != rgbEquation ||

-       mState.blendEquationAlpha != alphaEquation)

-    {

-        mState.blendEquationRGB = rgbEquation;

-        mState.blendEquationAlpha = alphaEquation;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setStencilTestEnabled(bool enabled)

-{

-    if(mState.stencilTestEnabled != enabled)

-    {

-        mState.stencilTestEnabled = enabled;

-        mStencilStateDirty = true;

-    }

-}

-

-bool Context::isStencilTestEnabled() const

-{

-    return mState.stencilTestEnabled;

-}

-

-void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)

-{

-    if(mState.stencilFunc != stencilFunc ||

-       mState.stencilRef != stencilRef ||

-       mState.stencilMask != stencilMask)

-    {

-        mState.stencilFunc = stencilFunc;

-        mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;

-        mState.stencilMask = stencilMask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)

-{

-    if(mState.stencilBackFunc != stencilBackFunc ||

-       mState.stencilBackRef != stencilBackRef ||

-       mState.stencilBackMask != stencilBackMask)

-    {

-        mState.stencilBackFunc = stencilBackFunc;

-        mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;

-        mState.stencilBackMask = stencilBackMask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilWritemask(GLuint stencilWritemask)

-{

-    if(mState.stencilWritemask != stencilWritemask)

-    {

-        mState.stencilWritemask = stencilWritemask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilBackWritemask(GLuint stencilBackWritemask)

-{

-    if(mState.stencilBackWritemask != stencilBackWritemask)

-    {

-        mState.stencilBackWritemask = stencilBackWritemask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)

-{

-    if(mState.stencilFail != stencilFail ||

-       mState.stencilPassDepthFail != stencilPassDepthFail ||

-       mState.stencilPassDepthPass != stencilPassDepthPass)

-    {

-        mState.stencilFail = stencilFail;

-        mState.stencilPassDepthFail = stencilPassDepthFail;

-        mState.stencilPassDepthPass = stencilPassDepthPass;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)

-{

-    if(mState.stencilBackFail != stencilBackFail ||

-       mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||

-       mState.stencilBackPassDepthPass != stencilBackPassDepthPass)

-    {

-        mState.stencilBackFail = stencilBackFail;

-        mState.stencilBackPassDepthFail = stencilBackPassDepthFail;

-        mState.stencilBackPassDepthPass = stencilBackPassDepthPass;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setPolygonOffsetFillEnabled(bool enabled)

-{

-    if(mState.polygonOffsetFillEnabled != enabled)

-    {

-        mState.polygonOffsetFillEnabled = enabled;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-bool Context::isPolygonOffsetFillEnabled() const

-{

-    return mState.polygonOffsetFillEnabled;

-}

-

-void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)

-{

-    if(mState.polygonOffsetFactor != factor ||

-       mState.polygonOffsetUnits != units)

-    {

-        mState.polygonOffsetFactor = factor;

-        mState.polygonOffsetUnits = units;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-void Context::setSampleAlphaToCoverageEnabled(bool enabled)

-{

-    if(mState.sampleAlphaToCoverageEnabled != enabled)

-    {

-        mState.sampleAlphaToCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleAlphaToCoverageEnabled() const

-{

-    return mState.sampleAlphaToCoverageEnabled;

-}

-

-void Context::setSampleCoverageEnabled(bool enabled)

-{

-    if(mState.sampleCoverageEnabled != enabled)

-    {

-        mState.sampleCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleCoverageEnabled() const

-{

-    return mState.sampleCoverageEnabled;

-}

-

-void Context::setSampleCoverageParams(GLclampf value, bool invert)

-{

-    if(mState.sampleCoverageValue != value ||

-        mState.sampleCoverageInvert != invert)

-    {

-        mState.sampleCoverageValue = value;

-        mState.sampleCoverageInvert = invert;

-        mSampleStateDirty = true;

-    }

-}

-

-void Context::setScissorTestEnabled(bool enabled)

-{

-    mState.scissorTestEnabled = enabled;

-}

-

-bool Context::isScissorTestEnabled() const

-{

-    return mState.scissorTestEnabled;

-}

-

-void Context::setDitherEnabled(bool enabled)

-{

-    if(mState.ditherEnabled != enabled)

-    {

-        mState.ditherEnabled = enabled;

-        mDitherStateDirty = true;

-    }

-}

-

-bool Context::isDitherEnabled() const

-{

-    return mState.ditherEnabled;

-}

-

-void Context::setLineWidth(GLfloat width)

-{

-    mState.lineWidth = width;

-	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

-}

-

-void Context::setGenerateMipmapHint(GLenum hint)

-{

-    mState.generateMipmapHint = hint;

-}

-

-void Context::setFragmentShaderDerivativeHint(GLenum hint)

-{

-    mState.fragmentShaderDerivativeHint = hint;

-    // TODO: Propagate the hint to shader translator so we can write

-    // ddx, ddx_coarse, or ddx_fine depending on the hint.

-    // Ignore for now. It is valid for implementations to ignore hint.

-}

-

-void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.viewportX = x;

-    mState.viewportY = y;

-    mState.viewportWidth = width;

-    mState.viewportHeight = height;

-}

-

-void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.scissorX = x;

-    mState.scissorY = y;

-    mState.scissorWidth = width;

-    mState.scissorHeight = height;

-}

-

-void Context::setColorMask(bool red, bool green, bool blue, bool alpha)

-{

-    if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||

-       mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)

-    {

-        mState.colorMaskRed = red;

-        mState.colorMaskGreen = green;

-        mState.colorMaskBlue = blue;

-        mState.colorMaskAlpha = alpha;

-        mMaskStateDirty = true;

-    }

-}

-

-void Context::setDepthMask(bool mask)

-{

-    if(mState.depthMask != mask)

-    {

-        mState.depthMask = mask;

-        mMaskStateDirty = true;

-    }

-}

-

-void Context::setActiveSampler(unsigned int active)

-{

-    mState.activeSampler = active;

-}

-

-GLuint Context::getReadFramebufferName() const

-{

-    return mState.readFramebuffer;

-}

-

-GLuint Context::getDrawFramebufferName() const

-{

-    return mState.drawFramebuffer;

-}

-

-GLuint Context::getRenderbufferName() const

-{

-    return mState.renderbuffer.name();

-}

-

-GLuint Context::getArrayBufferName() const

-{

-    return mState.arrayBuffer.name();

-}

-

-GLuint Context::getActiveQuery(GLenum target) const

-{

-    Query *queryObject = nullptr;

-

-    switch(target)

-    {

-    case GL_ANY_SAMPLES_PASSED:

-        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];

-        break;

-    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];

-        break;

-    default:

-        ASSERT(false);

-    }

-

-    if(queryObject)

-    {

-        return queryObject->name;

-    }

-

-	return 0;

-}

-

-void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)

-{

-    mState.vertexAttribute[attribNum].mArrayEnabled = enabled;

-}

-

-const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)

-{

-    return mState.vertexAttribute[attribNum];

-}

-

-void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,

-                                   GLsizei stride, const void *pointer)

-{

-    mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;

-    mState.vertexAttribute[attribNum].mSize = size;

-    mState.vertexAttribute[attribNum].mType = type;

-    mState.vertexAttribute[attribNum].mNormalized = normalized;

-    mState.vertexAttribute[attribNum].mStride = stride;

-    mState.vertexAttribute[attribNum].mPointer = pointer;

-}

-

-const void *Context::getVertexAttribPointer(unsigned int attribNum) const

-{

-    return mState.vertexAttribute[attribNum].mPointer;

-}

-

-const VertexAttributeArray &Context::getVertexAttributes()

-{

-    return mState.vertexAttribute;

-}

-

-void Context::setPackAlignment(GLint alignment)

-{

-    mState.packAlignment = alignment;

-}

-

-GLint Context::getPackAlignment() const

-{

-    return mState.packAlignment;

-}

-

-void Context::setUnpackAlignment(GLint alignment)

-{

-    mState.unpackAlignment = alignment;

-}

-

-GLint Context::getUnpackAlignment() const

-{

-    return mState.unpackAlignment;

-}

-

-GLuint Context::createBuffer()

-{

-    return mResourceManager->createBuffer();

-}

-

-GLuint Context::createProgram()

-{

-    return mResourceManager->createProgram();

-}

-

-GLuint Context::createShader(GLenum type)

-{

-    return mResourceManager->createShader(type);

-}

-

-GLuint Context::createTexture()

-{

-    return mResourceManager->createTexture();

-}

-

-GLuint Context::createRenderbuffer()

-{

-    return mResourceManager->createRenderbuffer();

-}

-

-// Returns an unused framebuffer name

-GLuint Context::createFramebuffer()

-{

-	return mFramebufferNameSpace.allocate();

-}

-

-GLuint Context::createFence()

-{

-	return mFenceNameSpace.allocate(new Fence());

-}

-

-// Returns an unused query name

-GLuint Context::createQuery()

-{

-	return mQueryNameSpace.allocate();

-}

-

-void Context::deleteBuffer(GLuint buffer)

-{

-    if(mResourceManager->getBuffer(buffer))

-    {

-        detachBuffer(buffer);

-    }

-

-    mResourceManager->deleteBuffer(buffer);

-}

-

-void Context::deleteShader(GLuint shader)

-{

-    mResourceManager->deleteShader(shader);

-}

-

-void Context::deleteProgram(GLuint program)

-{

-    mResourceManager->deleteProgram(program);

-}

-

-void Context::deleteTexture(GLuint texture)

-{

-    if(mResourceManager->getTexture(texture))

-    {

-        detachTexture(texture);

-    }

-

-    mResourceManager->deleteTexture(texture);

-}

-

-void Context::deleteRenderbuffer(GLuint renderbuffer)

-{

-    if(mResourceManager->getRenderbuffer(renderbuffer))

-    {

-        detachRenderbuffer(renderbuffer);

-    }

-

-    mResourceManager->deleteRenderbuffer(renderbuffer);

-}

-

-void Context::deleteFramebuffer(GLuint framebuffer)

-{

-    Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);

-

-    if(framebufferObject)

-    {

-        detachFramebuffer(framebuffer);

-

-        delete framebufferObject;

-    }

-}

-

-void Context::deleteFence(GLuint fence)

-{

-    Fence *fenceObject = mFenceNameSpace.remove(fence);

-

-    if(fenceObject)

-    {

-        delete fenceObject;

-    }

-}

-

-void Context::deleteQuery(GLuint query)

-{

-    Query *queryObject = mQueryNameSpace.remove(query);

-

-	if(queryObject)

-    {

-		queryObject->release();

-	}

-}

-

-Buffer *Context::getBuffer(GLuint handle)

-{

-    return mResourceManager->getBuffer(handle);

-}

-

-Shader *Context::getShader(GLuint handle)

-{

-    return mResourceManager->getShader(handle);

-}

-

-Program *Context::getProgram(GLuint handle)

-{

-    return mResourceManager->getProgram(handle);

-}

-

-Texture *Context::getTexture(GLuint handle)

-{

-    return mResourceManager->getTexture(handle);

-}

-

-Renderbuffer *Context::getRenderbuffer(GLuint handle)

-{

-    return mResourceManager->getRenderbuffer(handle);

-}

-

-Framebuffer *Context::getReadFramebuffer()

-{

-    return getFramebuffer(mState.readFramebuffer);

-}

-

-Framebuffer *Context::getDrawFramebuffer()

-{

-    return getFramebuffer(mState.drawFramebuffer);

-}

-

-void Context::bindArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-    mState.arrayBuffer = getBuffer(buffer);

-}

-

-void Context::bindElementArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-    mState.elementArrayBuffer = getBuffer(buffer);

-}

-

-void Context::bindTexture2D(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);

-

-    mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindTextureCubeMap(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);

-

-    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindReadFramebuffer(GLuint framebuffer)

-{

-    if(!getFramebuffer(framebuffer))

-    {

-        mFramebufferNameSpace.insert(framebuffer, new Framebuffer());

-    }

-

-    mState.readFramebuffer = framebuffer;

-}

-

-void Context::bindDrawFramebuffer(GLuint framebuffer)

-{

-    if(!getFramebuffer(framebuffer))

-    {

-        mFramebufferNameSpace.insert(framebuffer, new Framebuffer());

-    }

-

-    mState.drawFramebuffer = framebuffer;

-}

-

-void Context::bindRenderbuffer(GLuint renderbuffer)

-{

-	mResourceManager->checkRenderbufferAllocation(renderbuffer);

-

-    mState.renderbuffer = getRenderbuffer(renderbuffer);

-}

-

-void Context::useProgram(GLuint program)

-{

-    GLuint priorProgram = mState.currentProgram;

-    mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.

-

-    if(priorProgram != program)

-    {

-        Program *newProgram = mResourceManager->getProgram(program);

-        Program *oldProgram = mResourceManager->getProgram(priorProgram);

-

-        if(newProgram)

-        {

-            newProgram->addRef();

-        }

-

-        if(oldProgram)

-        {

-            oldProgram->release();

-        }

-    }

-}

-

-void Context::beginQuery(GLenum target, GLuint query)

-{

-    // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>

-    // of zero, if the active query object name for <target> is non-zero (for the

-    // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if

-    // the active query for either target is non-zero), if <id> is the name of an

-    // existing query object whose type does not match <target>, or if <id> is the

-    // active query object name for any query type, the error INVALID_OPERATION is

-    // generated.

-

-    // Ensure no other queries are active

-    // NOTE: If other queries than occlusion are supported, we will need to check

-    // separately that:

-    //    a) The query ID passed is not the current active query for any target/type

-    //    b) There are no active queries for the requested target (and in the case

-    //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,

-    //       no query may be active for either if glBeginQuery targets either.

-    for(int i = 0; i < QUERY_TYPE_COUNT; i++)

-    {

-        if(mState.activeQuery[i])

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-    }

-

-    QueryType qType;

-    switch(target)

-    {

-    case GL_ANY_SAMPLES_PASSED:

-        qType = QUERY_ANY_SAMPLES_PASSED;

-        break;

-    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;

-        break;

-    default:

-        ASSERT(false);

-    }

-

-    Query *queryObject = getQuery(query, true, target);

-

-    // Check that name was obtained with glGenQueries

-    if(!queryObject)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    // Check for type mismatch

-    if(queryObject->getType() != target)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    // Set query as active for specified target

-    mState.activeQuery[qType] = queryObject;

-

-    // Begin query

-    queryObject->begin();

-}

-

-void Context::endQuery(GLenum target)

-{

-    QueryType qType;

-

-    switch(target)

-    {

-    case GL_ANY_SAMPLES_PASSED:

-        qType = QUERY_ANY_SAMPLES_PASSED;

-        break;

-    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;

-        break;

-    default:

-        ASSERT(false);

-    }

-

-    Query *queryObject = mState.activeQuery[qType];

-

-    if(!queryObject)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    queryObject->end();

-

-    mState.activeQuery[qType] = nullptr;

-}

-

-void Context::setFramebufferZero(Framebuffer *buffer)

-{

-    delete mFramebufferNameSpace.remove(0);

-    mFramebufferNameSpace.insert(0, buffer);

-}

-

-void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)

-{

-    Renderbuffer *renderbufferObject = mState.renderbuffer;

-    renderbufferObject->setStorage(renderbuffer);

-}

-

-Framebuffer *Context::getFramebuffer(unsigned int handle)

-{

-    return mFramebufferNameSpace.find(handle);

-}

-

-Fence *Context::getFence(unsigned int handle)

-{

-    return mFenceNameSpace.find(handle);

-}

-

-Query *Context::getQuery(unsigned int handle, bool create, GLenum type)

-{

-    if(!mQueryNameSpace.isReserved(handle))

-    {

-        return nullptr;

-    }

-    else

-    {

-		Query *query = mQueryNameSpace.find(handle);

-        if(!query && create)

-        {

-            query = new Query(handle, type);

-            query->addRef();

-			mQueryNameSpace.insert(handle, query);

-        }

-

-        return query;

-    }

-}

-

-Buffer *Context::getArrayBuffer()

-{

-    return mState.arrayBuffer;

-}

-

-Buffer *Context::getElementArrayBuffer()

-{

-    return mState.elementArrayBuffer;

-}

-

-Program *Context::getCurrentProgram()

-{

-    return mResourceManager->getProgram(mState.currentProgram);

-}

-

-Texture2D *Context::getTexture2D(GLenum target)

-{

-    if(target == GL_TEXTURE_2D)

-    {

-        return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));

-    }

-    else if(target == GL_PROXY_TEXTURE_2D)

-    {

-        return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, PROXY_TEXTURE_2D));

-    }

-    else UNREACHABLE(target);

-

-    return 0;

-}

-

-TextureCubeMap *Context::getTextureCubeMap()

-{

-    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));

-}

-

-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)

-{

-    GLuint texid = mState.samplerTexture[type][sampler].name();

-

-    if(texid == 0)   // Special case: 0 refers to different initial textures based on the target

-    {

-        switch (type)

-        {

-        case TEXTURE_2D:       return mTexture2DZero;

-        case PROXY_TEXTURE_2D: return mProxyTexture2DZero;

-        case TEXTURE_CUBE:     return mTextureCubeMapZero;

-        default: UNREACHABLE(type);

-        }

-    }

-

-    return mState.samplerTexture[type][sampler];

-}

-

-bool Context::getBooleanv(GLenum pname, GLboolean *params)

-{

-    switch (pname)

-    {

-	case GL_SHADER_COMPILER:          *params = GL_TRUE;                             break;

-	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;

-	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;

-    case GL_COLOR_WRITEMASK:

-        params[0] = mState.colorMaskRed;

-        params[1] = mState.colorMaskGreen;

-        params[2] = mState.colorMaskBlue;

-        params[3] = mState.colorMaskAlpha;

-        break;

-    case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;

-    case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;

-    case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;

-    case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;

-    case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;

-    case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;

-    case GL_BLEND:                    *params = mState.blendEnabled;                 break;

-    case GL_DITHER:                   *params = mState.ditherEnabled;                break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getFloatv(GLenum pname, GLfloat *params)

-{

-    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application.

-    switch(pname)

-    {

-    case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;

-    case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;

-    case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;

-    case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;

-    case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-        params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;

-        params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;

-        break;

-    case GL_ALIASED_POINT_SIZE_RANGE:

-        params[0] = ALIASED_POINT_SIZE_RANGE_MIN;

-        params[1] = ALIASED_POINT_SIZE_RANGE_MAX;

-        break;

-    case GL_DEPTH_RANGE:

-        params[0] = mState.zNear;

-        params[1] = mState.zFar;

-        break;

-    case GL_COLOR_CLEAR_VALUE:

-        params[0] = mState.colorClearValue.red;

-        params[1] = mState.colorClearValue.green;

-        params[2] = mState.colorClearValue.blue;

-        params[3] = mState.colorClearValue.alpha;

-        break;

-    case GL_BLEND_COLOR:

-        params[0] = mState.blendColor.red;

-        params[1] = mState.blendColor.green;

-        params[2] = mState.blendColor.blue;

-        params[3] = mState.blendColor.alpha;

-        break;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-        *params = MAX_TEXTURE_MAX_ANISOTROPY;

-		break;

-	case GL_MODELVIEW_MATRIX:

-		for(int i = 0; i < 16; i++)

-		{

-			params[i] = modelView.current()[i % 4][i / 4];

-		}

-		break;

-	case GL_PROJECTION_MATRIX:

-		for(int i = 0; i < 16; i++)

-		{

-			params[i] = projection.current()[i % 4][i / 4];

-		}

-		break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getIntegerv(GLenum pname, GLint *params)

-{

-    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application. You may find it in

-    // Context::getFloatv.

-    switch (pname)

-    {

-    case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;

-    case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;

-    case GL_MAX_VERTEX_UNIFORM_COMPONENTS:    *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify

-    case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;

-    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;

-    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;

-    case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;

-	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;

-    case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:  *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify

-	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;

-    case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;

-    case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;

-    case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;

-//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE

-    case GL_DRAW_FRAMEBUFFER_BINDING:         *params = mState.drawFramebuffer;               break;

-    case GL_READ_FRAMEBUFFER_BINDING:         *params = mState.readFramebuffer;               break;

-    case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;

-    case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;

-    case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;

-    case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;

-    case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;

-    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:  *params = mState.fragmentShaderDerivativeHint; break;

-    case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;

-    case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;

-    case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;

-    case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;

-    case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;

-    case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;

-    case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.stencilBackMask;               break;

-    case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;

-    case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;

-    case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;

-    case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;

-    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;

-    case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;

-    case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;

-    case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;

-    case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;

-    case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;

-    case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;

-    case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;

-    case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;

-    case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;

-    case GL_STENCIL_BACK_WRITEMASK:           *params = mState.stencilBackWritemask;          break;

-    case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;

-    case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;

-	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;

-	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;

-    case GL_MAX_ARRAY_TEXTURE_LAYERS:         *params = 0;                                    break;

-	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;

-	case GL_MAX_SAMPLES:                      *params = IMPLEMENTATION_MAX_SAMPLES;           break;

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-			int width, height, samples;

-

-            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)

-            {

-                switch(pname)

-                {

-                case GL_SAMPLE_BUFFERS:

-                    if(samples > 1)

-                    {

-                        *params = 1;

-                    }

-                    else

-                    {

-                        *params = 0;

-                    }

-                    break;

-                case GL_SAMPLES:

-                    *params = samples;

-                    break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE:   *params = IMPLEMENTATION_COLOR_READ_TYPE;   break;

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;

-    case GL_MAX_VIEWPORT_DIMS:

-        {

-			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;

-            params[0] = maxDimension;

-            params[1] = maxDimension;

-        }

-        break;

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-        {

-			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)

-            {

-                params[i] = compressedTextureFormats[i];

-            }

-        }

-        break;

-    case GL_VIEWPORT:

-        params[0] = mState.viewportX;

-        params[1] = mState.viewportY;

-        params[2] = mState.viewportWidth;

-        params[3] = mState.viewportHeight;

-        break;

-    case GL_SCISSOR_BOX:

-        params[0] = mState.scissorX;

-        params[1] = mState.scissorY;

-        params[2] = mState.scissorWidth;

-        params[3] = mState.scissorHeight;

-        break;

-    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;

-    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-            Renderbuffer *colorbuffer = framebuffer->getColorbuffer();

-

-            if(colorbuffer)

-            {

-                switch (pname)

-                {

-                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;

-                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;

-                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;

-                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_DEPTH_BITS:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-

-            if(depthbuffer)

-            {

-                *params = depthbuffer->getDepthSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_STENCIL_BITS:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-

-            if(stencilbuffer)

-            {

-                *params = stencilbuffer->getStencilSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_TEXTURE_BINDING_2D:

-        {

-            if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-            {

-                error(GL_INVALID_OPERATION);

-                return false;

-            }

-

-            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();

-        }

-        break;

-    case GL_TEXTURE_BINDING_CUBE_MAP:

-        {

-            if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-            {

-                error(GL_INVALID_OPERATION);

-                return false;

-            }

-

-            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();

-        }

-        break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-		{

-            *type = GL_INT;

-			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;

-        }

-		break;

-    case GL_SHADER_BINARY_FORMATS:

-        {

-            *type = GL_INT;

-            *numParams = 0;

-        }

-        break;

-    case GL_MAX_VERTEX_ATTRIBS:

-    case GL_MAX_VERTEX_UNIFORM_VECTORS:

-    case GL_MAX_VARYING_VECTORS:

-    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:

-    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:

-    case GL_MAX_TEXTURE_IMAGE_UNITS:

-    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:

-    case GL_MAX_RENDERBUFFER_SIZE:

-    case GL_NUM_SHADER_BINARY_FORMATS:

-    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:

-    case GL_ARRAY_BUFFER_BINDING:

-    case GL_FRAMEBUFFER_BINDING:

-    case GL_RENDERBUFFER_BINDING:

-    case GL_CURRENT_PROGRAM:

-    case GL_PACK_ALIGNMENT:

-    case GL_UNPACK_ALIGNMENT:

-    case GL_GENERATE_MIPMAP_HINT:

-    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-    case GL_DEPTH_BITS:

-    case GL_STENCIL_BITS:

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:

-    case GL_CULL_FACE_MODE:

-    case GL_FRONT_FACE:

-    case GL_ACTIVE_TEXTURE:

-    case GL_STENCIL_FUNC:

-    case GL_STENCIL_VALUE_MASK:

-    case GL_STENCIL_REF:

-    case GL_STENCIL_FAIL:

-    case GL_STENCIL_PASS_DEPTH_FAIL:

-    case GL_STENCIL_PASS_DEPTH_PASS:

-    case GL_STENCIL_BACK_FUNC:

-    case GL_STENCIL_BACK_VALUE_MASK:

-    case GL_STENCIL_BACK_REF:

-    case GL_STENCIL_BACK_FAIL:

-    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:

-    case GL_STENCIL_BACK_PASS_DEPTH_PASS:

-    case GL_DEPTH_FUNC:

-    case GL_BLEND_SRC_RGB:

-    case GL_BLEND_SRC_ALPHA:

-    case GL_BLEND_DST_RGB:

-    case GL_BLEND_DST_ALPHA:

-    case GL_BLEND_EQUATION_RGB:

-    case GL_BLEND_EQUATION_ALPHA:

-    case GL_STENCIL_WRITEMASK:

-    case GL_STENCIL_BACK_WRITEMASK:

-    case GL_STENCIL_CLEAR_VALUE:

-    case GL_SUBPIXEL_BITS:

-    case GL_MAX_TEXTURE_SIZE:

-    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE:

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT:

-    case GL_TEXTURE_BINDING_2D:

-    case GL_TEXTURE_BINDING_CUBE_MAP:

-    case GL_MAX_VERTEX_UNIFORM_COMPONENTS:

-    case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:

-    case GL_MAX_ARRAY_TEXTURE_LAYERS:

-        {

-            *type = GL_INT;

-            *numParams = 1;

-        }

-        break;

-    case GL_MAX_SAMPLES:

-        {

-            *type = GL_INT;

-            *numParams = 1;

-        }

-        break;

-    case GL_MAX_VIEWPORT_DIMS:

-        {

-            *type = GL_INT;

-            *numParams = 2;

-        }

-        break;

-    case GL_VIEWPORT:

-    case GL_SCISSOR_BOX:

-        {

-            *type = GL_INT;

-            *numParams = 4;

-        }

-        break;

-    case GL_SHADER_COMPILER:

-    case GL_SAMPLE_COVERAGE_INVERT:

-    case GL_DEPTH_WRITEMASK:

-    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,

-    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural

-    case GL_SAMPLE_COVERAGE:

-    case GL_SCISSOR_TEST:

-    case GL_STENCIL_TEST:

-    case GL_DEPTH_TEST:

-    case GL_BLEND:

-    case GL_DITHER:

-        {

-            *type = GL_BOOL;

-            *numParams = 1;

-        }

-        break;

-    case GL_COLOR_WRITEMASK:

-        {

-            *type = GL_BOOL;

-            *numParams = 4;

-        }

-        break;

-    case GL_POLYGON_OFFSET_FACTOR:

-    case GL_POLYGON_OFFSET_UNITS:

-    case GL_SAMPLE_COVERAGE_VALUE:

-    case GL_DEPTH_CLEAR_VALUE:

-    case GL_LINE_WIDTH:

-        {

-            *type = GL_FLOAT;

-            *numParams = 1;

-        }

-        break;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-    case GL_ALIASED_POINT_SIZE_RANGE:

-    case GL_DEPTH_RANGE:

-        {

-            *type = GL_FLOAT;

-            *numParams = 2;

-        }

-        break;

-    case GL_COLOR_CLEAR_VALUE:

-    case GL_BLEND_COLOR:

-        {

-            *type = GL_FLOAT;

-            *numParams = 4;

-        }

-        break;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-        *type = GL_FLOAT;

-        *numParams = 1;

-        break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle

-bool Context::applyRenderTarget()

-{

-    Framebuffer *framebuffer = getDrawFramebuffer();

-	int width, height, samples;

-

-    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);

-    }

-

-    Image *renderTarget = framebuffer->getRenderTarget();

-	device->setRenderTarget(0, renderTarget);

-	if(renderTarget) renderTarget->release();

-

-    Image *depthStencil = framebuffer->getDepthStencil();

-    device->setDepthStencilSurface(depthStencil);

-	if(depthStencil) depthStencil->release();

-

-    Viewport viewport;

-    float zNear = clamp01(mState.zNear);

-    float zFar = clamp01(mState.zFar);

-

-    viewport.x0 = mState.viewportX;

-    viewport.y0 = mState.viewportY;

-    viewport.width = mState.viewportWidth;

-    viewport.height = mState.viewportHeight;

-    viewport.minZ = zNear;

-    viewport.maxZ = zFar;

-

-    device->setViewport(viewport);

-

-    if(mState.scissorTestEnabled)

-    {

-		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};

-		scissor.clip(0, 0, width, height);

-

-		device->setScissorRect(scissor);

-        device->setScissorEnable(true);

-    }

-    else

-    {

-        device->setScissorEnable(false);

-    }

-

-	Program *program = getCurrentProgram();

-

-	if(program)

-	{

-		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};

-        program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);

-		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);

-		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);

-    }

-

-    return true;

-}

-

-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)

-void Context::applyState(GLenum drawMode)

-{

-    Framebuffer *framebuffer = getDrawFramebuffer();

-

-    if(mState.cullFaceEnabled)

-    {

-        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));

-    }

-    else

-    {

-		device->setCullMode(sw::CULL_NONE);

-    }

-

-    if(mDepthStateDirty)

-    {

-        if(mState.depthTestEnabled)

-        {

-			device->setDepthBufferEnable(true);

-			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));

-        }

-        else

-        {

-            device->setDepthBufferEnable(false);

-        }

-

-        mDepthStateDirty = false;

-    }

-

-    if(mBlendStateDirty)

-    {

-        if(mState.blendEnabled)

-        {

-			device->setAlphaBlendEnable(true);

-			device->setSeparateAlphaBlendEnable(true);

-

-            device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));

-

-			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));

-			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));

-			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));

-

-            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));

-			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));

-			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));

-        }

-        else

-        {

-			device->setAlphaBlendEnable(false);

-        }

-

-        mBlendStateDirty = false;

-    }

-

-	if(mColorLogicOperatorDirty)

-	{

-		if(mState.colorLogicOpEnabled)

-		{

-			device->setColorLogicOpEnabled(true);

-			device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation));

-		}

-		else

-		{

-			device->setColorLogicOpEnabled(false);

-		}

-

-		mColorLogicOperatorDirty = false;

-	}

-

-    if(mStencilStateDirty || mFrontFaceDirty)

-    {

-        if(mState.stencilTestEnabled && framebuffer->hasStencil())

-        {

-			device->setStencilEnable(true);

-			device->setTwoSidedStencil(true);

-

-            if(mState.stencilWritemask != mState.stencilBackWritemask ||

-               mState.stencilRef != mState.stencilBackRef ||

-               mState.stencilMask != mState.stencilBackMask)

-            {

-				ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");

-                return error(GL_INVALID_OPERATION);

-            }

-

-            // get the maximum size of the stencil ref

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;

-

-			if(mState.frontFace == GL_CCW)

-			{

-				device->setStencilWriteMask(mState.stencilWritemask);

-				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-				device->setStencilMask(mState.stencilMask);

-

-				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));

-				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-

-				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);

-				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));

-

-				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);

-				device->setStencilMaskCCW(mState.stencilBackMask);

-

-				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));

-				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));

-				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));

-			}

-			else

-			{

-				device->setStencilWriteMaskCCW(mState.stencilWritemask);

-				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-				device->setStencilMaskCCW(mState.stencilMask);

-

-				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));

-				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-

-				device->setStencilWriteMask(mState.stencilBackWritemask);

-				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));

-

-				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);

-				device->setStencilMask(mState.stencilBackMask);

-

-				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));

-				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));

-				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));

-			}

-        }

-        else

-        {

-			device->setStencilEnable(false);

-        }

-

-        mStencilStateDirty = false;

-        mFrontFaceDirty = false;

-    }

-

-    if(mMaskStateDirty)

-    {

-		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));

-		device->setDepthWriteEnable(mState.depthMask);

-

-        mMaskStateDirty = false;

-    }

-

-    if(mPolygonOffsetStateDirty)

-    {

-        if(mState.polygonOffsetFillEnabled)

-        {

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-            if(depthbuffer)

-            {

-				device->setSlopeDepthBias(mState.polygonOffsetFactor);

-                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));

-				device->setDepthBias(depthBias);

-            }

-        }

-        else

-        {

-            device->setSlopeDepthBias(0);

-            device->setDepthBias(0);

-        }

-

-        mPolygonOffsetStateDirty = false;

-    }

-

-    if(mSampleStateDirty)

-    {

-        if(mState.sampleAlphaToCoverageEnabled)

-        {

-            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);

-        }

-		else

-		{

-			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);

-		}

-

-        if(mState.sampleCoverageEnabled)

-        {

-            unsigned int mask = 0;

-            if(mState.sampleCoverageValue != 0)

-            {

-				int width, height, samples;

-				framebuffer->completeness(width, height, samples);

-

-                float threshold = 0.5f;

-

-                for(int i = 0; i < samples; i++)

-                {

-                    mask <<= 1;

-

-                    if((i + 1) * mState.sampleCoverageValue >= threshold)

-                    {

-                        threshold += 1.0f;

-                        mask |= 1;

-                    }

-                }

-            }

-

-            if(mState.sampleCoverageInvert)

-            {

-                mask = ~mask;

-            }

-

-			device->setMultiSampleMask(mask);

-        }

-        else

-        {

-			device->setMultiSampleMask(0xFFFFFFFF);

-        }

-

-        mSampleStateDirty = false;

-    }

-

-    if(mDitherStateDirty)

-    {

-    //	UNIMPLEMENTED();   // FIXME

-

-        mDitherStateDirty = false;

-    }

-}

-

-GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)

-{

-    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];

-

-    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);

-    if(err != GL_NO_ERROR)

-    {

-        return err;

-    }

-

-	Program *program = getCurrentProgram();

-

-	device->resetInputStreams(false);

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-	{

-		if(program && program->getAttributeStream(i) == -1)

-		{

-			continue;

-		}

-

-		sw::Resource *resource = attributes[i].vertexBuffer;

-		const void *buffer = (char*)resource->data() + attributes[i].offset;

-

-		int stride = attributes[i].stride;

-

-		buffer = (char*)buffer + stride * base;

-

-		sw::Stream attribute(resource, buffer, stride);

-

-		attribute.type = attributes[i].type;

-		attribute.count = attributes[i].count;

-		attribute.normalized = attributes[i].normalized;

-

-		int stream = program ? program->getAttributeStream(i) : i;

-		device->setInputStream(stream, attribute);

-	}

-

-	return GL_NO_ERROR;

-}

-

-// Applies the indices and element array bindings

-GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)

-{

-    GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);

-

-    if(err == GL_NO_ERROR)

-    {

-        device->setIndexBuffer(indexInfo->indexBuffer);

-    }

-

-    return err;

-}

-

-// Applies the shaders and shader constants

-void Context::applyShaders()

-{

-    Program *programObject = getCurrentProgram();

-    if(!programObject)

-    {

-        device->setVertexShader(0);

-        device->setPixelShader(0);

-        return;

-    }

-    sw::VertexShader *vertexShader = programObject->getVertexShader();

-	sw::PixelShader *pixelShader = programObject->getPixelShader();

-

-    device->setVertexShader(vertexShader);

-    device->setPixelShader(pixelShader);

-

-    if(programObject->getSerial() != mAppliedProgramSerial)

-    {

-        programObject->dirtyAllUniforms();

-        mAppliedProgramSerial = programObject->getSerial();

-    }

-

-    programObject->applyUniforms();

-}

-

-void Context::applyTextures()

-{

-    applyTextures(sw::SAMPLER_PIXEL);

-	//applyTextures(sw::SAMPLER_VERTEX);

-}

-

-void Context::applyTextures(sw::SamplerType samplerType)

-{

-    Program *programObject = getCurrentProgram();

-

-    int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type

-

-    for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)

-    {

-        int textureUnit = programObject ? programObject->getSamplerMapping(samplerType, samplerIndex) : samplerIndex;   // OpenGL texture image unit index

-

-        if(textureUnit != -1)

-        {

-            TextureType textureType = programObject ? programObject->getSamplerTextureType(samplerType, samplerIndex) : TEXTURE_2D;

-

-            Texture *texture = getSamplerTexture(textureUnit, textureType);

-

-			if(envEnable[samplerIndex] && texture->isSamplerComplete())

-            {

-                GLenum wrapS = texture->getWrapS();

-                GLenum wrapT = texture->getWrapT();

-                GLenum minFilter = texture->getMinFilter();

-                GLenum magFilter = texture->getMagFilter();

-				GLfloat maxAnisotropy = texture->getMaxAnisotropy();

-

-				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));

-                device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));

-

-				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));

-				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));

-				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);

-

-				applyTexture(samplerType, samplerIndex, texture);

-

-                device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE);

-                device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);

-                device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);

-		        //device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);

-

-                device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE);

-                device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);

-                device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);

-		        //device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);

-

-		        //device->setConstantColor(0, sw::Color<float>(0.0f, 0.0f, 0.0f, 0.0f));

-            }

-            else

-            {

-                applyTexture(samplerType, samplerIndex, nullptr);

-

-                device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);

-                device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);

-                device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);

-		        //device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);

-

-                device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);

-                device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);

-                device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);

-		        //device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);

-            }

-        }

-        else

-        {

-            applyTexture(samplerType, samplerIndex, nullptr);

-        }

-    }

-}

-

-void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)

-{

-	Program *program = getCurrentProgram();

-	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;

-	bool textureUsed = false;

-

-	if(type == sw::SAMPLER_PIXEL)

-	{

-		textureUsed = program ? program->getPixelShader()->usesSampler(index) : true;

-	}

-	else if(type == sw::SAMPLER_VERTEX)

-	{

-		textureUsed = program ? program->getVertexShader()->usesSampler(index) : false;

-	}

-	else UNREACHABLE(type);

-

-	sw::Resource *resource = 0;

-

-	if(baseTexture && textureUsed)

-	{

-		resource = baseTexture->getResource();

-	}

-

-	device->setTextureResource(sampler, resource);

-

-	if(baseTexture && textureUsed)

-	{

-		int levelCount = baseTexture->getLevelCount();

-

-		if(baseTexture->getTarget() == GL_TEXTURE_2D)

-		{

-			Texture2D *texture = static_cast<Texture2D*>(baseTexture);

-

-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-			{

-				int surfaceLevel = mipmapLevel;

-

-				if(surfaceLevel < 0)

-				{

-					surfaceLevel = 0;

-				}

-				else if(surfaceLevel >= levelCount)

-				{

-					surfaceLevel = levelCount - 1;

-				}

-

-				Image *surface = texture->getImage(surfaceLevel);

-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);

-			}

-		}

-		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)

-		{

-			for(int face = 0; face < 6; face++)

-			{

-				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);

-

-				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-				{

-					int surfaceLevel = mipmapLevel;

-

-					if(surfaceLevel < 0)

-					{

-						surfaceLevel = 0;

-					}

-					else if(surfaceLevel >= levelCount)

-					{

-						surfaceLevel = levelCount - 1;

-					}

-

-					Image *surface = cubeTexture->getImage(face, surfaceLevel);

-					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);

-				}

-			}

-		}

-		else UNIMPLEMENTED();

-	}

-	else

-	{

-		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);

-	}

-}

-

-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,

-                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)

-{

-    Framebuffer *framebuffer = getReadFramebuffer();

-	int framebufferWidth, framebufferHeight, framebufferSamples;

-

-    if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-    }

-

-    if(getReadFramebufferName() != 0 && framebufferSamples != 0)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);

-

-	// Sized query sanity check

-    if(bufSize)

-    {

-        int requiredSize = outputPitch * height;

-        if(requiredSize > *bufSize)

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-    }

-

-    Image *renderTarget = framebuffer->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	sw::Rect rect = {x, y, x + width, y + height};

-	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

-

-    unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);

-    unsigned char *dest = (unsigned char*)pixels;

-    unsigned short *dest16 = (unsigned short*)pixels;

-    int inputPitch = (int)renderTarget->getPitch();

-

-    for(int j = 0; j < rect.y1 - rect.y0; j++)

-    {

-        if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&

-           format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)

-        {

-            // Fast path for EXT_read_format_bgra, given an RGBA source buffer

-			// Note that buffers with no alpha go through the slow path below

-            memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);

-        }

-		else

-		{

-			for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				float r;

-				float g;

-				float b;

-				float a;

-

-				switch(renderTarget->getInternalFormat())

-				{

-				case sw::FORMAT_R5G6B5:

-					{

-						unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);

-

-						a = 1.0f;

-						b = (rgb & 0x001F) * (1.0f / 0x001F);

-						g = (rgb & 0x07E0) * (1.0f / 0x07E0);

-						r = (rgb & 0xF800) * (1.0f / 0xF800);

-					}

-					break;

-				case sw::FORMAT_A1R5G5B5:

-					{

-						unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);

-

-						a = (argb & 0x8000) ? 1.0f : 0.0f;

-						b = (argb & 0x001F) * (1.0f / 0x001F);

-						g = (argb & 0x03E0) * (1.0f / 0x03E0);

-						r = (argb & 0x7C00) * (1.0f / 0x7C00);

-					}

-					break;

-				case sw::FORMAT_A8R8G8B8:

-					{

-						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);

-

-						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);

-						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);

-						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);

-					}

-					break;

-				case sw::FORMAT_X8R8G8B8:

-					{

-						unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);

-

-						a = 1.0f;

-						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);

-						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);

-					}

-					break;

-				case sw::FORMAT_A2R10G10B10:

-					{

-						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);

-

-						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);

-						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);

-						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);

-						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);

-					}

-					break;

-				case sw::FORMAT_A32B32G32R32F:

-					{

-						r = *((float*)(source + 16 * i + j * inputPitch) + 0);

-						g = *((float*)(source + 16 * i + j * inputPitch) + 1);

-						b = *((float*)(source + 16 * i + j * inputPitch) + 2);

-						a = *((float*)(source + 16 * i + j * inputPitch) + 3);

-					}

-					break;

-				case sw::FORMAT_A16B16G16R16F:

-					{

-						r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);

-						g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);

-						b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);

-						a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);

-					}

-					break;

-				default:

-					UNIMPLEMENTED();   // FIXME

-					UNREACHABLE(renderTarget->getInternalFormat());

-				}

-

-				switch(format)

-				{

-				case GL_RGBA:

-					switch(type)

-					{

-					case GL_UNSIGNED_BYTE:

-						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);

-						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);

-						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);

-						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				case GL_BGRA_EXT:

-					switch(type)

-					{

-					case GL_UNSIGNED_BYTE:

-						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);

-						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);

-						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);

-						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);

-						break;

-					case GL_UNSIGNED_SHORT_4_4_4_4_REV:

-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section

-						// this type is packed as follows:

-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0

-						//  --------------------------------------------------------------------------------

-						// |       4th         |        3rd         |        2nd        |   1st component   |

-						//  --------------------------------------------------------------------------------

-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.

-						dest16[i + j * outputPitch / sizeof(unsigned short)] =

-							((unsigned short)(15 * a + 0.5f) << 12)|

-							((unsigned short)(15 * r + 0.5f) << 8) |

-							((unsigned short)(15 * g + 0.5f) << 4) |

-							((unsigned short)(15 * b + 0.5f) << 0);

-						break;

-					case GL_UNSIGNED_SHORT_1_5_5_5_REV:

-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section

-						// this type is packed as follows:

-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0

-						//  --------------------------------------------------------------------------------

-						// | 4th |          3rd           |           2nd          |      1st component     |

-						//  --------------------------------------------------------------------------------

-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.

-						dest16[i + j * outputPitch / sizeof(unsigned short)] =

-							((unsigned short)(     a + 0.5f) << 15) |

-							((unsigned short)(31 * r + 0.5f) << 10) |

-							((unsigned short)(31 * g + 0.5f) << 5) |

-							((unsigned short)(31 * b + 0.5f) << 0);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				case GL_RGB:   // IMPLEMENTATION_COLOR_READ_FORMAT

-					switch(type)

-					{

-					case GL_UNSIGNED_SHORT_5_6_5:   // IMPLEMENTATION_COLOR_READ_TYPE

-						dest16[i + j * outputPitch / sizeof(unsigned short)] =

-							((unsigned short)(31 * b + 0.5f) << 0) |

-							((unsigned short)(63 * g + 0.5f) << 5) |

-							((unsigned short)(31 * r + 0.5f) << 11);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				default: UNREACHABLE(format);

-				}

-			}

-        }

-    }

-

-	renderTarget->unlock();

-	renderTarget->release();

-}

-

-void Context::clear(GLbitfield mask)

-{

-    Framebuffer *framebuffer = getDrawFramebuffer();

-

-    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    float depth = clamp01(mState.depthClearValue);

-    int stencil = mState.stencilClearValue & 0x000000FF;

-

-	if(mask & GL_COLOR_BUFFER_BIT)

-	{

-		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |

-		                        (mState.colorMaskGreen ? 0x2 : 0) |

-		                        (mState.colorMaskBlue ? 0x4 : 0) |

-		                        (mState.colorMaskAlpha ? 0x8 : 0);

-

-		if(rgbaMask != 0)

-		{

-			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);

-		}

-	}

-

-	if(mask & GL_DEPTH_BUFFER_BIT)

-	{

-		if(mState.depthMask != 0)

-		{

-			device->clearDepth(depth);

-		}

-	}

-

-	if(mask & GL_STENCIL_BUFFER_BIT)

-	{

-		if(mState.stencilWritemask != 0)

-		{

-			device->clearStencil(stencil, mState.stencilWritemask);

-		}

-	}

-}

-

-void Context::drawArrays(GLenum mode, GLint first, GLsizei count)

-{

-    if(!mState.currentProgram)

-    {

-        //return;// error(GL_INVALID_OPERATION);

-

-		const sw::Matrix Z(1, 0, 0, 0,

-	                       0, 1, 0, 0,

-	                       0, 0, 0.5, 0.5,

-	                       0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]

-

-        device->setProjectionMatrix(Z * projection.current());

-        device->setViewMatrix(modelView.current());

-		device->setTextureMatrix(0, texture[0].current());

-		device->setTextureMatrix(1, texture[1].current());

-		device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);

-		device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);

-		device->setTexGen(0, sw::TEXGEN_NONE);

-		device->setTexGen(1, sw::TEXGEN_NONE);

-    }

-

-    PrimitiveType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-    GLenum err = applyVertexBuffer(0, first, count);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    applyShaders();

-    applyTextures();

-

-    if(getCurrentProgram() && !getCurrentProgram()->validateSamplers(false))

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(!cullSkipsDraw(mode))

-    {

-        device->drawPrimitive(primitiveType, primitiveCount);

-    }

-}

-

-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)

-{

-    if(!mState.currentProgram)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(!indices && !mState.elementArrayBuffer)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    PrimitiveType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-    TranslatedIndexData indexInfo;

-    GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;

-    err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    applyShaders();

-    applyTextures();

-

-    if(!getCurrentProgram()->validateSamplers(false))

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(!cullSkipsDraw(mode))

-    {

-		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));

-    }

-}

-

-void Context::finish()

-{

-	device->finish();

-}

-

-void Context::flush()

-{

-    // We don't queue anything without processing it as fast as possible

-}

-

-void Context::recordInvalidEnum()

-{

-    mInvalidEnum = true;

-}

-

-void Context::recordInvalidValue()

-{

-    mInvalidValue = true;

-}

-

-void Context::recordInvalidOperation()

-{

-    mInvalidOperation = true;

-}

-

-void Context::recordOutOfMemory()

-{

-    mOutOfMemory = true;

-}

-

-void Context::recordInvalidFramebufferOperation()

-{

-    mInvalidFramebufferOperation = true;

-}

-

-// Get one of the recorded errors and clear its flag, if any.

-GLenum Context::getError()

-{

-    if(mInvalidEnum)

-    {

-        mInvalidEnum = false;

-

-        return GL_INVALID_ENUM;

-    }

-

-    if(mInvalidValue)

-    {

-        mInvalidValue = false;

-

-        return GL_INVALID_VALUE;

-    }

-

-    if(mInvalidOperation)

-    {

-        mInvalidOperation = false;

-

-        return GL_INVALID_OPERATION;

-    }

-

-    if(mOutOfMemory)

-    {

-        mOutOfMemory = false;

-

-        return GL_OUT_OF_MEMORY;

-    }

-

-    if(mInvalidFramebufferOperation)

-    {

-        mInvalidFramebufferOperation = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION;

-    }

-

-    return GL_NO_ERROR;

-}

-

-int Context::getSupportedMultisampleCount(int requested)

-{

-	int supported = 0;

-

-	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)

-	{

-		if(supported >= requested)

-		{

-			return supported;

-		}

-

-		supported = multisampleCount[i];

-	}

-

-	return supported;

-}

-

-void Context::detachBuffer(GLuint buffer)

-{

-    // If a buffer object is deleted while it is bound, all bindings to that object in the current context

-    // (i.e. in the thread that called Delete-Buffers) are reset to zero.

-

-    if(mState.arrayBuffer.name() == buffer)

-    {

-        mState.arrayBuffer = nullptr;

-    }

-

-    if(mState.elementArrayBuffer.name() == buffer)

-    {

-        mState.elementArrayBuffer = nullptr;

-    }

-

-    for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)

-    {

-        if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)

-        {

-            mState.vertexAttribute[attribute].mBoundBuffer = nullptr;

-        }

-    }

-}

-

-void Context::detachTexture(GLuint texture)

-{

-    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are

-    // rebound to texture object zero

-

-    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-    {

-        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)

-        {

-            if(mState.samplerTexture[type][sampler].name() == texture)

-            {

-                mState.samplerTexture[type][sampler] = nullptr;

-            }

-        }

-    }

-

-    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is

-    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this

-    // image was attached in the currently bound framebuffer.

-

-    Framebuffer *readFramebuffer = getReadFramebuffer();

-    Framebuffer *drawFramebuffer = getDrawFramebuffer();

-

-    if(readFramebuffer)

-    {

-        readFramebuffer->detachTexture(texture);

-    }

-

-    if(drawFramebuffer && drawFramebuffer != readFramebuffer)

-    {

-        drawFramebuffer->detachTexture(texture);

-    }

-}

-

-void Context::detachFramebuffer(GLuint framebuffer)

-{

-    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though

-    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.

-

-    if(mState.readFramebuffer == framebuffer)

-    {

-        bindReadFramebuffer(0);

-    }

-

-    if(mState.drawFramebuffer == framebuffer)

-    {

-        bindDrawFramebuffer(0);

-    }

-}

-

-void Context::detachRenderbuffer(GLuint renderbuffer)

-{

-    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer

-    // had been executed with the target RENDERBUFFER and name of zero.

-

-    if(mState.renderbuffer.name() == renderbuffer)

-    {

-        bindRenderbuffer(0);

-    }

-

-    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,

-    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment

-    // point to which this image was attached in the currently bound framebuffer.

-

-    Framebuffer *readFramebuffer = getReadFramebuffer();

-    Framebuffer *drawFramebuffer = getDrawFramebuffer();

-

-    if(readFramebuffer)

-    {

-        readFramebuffer->detachRenderbuffer(renderbuffer);

-    }

-

-    if(drawFramebuffer && drawFramebuffer != readFramebuffer)

-    {

-        drawFramebuffer->detachRenderbuffer(renderbuffer);

-    }

-}

-

-bool Context::cullSkipsDraw(GLenum drawMode)

-{

-    return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);

-}

-

-bool Context::isTriangleMode(GLenum drawMode)

-{

-    switch (drawMode)

-    {

-      case GL_TRIANGLES:

-      case GL_TRIANGLE_FAN:

-      case GL_TRIANGLE_STRIP:

-        return true;

-      case GL_POINTS:

-      case GL_LINES:

-      case GL_LINE_LOOP:

-      case GL_LINE_STRIP:

-        return false;

-      default: UNREACHABLE(drawMode);

-    }

-

-    return false;

-}

-

-void Context::setVertexAttrib(GLuint index, float x, float y, float z, float w)

-{

-    ASSERT(index < MAX_VERTEX_ATTRIBS);

-

-    mState.vertexAttribute[index].mCurrentValue[0] = x;

-    mState.vertexAttribute[index].mCurrentValue[1] = y;

-    mState.vertexAttribute[index].mCurrentValue[2] = z;

-    mState.vertexAttribute[index].mCurrentValue[3] = w;

-

-    mVertexDataManager->dirtyCurrentValue(index);

-}

-

-void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,

-                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                              GLbitfield mask)

-{

-    Framebuffer *readFramebuffer = getReadFramebuffer();

-    Framebuffer *drawFramebuffer = getDrawFramebuffer();

-

-	int readBufferWidth, readBufferHeight, readBufferSamples;

-    int drawBufferWidth, drawBufferHeight, drawBufferSamples;

-

-    if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||

-       !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-    }

-

-    if(drawBufferSamples > 1)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    sw::SliceRect sourceRect;

-    sw::SliceRect destRect;

-

-    if(srcX0 < srcX1)

-    {

-        sourceRect.x0 = srcX0;

-        sourceRect.x1 = srcX1;

-        destRect.x0 = dstX0;

-        destRect.x1 = dstX1;

-    }

-    else

-    {

-        sourceRect.x0 = srcX1;

-        destRect.x0 = dstX1;

-        sourceRect.x1 = srcX0;

-        destRect.x1 = dstX0;

-    }

-

-    if(srcY0 < srcY1)

-    {

-        sourceRect.y0 = srcY0;

-        destRect.y0 = dstY0;

-        sourceRect.y1 = srcY1;

-        destRect.y1 = dstY1;

-    }

-    else

-    {

-        sourceRect.y0 = srcY1;

-        destRect.y0 = dstY1;

-        sourceRect.y1 = srcY0;

-        destRect.y1 = dstY0;

-    }

-

-    sw::Rect sourceScissoredRect = sourceRect;

-    sw::Rect destScissoredRect = destRect;

-

-    if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test

-    {

-        if(destRect.x0 < mState.scissorX)

-        {

-            int xDiff = mState.scissorX - destRect.x0;

-            destScissoredRect.x0 = mState.scissorX;

-            sourceScissoredRect.x0 += xDiff;

-        }

-

-        if(destRect.x1 > mState.scissorX + mState.scissorWidth)

-        {

-            int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);

-            destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;

-            sourceScissoredRect.x1 -= xDiff;

-        }

-

-        if(destRect.y0 < mState.scissorY)

-        {

-            int yDiff = mState.scissorY - destRect.y0;

-            destScissoredRect.y0 = mState.scissorY;

-            sourceScissoredRect.y0 += yDiff;

-        }

-

-        if(destRect.y1 > mState.scissorY + mState.scissorHeight)

-        {

-            int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);

-            destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;

-            sourceScissoredRect.y1 -= yDiff;

-        }

-    }

-

-    sw::Rect sourceTrimmedRect = sourceScissoredRect;

-    sw::Rect destTrimmedRect = destScissoredRect;

-

-    // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of

-    // the actual draw and read surfaces.

-    if(sourceTrimmedRect.x0 < 0)

-    {

-        int xDiff = 0 - sourceTrimmedRect.x0;

-        sourceTrimmedRect.x0 = 0;

-        destTrimmedRect.x0 += xDiff;

-    }

-

-    if(sourceTrimmedRect.x1 > readBufferWidth)

-    {

-        int xDiff = sourceTrimmedRect.x1 - readBufferWidth;

-        sourceTrimmedRect.x1 = readBufferWidth;

-        destTrimmedRect.x1 -= xDiff;

-    }

-

-    if(sourceTrimmedRect.y0 < 0)

-    {

-        int yDiff = 0 - sourceTrimmedRect.y0;

-        sourceTrimmedRect.y0 = 0;

-        destTrimmedRect.y0 += yDiff;

-    }

-

-    if(sourceTrimmedRect.y1 > readBufferHeight)

-    {

-        int yDiff = sourceTrimmedRect.y1 - readBufferHeight;

-        sourceTrimmedRect.y1 = readBufferHeight;

-        destTrimmedRect.y1 -= yDiff;

-    }

-

-    if(destTrimmedRect.x0 < 0)

-    {

-        int xDiff = 0 - destTrimmedRect.x0;

-        destTrimmedRect.x0 = 0;

-        sourceTrimmedRect.x0 += xDiff;

-    }

-

-    if(destTrimmedRect.x1 > drawBufferWidth)

-    {

-        int xDiff = destTrimmedRect.x1 - drawBufferWidth;

-        destTrimmedRect.x1 = drawBufferWidth;

-        sourceTrimmedRect.x1 -= xDiff;

-    }

-

-    if(destTrimmedRect.y0 < 0)

-    {

-        int yDiff = 0 - destTrimmedRect.y0;

-        destTrimmedRect.y0 = 0;

-        sourceTrimmedRect.y0 += yDiff;

-    }

-

-    if(destTrimmedRect.y1 > drawBufferHeight)

-    {

-        int yDiff = destTrimmedRect.y1 - drawBufferHeight;

-        destTrimmedRect.y1 = drawBufferHeight;

-        sourceTrimmedRect.y1 -= yDiff;

-    }

-

-    bool partialBufferCopy = false;

-

-    if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||

-       sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||

-       destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||

-       destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||

-       sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)

-    {

-        partialBufferCopy = true;

-    }

-

-	bool blitRenderTarget = false;

-    bool blitDepthStencil = false;

-

-    if(mask & GL_COLOR_BUFFER_BIT)

-    {

-        const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||

-                                   readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;

-        const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||

-                                   drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;

-        if(!validReadType || !validDrawType ||

-           readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())

-        {

-            ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");

-            return error(GL_INVALID_OPERATION);

-        }

-

-        if(partialBufferCopy && readBufferSamples > 1)

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-

-        blitRenderTarget = true;

-    }

-

-    if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))

-    {

-        Renderbuffer *readDSBuffer = nullptr;

-        Renderbuffer *drawDSBuffer = nullptr;

-

-        // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have

-        // both a depth and stencil buffer, it will be the same buffer.

-

-        if(mask & GL_DEPTH_BUFFER_BIT)

-        {

-            if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())

-            {

-                if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||

-                   readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())

-                {

-                    return error(GL_INVALID_OPERATION);

-                }

-

-                blitDepthStencil = true;

-                readDSBuffer = readFramebuffer->getDepthbuffer();

-                drawDSBuffer = drawFramebuffer->getDepthbuffer();

-            }

-        }

-

-        if(mask & GL_STENCIL_BUFFER_BIT)

-        {

-            if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())

-            {

-                if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||

-                   readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())

-                {

-                    return error(GL_INVALID_OPERATION);

-                }

-

-                blitDepthStencil = true;

-                readDSBuffer = readFramebuffer->getStencilbuffer();

-                drawDSBuffer = drawFramebuffer->getStencilbuffer();

-            }

-        }

-

-        if(partialBufferCopy)

-        {

-            ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");

-            return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted

-        }

-

-        if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||

-           (readDSBuffer && readDSBuffer->getSamples() > 1))

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-    }

-

-    if(blitRenderTarget || blitDepthStencil)

-    {

-        if(blitRenderTarget)

-        {

-            Image *readRenderTarget = readFramebuffer->getRenderTarget();

-            Image *drawRenderTarget = drawFramebuffer->getRenderTarget();

-

-            bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);

-

-            readRenderTarget->release();

-            drawRenderTarget->release();

-

-            if(!success)

-            {

-                ERR("BlitFramebufferANGLE failed.");

-                return;

-            }

-        }

-

-        if(blitDepthStencil)

-        {

-            bool success = device->stretchRect(readFramebuffer->getDepthStencil(), nullptr, drawFramebuffer->getDepthStencil(), nullptr, false);

-

-            if(!success)

-            {

-                ERR("BlitFramebufferANGLE failed.");

-                return;

-            }

-        }

-    }

-}

-

-void Context::setMatrixMode(GLenum mode)

-{

-    matrixMode = mode;

-}

-

-sw::MatrixStack &Context::currentMatrixStack()

-{

-	switch(matrixMode)

-	{

-	case GL_MODELVIEW:  return modelView;                     break;

-	case GL_PROJECTION: return projection;                    break;

-	case GL_TEXTURE:    return texture[mState.activeSampler]; break;

-	default:            UNREACHABLE(matrixMode); return modelView;      break;

-	}

-}

-

-void Context::loadIdentity()

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	currentMatrixStack().identity();

-}

-

-void Context::pushMatrix()

-{

-    //if(drawing)

-    //{

-    //    return error(GL_INVALID_OPERATION);

-    //}

-

-	if(!currentMatrixStack().push())

-	{

-		return error(GL_STACK_OVERFLOW);

-	}

-}

-

-void Context::popMatrix()

-{

-    //if(drawing)

-    //{

-    //    return error(GL_INVALID_OPERATION);

-    //}

-

-    if(!currentMatrixStack().pop())

-	{

-		return error(GL_STACK_OVERFLOW);

-	}

-}

-

-void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    currentMatrixStack().rotate(angle, x, y, z);

-}

-

-void Context::translate(GLfloat x, GLfloat y, GLfloat z)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    currentMatrixStack().translate(x, y, z);

-}

-

-void Context::scale(GLfloat x, GLfloat y, GLfloat z)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    currentMatrixStack().scale(x, y, z);

-}

-

-void Context::multiply(const GLdouble *m)

-{

-	if(drawing)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	currentMatrixStack().multiply(m);

-}

-

-void Context::multiply(const GLfloat *m)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    currentMatrixStack().multiply(m);

-}

-

-void Context::frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)

-{

-	if(drawing)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);

-}

-

-void Context::ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);

-}

-

-void Context::setLightingEnabled(bool enable)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    device->setLightingEnable(enable);

-}

-

-void Context::setFogEnabled(bool enable)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    device->setFogEnable(enable);

-}

-

-void Context::setAlphaTestEnabled(bool enable)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	device->setAlphaTestEnable(enable);

-}

-

-void Context::alphaFunc(GLenum func, GLclampf ref)

-{

-	if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	switch(func)

-	{

-	case GL_NEVER:    device->setAlphaCompare(sw::ALPHA_NEVER);        break;

-	case GL_LESS:     device->setAlphaCompare(sw::ALPHA_LESS);         break;

-	case GL_EQUAL:    device->setAlphaCompare(sw::ALPHA_EQUAL);        break;

-	case GL_LEQUAL:   device->setAlphaCompare(sw::ALPHA_LESSEQUAL);    break;

-	case GL_GREATER:  device->setAlphaCompare(sw::ALPHA_GREATER);      break;

-	case GL_NOTEQUAL: device->setAlphaCompare(sw::ALPHA_NOTEQUAL);     break;

-	case GL_GEQUAL:   device->setAlphaCompare(sw::ALPHA_GREATEREQUAL); break;

-	case GL_ALWAYS:   device->setAlphaCompare(sw::ALPHA_ALWAYS);       break;

-	default: UNREACHABLE(func);

-	}

-

-	device->setAlphaReference(gl::clamp01(ref));

-}

-

-void Context::setTexture2DEnabled(bool enable)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    envEnable[mState.activeSampler] = enable;

-}

-

-void Context::setShadeModel(GLenum mode)

-{

-    //if(drawing)

-    //{

-    //    return error(GL_INVALID_OPERATION);

-    //}

-

-    switch(mode)

-	{

-	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;

-	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;

-	default: return error(GL_INVALID_ENUM);

-	}

-}

-

-void Context::setLightEnabled(int index, bool enable)

-{

-    device->setLightEnable(index, enable);

-}

-

-void Context::setNormalizeNormalsEnabled(bool enable)

-{

-	device->setNormalizeNormals(enable);

-}

-

-GLuint Context::genLists(GLsizei range)

-{

-	if(drawing)

-    {

-        return error(GL_INVALID_OPERATION, 0);

-    }

-

-	int firstIndex = std::max(1u, firstFreeIndex);

-	for(; true; firstIndex++)

-	{

-		int empty = 0;

-		for(; empty < range; empty++)

-		{

-			if(displayList[firstIndex + empty] != 0)

-			{

-				break;

-			}

-		}

-

-		if(empty == range)

-		{

-			for(int i = firstIndex; i < firstIndex + range; i++)

-			{

-				displayList[i] = new DisplayList();

-			}

-

-			if(firstIndex == firstFreeIndex)

-			{

-				firstFreeIndex = firstIndex + range;

-			}

-

-			return firstIndex;

-		}

-	}

-

-	return 0;

-}

-

-void Context::newList(GLuint list, GLenum mode)

-{

-	if(drawing || listIndex != 0)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    ASSERT(!this->list);

-    this->list = new DisplayList();

-

-	listIndex = list;

-	listMode = mode;

-}

-

-void Context::endList()

-{

-    if(drawing || listIndex == 0)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    ASSERT(list);

-	delete displayList[listIndex];

-    displayList[listIndex] = list;

-    list = 0;

-

-	listIndex = 0;

-	listMode = 0;

-}

-

-void Context::callList(GLuint list)

-{

-	// As per GL specifications, if the list does not exist, it is ignored

-	if(displayList[list])

-	{

-		displayList[list]->call();

-	}

-}

-

-void Context::deleteList(GLuint list)

-{

-	delete displayList[list];

-	displayList[list] = 0;

-	displayList.erase(list);

-	firstFreeIndex = std::min(firstFreeIndex , list);

-}

-

-void Context::listCommand(Command *command)

-{

-    ASSERT(list);

-	list->list.push_back(command);

-

-	if(listMode == GL_COMPILE_AND_EXECUTE)

-	{

-		listMode = 0;

-		command->call();

-		listMode = GL_COMPILE_AND_EXECUTE;

-	}

-}

-

-void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)

-{

-    TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "

-          "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",

-          index, size, type, normalized, stride, ptr);

-

-	gl::Context *context = gl::getContext();

-

-    if(context)

-    {

-        context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);

-		context->setVertexAttribArrayEnabled(index, ptr != 0);

-    }

-}

-

-void Context::captureAttribs()

-{

-	memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute));

-}

-

-void Context::captureDrawArrays(GLenum mode, GLint first, GLsizei count)

-{

-	ASSERT(first == 0);   // FIXME: UNIMPLEMENTED!

-

-	for(GLuint i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-	{

-		GLint size = mState.vertexAttribute[i].mSize;

-		GLenum type = mState.vertexAttribute[i].mType;

-		GLboolean normalized = mState.vertexAttribute[i].mNormalized;

-		GLsizei stride = mState.vertexAttribute[i].mStride;

-		const GLvoid *pointer = mState.vertexAttribute[i].mPointer;

-

-		size_t length = count * mState.vertexAttribute[i].stride();

-

-		if(mState.vertexAttribute[i].mArrayEnabled)

-		{

-			ASSERT(pointer);   // FIXME: Add to condition?

-			const int padding = 1024;   // For SIMD processing of vertices   // FIXME: Still necessary?

-			void *buffer = new unsigned char[length + padding];

-			memcpy(buffer, pointer, length);

-

-			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)buffer));

-		}

-		else

-		{

-			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)0));

-		}

-	}

-}

-

-void Context::restoreAttribs()

-{

-	memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute));

-}

-

-void Context::clientActiveTexture(GLenum texture)

-{

-	clientTexture = texture;

-}

-

-GLenum Context::getClientActiveTexture() const

-{

-	return clientTexture;

-}

-

-unsigned int Context::getActiveTexture() const

-{

-	return mState.activeSampler;

-}

-

-void Context::begin(GLenum mode)

-{

-    if(drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    drawing = true;

-    drawMode = mode;

-

-    vertex.clear();

-}

-

-void Context::position(GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-    InVertex v;

-

-	v.P.x = x;

-	v.P.y = y;

-	v.P.z = z;

-	v.P.w = w;

-    v.C.x = mState.vertexAttribute[sw::Color0].mCurrentValue[0];

-	v.C.y = mState.vertexAttribute[sw::Color0].mCurrentValue[1];

-	v.C.z = mState.vertexAttribute[sw::Color0].mCurrentValue[2];

-	v.C.w = mState.vertexAttribute[sw::Color0].mCurrentValue[3];

-	v.N.x = mState.vertexAttribute[sw::Normal].mCurrentValue[0];

-	v.N.y = mState.vertexAttribute[sw::Normal].mCurrentValue[1];

-	v.N.z = mState.vertexAttribute[sw::Normal].mCurrentValue[2];

-	v.N.w = mState.vertexAttribute[sw::Normal].mCurrentValue[3];

-    v.T0.x = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0];

-	v.T0.y = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1];

-    v.T0.z = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2];

-	v.T0.w = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3];

-	v.T1.x = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0];

-	v.T1.y = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1];

-    v.T1.z = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2];

-	v.T1.w = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3];

-

-	vertex.push_back(v);

-}

-

-void Context::end()

-{

-    if(!drawing)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	const sw::Matrix Z(1, 0, 0, 0,

-	                   0, 1, 0, 0,

-	                   0, 0, 0.5, 0.5,

-	                   0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]

-

-	device->setProjectionMatrix(Z * projection.current());

-    device->setViewMatrix(modelView.current());

-    device->setTextureMatrix(0, texture[0].current());

-	device->setTextureMatrix(1, texture[1].current());

-	device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);

-	device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);

-

-	captureAttribs();

-

-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-	{

-		mState.vertexAttribute[i].mArrayEnabled = false;

-	}

-

-	setVertexAttribState(sw::Position, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].P);

-	setVertexAttribState(sw::Normal, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].N);

-	setVertexAttribState(sw::Color0, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].C);

-	setVertexAttribState(sw::TexCoord0, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T0);

-	setVertexAttribState(sw::TexCoord1, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T1);

-

-	mState.vertexAttribute[sw::Position].mArrayEnabled = true;

-	mState.vertexAttribute[sw::Normal].mArrayEnabled = true;

-	mState.vertexAttribute[sw::Color0].mArrayEnabled = true;

-	mState.vertexAttribute[sw::TexCoord0].mArrayEnabled = true;

-	mState.vertexAttribute[sw::TexCoord1].mArrayEnabled = true;

-

-	applyState(drawMode);

-

-	GLenum err = applyVertexBuffer(0, 0, vertex.size());

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-	applyTextures();

-

-    switch(drawMode)

-    {

-    case GL_POINTS:

-        UNIMPLEMENTED();

-        break;

-    case GL_LINES:

-        UNIMPLEMENTED();

-        break;

-    case GL_LINE_STRIP:

-        UNIMPLEMENTED();

-        break;

-    case GL_LINE_LOOP:

-        UNIMPLEMENTED();

-        break;

-    case GL_TRIANGLES:

-        UNIMPLEMENTED();

-        break;

-    case GL_TRIANGLE_STRIP:

-        device->drawPrimitive(DRAW_TRIANGLESTRIP, vertex.size() - 2);

-        break;

-    case GL_TRIANGLE_FAN:

-        UNIMPLEMENTED();

-        break;

-    case GL_QUADS:

-        UNIMPLEMENTED();

-        break;

-    case GL_QUAD_STRIP:

-        UNIMPLEMENTED();

-        break;

-    case GL_POLYGON:

-        UNIMPLEMENTED();

-        break;

-    default:

-        UNREACHABLE(drawMode);

-    }

-

-	restoreAttribs();

-

-    drawing = false;

-}

-

-void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled)

-{

-	if(mState.colorLogicOpEnabled != colorLogicOpEnabled)

-	{

-		mState.colorLogicOpEnabled = colorLogicOpEnabled;

-		mColorLogicOperatorDirty = true;

-	}

-}

-

-bool Context::isColorLogicOpEnabled()

-{

-	return mState.colorLogicOpEnabled;

-}

-

-void Context::setLogicalOperation(GLenum logicalOperation)

-{

-	if(mState.logicalOperation != logicalOperation)

-	{

-		mState.logicalOperation = logicalOperation;

-		mColorLogicOperatorDirty = true;

-	}

-}

-

-void Context::setColorMaterialEnabled(bool enable)

-{

-    device->setColorVertexEnable(enable);

-}

-

-void Context::setColorMaterialMode(GLenum mode)

-{

-    switch(mode)

-    {

-    case GL_EMISSION:

-        device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);

-        break;

-    case GL_AMBIENT:

-        device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);

-        device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-        break;

-    case GL_DIFFUSE:

-        device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);

-        device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-        break;

-    case GL_SPECULAR:

-        device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setSpecularMaterialSource(sw::MATERIAL_COLOR1);

-        device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-        break;

-    case GL_AMBIENT_AND_DIFFUSE:

-        device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);

-        device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-        device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);

-        device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-        break;

-    default:

-        UNREACHABLE(mode);

-    }

-}

-

-Device *Context::getDevice()

-{

-	return device;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Context.cpp: Implements the gl::Context class, managing all GL state and performing
+// rendering operations.
+
+#include "Context.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "ResourceManager.h"
+#include "Buffer.h"
+#include "Fence.h"
+#include "Framebuffer.h"
+#include "Program.h"
+#include "Query.h"
+#include "Renderbuffer.h"
+#include "Shader.h"
+#include "Texture.h"
+#include "VertexDataManager.h"
+#include "IndexDataManager.h"
+#include "Display.h"
+#include "Surface.h"
+#include "Common/Half.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+Context::Context(const Context *shareContext)
+	: modelView(32),
+	  projection(2)
+{
+	sw::Context *context = new sw::Context();
+	device = new gl::Device(context);
+
+	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+	mState.depthClearValue = 1.0f;
+	mState.stencilClearValue = 0;
+
+	mState.cullFaceEnabled = false;
+	mState.cullMode = GL_BACK;
+	mState.frontFace = GL_CCW;
+	mState.depthTestEnabled = false;
+	mState.depthFunc = GL_LESS;
+	mState.blendEnabled = false;
+	mState.sourceBlendRGB = GL_ONE;
+	mState.sourceBlendAlpha = GL_ONE;
+	mState.destBlendRGB = GL_ZERO;
+	mState.destBlendAlpha = GL_ZERO;
+	mState.blendEquationRGB = GL_FUNC_ADD;
+	mState.blendEquationAlpha = GL_FUNC_ADD;
+	mState.blendColor.red = 0;
+	mState.blendColor.green = 0;
+	mState.blendColor.blue = 0;
+	mState.blendColor.alpha = 0;
+	mState.stencilTestEnabled = false;
+	mState.stencilFunc = GL_ALWAYS;
+	mState.stencilRef = 0;
+	mState.stencilMask = -1;
+	mState.stencilWritemask = -1;
+	mState.stencilBackFunc = GL_ALWAYS;
+	mState.stencilBackRef = 0;
+	mState.stencilBackMask = - 1;
+	mState.stencilBackWritemask = -1;
+	mState.stencilFail = GL_KEEP;
+	mState.stencilPassDepthFail = GL_KEEP;
+	mState.stencilPassDepthPass = GL_KEEP;
+	mState.stencilBackFail = GL_KEEP;
+	mState.stencilBackPassDepthFail = GL_KEEP;
+	mState.stencilBackPassDepthPass = GL_KEEP;
+	mState.polygonOffsetFillEnabled = false;
+	mState.polygonOffsetFactor = 0.0f;
+	mState.polygonOffsetUnits = 0.0f;
+	mState.sampleAlphaToCoverageEnabled = false;
+	mState.sampleCoverageEnabled = false;
+	mState.sampleCoverageValue = 1.0f;
+	mState.sampleCoverageInvert = false;
+	mState.scissorTestEnabled = false;
+	mState.ditherEnabled = true;
+	mState.generateMipmapHint = GL_DONT_CARE;
+	mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
+	mState.colorLogicOpEnabled = false;
+	mState.logicalOperation = GL_COPY;
+
+	mState.lineWidth = 1.0f;
+
+	mState.viewportX = 0;
+	mState.viewportY = 0;
+	mState.viewportWidth = 0;
+	mState.viewportHeight = 0;
+	mState.zNear = 0.0f;
+	mState.zFar = 1.0f;
+
+	mState.scissorX = 0;
+	mState.scissorY = 0;
+	mState.scissorWidth = 0;
+	mState.scissorHeight = 0;
+
+	mState.colorMaskRed = true;
+	mState.colorMaskGreen = true;
+	mState.colorMaskBlue = true;
+	mState.colorMaskAlpha = true;
+	mState.depthMask = true;
+
+	if(shareContext)
+	{
+		mResourceManager = shareContext->mResourceManager;
+		mResourceManager->addRef();
+	}
+	else
+	{
+		mResourceManager = new ResourceManager();
+	}
+
+	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
+	// and cube map texture state vectors respectively associated with them.
+	// In order that access to these initial textures not be lost, they are treated as texture
+	// objects all of whose names are 0.
+
+	mTexture2DZero = new Texture2D(0);
+	mProxyTexture2DZero = new Texture2D(0);
+	mTextureCubeMapZero = new TextureCubeMap(0);
+
+	mState.activeSampler = 0;
+	bindArrayBuffer(0);
+	bindElementArrayBuffer(0);
+	bindTextureCubeMap(0);
+	bindTexture2D(0);
+	bindReadFramebuffer(0);
+	bindDrawFramebuffer(0);
+	bindRenderbuffer(0);
+
+	mState.currentProgram = 0;
+
+	mState.packAlignment = 4;
+	mState.unpackAlignment = 4;
+
+	mVertexDataManager = nullptr;
+	mIndexDataManager = nullptr;
+
+	mInvalidEnum = false;
+	mInvalidValue = false;
+	mInvalidOperation = false;
+	mOutOfMemory = false;
+	mInvalidFramebufferOperation = false;
+
+	mHasBeenCurrent = false;
+
+	markAllStateDirty();
+
+	matrixMode = GL_MODELVIEW;
+
+	listMode = 0;
+	//memset(displayList, 0, sizeof(displayList));
+	listIndex = 0;
+	list = 0;
+	firstFreeIndex = 1;
+
+	clientTexture = GL_TEXTURE0;
+
+	drawing = false;
+	drawMode = 0;   // FIXME
+
+	mState.vertexAttribute[sw::Color0].mCurrentValue[0] = 1.0f;
+	mState.vertexAttribute[sw::Color0].mCurrentValue[1] = 1.0f;
+	mState.vertexAttribute[sw::Color0].mCurrentValue[2] = 1.0f;
+	mState.vertexAttribute[sw::Color0].mCurrentValue[3] = 1.0f;
+	mState.vertexAttribute[sw::Normal].mCurrentValue[0] = 0.0f;
+	mState.vertexAttribute[sw::Normal].mCurrentValue[1] = 0.0f;
+	mState.vertexAttribute[sw::Normal].mCurrentValue[2] = 1.0f;
+	mState.vertexAttribute[sw::Normal].mCurrentValue[3] = 0.0f;
+	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0] = 0.0f;
+	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1] = 0.0f;
+	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2] = 0.0f;
+	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3] = 1.0f;
+	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0] = 0.0f;
+	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1] = 0.0f;
+	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2] = 0.0f;
+	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3] = 1.0f;
+
+	for(int i = 0; i < 8; i++)
+	{
+		envEnable[i] = true;
+	}
+}
+
+Context::~Context()
+{
+	if(mState.currentProgram != 0)
+	{
+		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
+		if(programObject)
+		{
+			programObject->release();
+		}
+		mState.currentProgram = 0;
+	}
+
+	while(!mFramebufferNameSpace.empty())
+	{
+		deleteFramebuffer(mFramebufferNameSpace.firstName());
+	}
+
+	while(!mFenceNameSpace.empty())
+	{
+		deleteFence(mFenceNameSpace.firstName());
+	}
+
+	while(!mQueryNameSpace.empty())
+	{
+		deleteQuery(mQueryNameSpace.firstName());
+	}
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+		{
+			mState.samplerTexture[type][sampler] = nullptr;
+		}
+	}
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mState.vertexAttribute[i].mBoundBuffer = nullptr;
+	}
+
+	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
+	{
+		mState.activeQuery[i] = nullptr;
+	}
+
+	mState.arrayBuffer = nullptr;
+	mState.elementArrayBuffer = nullptr;
+	mState.renderbuffer = nullptr;
+
+	mTexture2DZero = nullptr;
+	mProxyTexture2DZero = nullptr;
+	mTextureCubeMapZero = nullptr;
+
+	delete mVertexDataManager;
+	delete mIndexDataManager;
+
+	mResourceManager->release();
+	delete device;
+}
+
+void Context::makeCurrent(Surface *surface)
+{
+	if(!mHasBeenCurrent)
+	{
+		mVertexDataManager = new VertexDataManager(this);
+		mIndexDataManager = new IndexDataManager();
+
+		mState.viewportX = 0;
+		mState.viewportY = 0;
+		mState.viewportWidth = surface->getWidth();
+		mState.viewportHeight = surface->getHeight();
+
+		mState.scissorX = 0;
+		mState.scissorY = 0;
+		mState.scissorWidth = surface->getWidth();
+		mState.scissorHeight = surface->getHeight();
+
+		mHasBeenCurrent = true;
+	}
+
+	// Wrap the existing resources into GL objects and assign them to the '0' names
+	Image *defaultRenderTarget = surface->getRenderTarget();
+	Image *depthStencil = surface->getDepthStencil();
+
+	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
+	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
+	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
+
+	setFramebufferZero(framebufferZero);
+
+	if(defaultRenderTarget)
+	{
+		defaultRenderTarget->release();
+	}
+
+	if(depthStencil)
+	{
+		depthStencil->release();
+	}
+
+	markAllStateDirty();
+}
+
+// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
+void Context::markAllStateDirty()
+{
+	mAppliedProgramSerial = 0;
+
+	mDepthStateDirty = true;
+	mMaskStateDirty = true;
+	mBlendStateDirty = true;
+	mStencilStateDirty = true;
+	mPolygonOffsetStateDirty = true;
+	mSampleStateDirty = true;
+	mDitherStateDirty = true;
+	mFrontFaceDirty = true;
+	mColorLogicOperatorDirty = true;
+}
+
+void Context::setClearColor(float red, float green, float blue, float alpha)
+{
+	mState.colorClearValue.red = red;
+	mState.colorClearValue.green = green;
+	mState.colorClearValue.blue = blue;
+	mState.colorClearValue.alpha = alpha;
+}
+
+void Context::setClearDepth(float depth)
+{
+	mState.depthClearValue = depth;
+}
+
+void Context::setClearStencil(int stencil)
+{
+	mState.stencilClearValue = stencil;
+}
+
+void Context::setCullFaceEnabled(bool enabled)
+{
+	mState.cullFaceEnabled = enabled;
+}
+
+bool Context::isCullFaceEnabled() const
+{
+	return mState.cullFaceEnabled;
+}
+
+void Context::setCullMode(GLenum mode)
+{
+   mState.cullMode = mode;
+}
+
+void Context::setFrontFace(GLenum front)
+{
+	if(mState.frontFace != front)
+	{
+		mState.frontFace = front;
+		mFrontFaceDirty = true;
+	}
+}
+
+void Context::setDepthTestEnabled(bool enabled)
+{
+	if(mState.depthTestEnabled != enabled)
+	{
+		mState.depthTestEnabled = enabled;
+		mDepthStateDirty = true;
+	}
+}
+
+bool Context::isDepthTestEnabled() const
+{
+	return mState.depthTestEnabled;
+}
+
+void Context::setDepthFunc(GLenum depthFunc)
+{
+	if(mState.depthFunc != depthFunc)
+	{
+		mState.depthFunc = depthFunc;
+		mDepthStateDirty = true;
+	}
+}
+
+void Context::setDepthRange(float zNear, float zFar)
+{
+	mState.zNear = zNear;
+	mState.zFar = zFar;
+}
+
+void Context::setBlendEnabled(bool enabled)
+{
+	if(mState.blendEnabled != enabled)
+	{
+		mState.blendEnabled = enabled;
+		mBlendStateDirty = true;
+	}
+}
+
+bool Context::isBlendEnabled() const
+{
+	return mState.blendEnabled;
+}
+
+void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
+{
+	if(mState.sourceBlendRGB != sourceRGB ||
+	   mState.sourceBlendAlpha != sourceAlpha ||
+	   mState.destBlendRGB != destRGB ||
+	   mState.destBlendAlpha != destAlpha)
+	{
+		mState.sourceBlendRGB = sourceRGB;
+		mState.destBlendRGB = destRGB;
+		mState.sourceBlendAlpha = sourceAlpha;
+		mState.destBlendAlpha = destAlpha;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setBlendColor(float red, float green, float blue, float alpha)
+{
+	if(mState.blendColor.red != red ||
+	   mState.blendColor.green != green ||
+	   mState.blendColor.blue != blue ||
+	   mState.blendColor.alpha != alpha)
+	{
+		mState.blendColor.red = red;
+		mState.blendColor.green = green;
+		mState.blendColor.blue = blue;
+		mState.blendColor.alpha = alpha;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
+{
+	if(mState.blendEquationRGB != rgbEquation ||
+	   mState.blendEquationAlpha != alphaEquation)
+	{
+		mState.blendEquationRGB = rgbEquation;
+		mState.blendEquationAlpha = alphaEquation;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setStencilTestEnabled(bool enabled)
+{
+	if(mState.stencilTestEnabled != enabled)
+	{
+		mState.stencilTestEnabled = enabled;
+		mStencilStateDirty = true;
+	}
+}
+
+bool Context::isStencilTestEnabled() const
+{
+	return mState.stencilTestEnabled;
+}
+
+void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
+{
+	if(mState.stencilFunc != stencilFunc ||
+	   mState.stencilRef != stencilRef ||
+	   mState.stencilMask != stencilMask)
+	{
+		mState.stencilFunc = stencilFunc;
+		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
+		mState.stencilMask = stencilMask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
+{
+	if(mState.stencilBackFunc != stencilBackFunc ||
+	   mState.stencilBackRef != stencilBackRef ||
+	   mState.stencilBackMask != stencilBackMask)
+	{
+		mState.stencilBackFunc = stencilBackFunc;
+		mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
+		mState.stencilBackMask = stencilBackMask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilWritemask(GLuint stencilWritemask)
+{
+	if(mState.stencilWritemask != stencilWritemask)
+	{
+		mState.stencilWritemask = stencilWritemask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
+{
+	if(mState.stencilBackWritemask != stencilBackWritemask)
+	{
+		mState.stencilBackWritemask = stencilBackWritemask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
+{
+	if(mState.stencilFail != stencilFail ||
+	   mState.stencilPassDepthFail != stencilPassDepthFail ||
+	   mState.stencilPassDepthPass != stencilPassDepthPass)
+	{
+		mState.stencilFail = stencilFail;
+		mState.stencilPassDepthFail = stencilPassDepthFail;
+		mState.stencilPassDepthPass = stencilPassDepthPass;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
+{
+	if(mState.stencilBackFail != stencilBackFail ||
+	   mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
+	   mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
+	{
+		mState.stencilBackFail = stencilBackFail;
+		mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
+		mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setPolygonOffsetFillEnabled(bool enabled)
+{
+	if(mState.polygonOffsetFillEnabled != enabled)
+	{
+		mState.polygonOffsetFillEnabled = enabled;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+bool Context::isPolygonOffsetFillEnabled() const
+{
+	return mState.polygonOffsetFillEnabled;
+}
+
+void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
+{
+	if(mState.polygonOffsetFactor != factor ||
+	   mState.polygonOffsetUnits != units)
+	{
+		mState.polygonOffsetFactor = factor;
+		mState.polygonOffsetUnits = units;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+void Context::setSampleAlphaToCoverageEnabled(bool enabled)
+{
+	if(mState.sampleAlphaToCoverageEnabled != enabled)
+	{
+		mState.sampleAlphaToCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleAlphaToCoverageEnabled() const
+{
+	return mState.sampleAlphaToCoverageEnabled;
+}
+
+void Context::setSampleCoverageEnabled(bool enabled)
+{
+	if(mState.sampleCoverageEnabled != enabled)
+	{
+		mState.sampleCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleCoverageEnabled() const
+{
+	return mState.sampleCoverageEnabled;
+}
+
+void Context::setSampleCoverageParams(GLclampf value, bool invert)
+{
+	if(mState.sampleCoverageValue != value ||
+		mState.sampleCoverageInvert != invert)
+	{
+		mState.sampleCoverageValue = value;
+		mState.sampleCoverageInvert = invert;
+		mSampleStateDirty = true;
+	}
+}
+
+void Context::setScissorTestEnabled(bool enabled)
+{
+	mState.scissorTestEnabled = enabled;
+}
+
+bool Context::isScissorTestEnabled() const
+{
+	return mState.scissorTestEnabled;
+}
+
+void Context::setDitherEnabled(bool enabled)
+{
+	if(mState.ditherEnabled != enabled)
+	{
+		mState.ditherEnabled = enabled;
+		mDitherStateDirty = true;
+	}
+}
+
+bool Context::isDitherEnabled() const
+{
+	return mState.ditherEnabled;
+}
+
+void Context::setLineWidth(GLfloat width)
+{
+	mState.lineWidth = width;
+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
+}
+
+void Context::setGenerateMipmapHint(GLenum hint)
+{
+	mState.generateMipmapHint = hint;
+}
+
+void Context::setFragmentShaderDerivativeHint(GLenum hint)
+{
+	mState.fragmentShaderDerivativeHint = hint;
+	// TODO: Propagate the hint to shader translator so we can write
+	// ddx, ddx_coarse, or ddx_fine depending on the hint.
+	// Ignore for now. It is valid for implementations to ignore hint.
+}
+
+void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.viewportX = x;
+	mState.viewportY = y;
+	mState.viewportWidth = width;
+	mState.viewportHeight = height;
+}
+
+void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.scissorX = x;
+	mState.scissorY = y;
+	mState.scissorWidth = width;
+	mState.scissorHeight = height;
+}
+
+void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
+{
+	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
+	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
+	{
+		mState.colorMaskRed = red;
+		mState.colorMaskGreen = green;
+		mState.colorMaskBlue = blue;
+		mState.colorMaskAlpha = alpha;
+		mMaskStateDirty = true;
+	}
+}
+
+void Context::setDepthMask(bool mask)
+{
+	if(mState.depthMask != mask)
+	{
+		mState.depthMask = mask;
+		mMaskStateDirty = true;
+	}
+}
+
+void Context::setActiveSampler(unsigned int active)
+{
+	mState.activeSampler = active;
+}
+
+GLuint Context::getReadFramebufferName() const
+{
+	return mState.readFramebuffer;
+}
+
+GLuint Context::getDrawFramebufferName() const
+{
+	return mState.drawFramebuffer;
+}
+
+GLuint Context::getRenderbufferName() const
+{
+	return mState.renderbuffer.name();
+}
+
+GLuint Context::getArrayBufferName() const
+{
+	return mState.arrayBuffer.name();
+}
+
+GLuint Context::getActiveQuery(GLenum target) const
+{
+	Query *queryObject = nullptr;
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED:
+		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
+		break;
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
+		break;
+	default:
+		ASSERT(false);
+	}
+
+	if(queryObject)
+	{
+		return queryObject->name;
+	}
+
+	return 0;
+}
+
+void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
+{
+	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
+}
+
+const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
+{
+	return mState.vertexAttribute[attribNum];
+}
+
+void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
+                                   GLsizei stride, const void *pointer)
+{
+	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
+	mState.vertexAttribute[attribNum].mSize = size;
+	mState.vertexAttribute[attribNum].mType = type;
+	mState.vertexAttribute[attribNum].mNormalized = normalized;
+	mState.vertexAttribute[attribNum].mStride = stride;
+	mState.vertexAttribute[attribNum].mPointer = pointer;
+}
+
+const void *Context::getVertexAttribPointer(unsigned int attribNum) const
+{
+	return mState.vertexAttribute[attribNum].mPointer;
+}
+
+const VertexAttributeArray &Context::getVertexAttributes()
+{
+	return mState.vertexAttribute;
+}
+
+void Context::setPackAlignment(GLint alignment)
+{
+	mState.packAlignment = alignment;
+}
+
+GLint Context::getPackAlignment() const
+{
+	return mState.packAlignment;
+}
+
+void Context::setUnpackAlignment(GLint alignment)
+{
+	mState.unpackAlignment = alignment;
+}
+
+GLint Context::getUnpackAlignment() const
+{
+	return mState.unpackAlignment;
+}
+
+GLuint Context::createBuffer()
+{
+	return mResourceManager->createBuffer();
+}
+
+GLuint Context::createProgram()
+{
+	return mResourceManager->createProgram();
+}
+
+GLuint Context::createShader(GLenum type)
+{
+	return mResourceManager->createShader(type);
+}
+
+GLuint Context::createTexture()
+{
+	return mResourceManager->createTexture();
+}
+
+GLuint Context::createRenderbuffer()
+{
+	return mResourceManager->createRenderbuffer();
+}
+
+// Returns an unused framebuffer name
+GLuint Context::createFramebuffer()
+{
+	return mFramebufferNameSpace.allocate();
+}
+
+GLuint Context::createFence()
+{
+	return mFenceNameSpace.allocate(new Fence());
+}
+
+// Returns an unused query name
+GLuint Context::createQuery()
+{
+	return mQueryNameSpace.allocate();
+}
+
+void Context::deleteBuffer(GLuint buffer)
+{
+	if(mResourceManager->getBuffer(buffer))
+	{
+		detachBuffer(buffer);
+	}
+
+	mResourceManager->deleteBuffer(buffer);
+}
+
+void Context::deleteShader(GLuint shader)
+{
+	mResourceManager->deleteShader(shader);
+}
+
+void Context::deleteProgram(GLuint program)
+{
+	mResourceManager->deleteProgram(program);
+}
+
+void Context::deleteTexture(GLuint texture)
+{
+	if(mResourceManager->getTexture(texture))
+	{
+		detachTexture(texture);
+	}
+
+	mResourceManager->deleteTexture(texture);
+}
+
+void Context::deleteRenderbuffer(GLuint renderbuffer)
+{
+	if(mResourceManager->getRenderbuffer(renderbuffer))
+	{
+		detachRenderbuffer(renderbuffer);
+	}
+
+	mResourceManager->deleteRenderbuffer(renderbuffer);
+}
+
+void Context::deleteFramebuffer(GLuint framebuffer)
+{
+	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
+
+	if(framebufferObject)
+	{
+		detachFramebuffer(framebuffer);
+
+		delete framebufferObject;
+	}
+}
+
+void Context::deleteFence(GLuint fence)
+{
+	Fence *fenceObject = mFenceNameSpace.remove(fence);
+
+	if(fenceObject)
+	{
+		delete fenceObject;
+	}
+}
+
+void Context::deleteQuery(GLuint query)
+{
+	Query *queryObject = mQueryNameSpace.remove(query);
+
+	if(queryObject)
+	{
+		queryObject->release();
+	}
+}
+
+Buffer *Context::getBuffer(GLuint handle)
+{
+	return mResourceManager->getBuffer(handle);
+}
+
+Shader *Context::getShader(GLuint handle)
+{
+	return mResourceManager->getShader(handle);
+}
+
+Program *Context::getProgram(GLuint handle)
+{
+	return mResourceManager->getProgram(handle);
+}
+
+Texture *Context::getTexture(GLuint handle)
+{
+	return mResourceManager->getTexture(handle);
+}
+
+Renderbuffer *Context::getRenderbuffer(GLuint handle)
+{
+	return mResourceManager->getRenderbuffer(handle);
+}
+
+Framebuffer *Context::getReadFramebuffer()
+{
+	return getFramebuffer(mState.readFramebuffer);
+}
+
+Framebuffer *Context::getDrawFramebuffer()
+{
+	return getFramebuffer(mState.drawFramebuffer);
+}
+
+void Context::bindArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.arrayBuffer = getBuffer(buffer);
+}
+
+void Context::bindElementArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.elementArrayBuffer = getBuffer(buffer);
+}
+
+void Context::bindTexture2D(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+
+	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindTextureCubeMap(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
+
+	mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindReadFramebuffer(GLuint framebuffer)
+{
+	if(!getFramebuffer(framebuffer))
+	{
+		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
+	}
+
+	mState.readFramebuffer = framebuffer;
+}
+
+void Context::bindDrawFramebuffer(GLuint framebuffer)
+{
+	if(!getFramebuffer(framebuffer))
+	{
+		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
+	}
+
+	mState.drawFramebuffer = framebuffer;
+}
+
+void Context::bindRenderbuffer(GLuint renderbuffer)
+{
+	mResourceManager->checkRenderbufferAllocation(renderbuffer);
+
+	mState.renderbuffer = getRenderbuffer(renderbuffer);
+}
+
+void Context::useProgram(GLuint program)
+{
+	GLuint priorProgram = mState.currentProgram;
+	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
+
+	if(priorProgram != program)
+	{
+		Program *newProgram = mResourceManager->getProgram(program);
+		Program *oldProgram = mResourceManager->getProgram(priorProgram);
+
+		if(newProgram)
+		{
+			newProgram->addRef();
+		}
+
+		if(oldProgram)
+		{
+			oldProgram->release();
+		}
+	}
+}
+
+void Context::beginQuery(GLenum target, GLuint query)
+{
+	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
+	// of zero, if the active query object name for <target> is non-zero (for the
+	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
+	// the active query for either target is non-zero), if <id> is the name of an
+	// existing query object whose type does not match <target>, or if <id> is the
+	// active query object name for any query type, the error INVALID_OPERATION is
+	// generated.
+
+	// Ensure no other queries are active
+	// NOTE: If other queries than occlusion are supported, we will need to check
+	// separately that:
+	//    a) The query ID passed is not the current active query for any target/type
+	//    b) There are no active queries for the requested target (and in the case
+	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
+	//       no query may be active for either if glBeginQuery targets either.
+	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
+	{
+		if(mState.activeQuery[i])
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	QueryType qType;
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED:
+		qType = QUERY_ANY_SAMPLES_PASSED;
+		break;
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
+		break;
+	default:
+		ASSERT(false);
+	}
+
+	Query *queryObject = getQuery(query, true, target);
+
+	// Check that name was obtained with glGenQueries
+	if(!queryObject)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	// Check for type mismatch
+	if(queryObject->getType() != target)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	// Set query as active for specified target
+	mState.activeQuery[qType] = queryObject;
+
+	// Begin query
+	queryObject->begin();
+}
+
+void Context::endQuery(GLenum target)
+{
+	QueryType qType;
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED:
+		qType = QUERY_ANY_SAMPLES_PASSED;
+		break;
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
+		break;
+	default:
+		ASSERT(false);
+	}
+
+	Query *queryObject = mState.activeQuery[qType];
+
+	if(!queryObject)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	queryObject->end();
+
+	mState.activeQuery[qType] = nullptr;
+}
+
+void Context::setFramebufferZero(Framebuffer *buffer)
+{
+	delete mFramebufferNameSpace.remove(0);
+	mFramebufferNameSpace.insert(0, buffer);
+}
+
+void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
+{
+	Renderbuffer *renderbufferObject = mState.renderbuffer;
+	renderbufferObject->setStorage(renderbuffer);
+}
+
+Framebuffer *Context::getFramebuffer(unsigned int handle)
+{
+	return mFramebufferNameSpace.find(handle);
+}
+
+Fence *Context::getFence(unsigned int handle)
+{
+	return mFenceNameSpace.find(handle);
+}
+
+Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
+{
+	if(!mQueryNameSpace.isReserved(handle))
+	{
+		return nullptr;
+	}
+	else
+	{
+		Query *query = mQueryNameSpace.find(handle);
+		if(!query && create)
+		{
+			query = new Query(handle, type);
+			query->addRef();
+			mQueryNameSpace.insert(handle, query);
+		}
+
+		return query;
+	}
+}
+
+Buffer *Context::getArrayBuffer()
+{
+	return mState.arrayBuffer;
+}
+
+Buffer *Context::getElementArrayBuffer()
+{
+	return mState.elementArrayBuffer;
+}
+
+Program *Context::getCurrentProgram()
+{
+	return mResourceManager->getProgram(mState.currentProgram);
+}
+
+Texture2D *Context::getTexture2D(GLenum target)
+{
+	if(target == GL_TEXTURE_2D)
+	{
+		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
+	}
+	else if(target == GL_PROXY_TEXTURE_2D)
+	{
+		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, PROXY_TEXTURE_2D));
+	}
+	else UNREACHABLE(target);
+
+	return nullptr;
+}
+
+TextureCubeMap *Context::getTextureCubeMap()
+{
+	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
+}
+
+Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
+{
+	GLuint texid = mState.samplerTexture[type][sampler].name();
+
+	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
+	{
+		switch(type)
+		{
+		case TEXTURE_2D:       return mTexture2DZero;
+		case PROXY_TEXTURE_2D: return mProxyTexture2DZero;
+		case TEXTURE_CUBE:     return mTextureCubeMapZero;
+		default: UNREACHABLE(type);
+		}
+	}
+
+	return mState.samplerTexture[type][sampler];
+}
+
+bool Context::getBooleanv(GLenum pname, GLboolean *params)
+{
+	switch(pname)
+	{
+	case GL_SHADER_COMPILER:          *params = GL_TRUE;                             break;
+	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
+	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
+	case GL_COLOR_WRITEMASK:
+		params[0] = mState.colorMaskRed;
+		params[1] = mState.colorMaskGreen;
+		params[2] = mState.colorMaskBlue;
+		params[3] = mState.colorMaskAlpha;
+		break;
+	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
+	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
+	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
+	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
+	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
+	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
+	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
+	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getFloatv(GLenum pname, GLfloat *params)
+{
+	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application.
+	switch(pname)
+	{
+	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
+	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
+	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
+	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
+	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
+		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
+		break;
+	case GL_ALIASED_POINT_SIZE_RANGE:
+		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
+		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
+		break;
+	case GL_DEPTH_RANGE:
+		params[0] = mState.zNear;
+		params[1] = mState.zFar;
+		break;
+	case GL_COLOR_CLEAR_VALUE:
+		params[0] = mState.colorClearValue.red;
+		params[1] = mState.colorClearValue.green;
+		params[2] = mState.colorClearValue.blue;
+		params[3] = mState.colorClearValue.alpha;
+		break;
+	case GL_BLEND_COLOR:
+		params[0] = mState.blendColor.red;
+		params[1] = mState.blendColor.green;
+		params[2] = mState.blendColor.blue;
+		params[3] = mState.blendColor.alpha;
+		break;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+		*params = MAX_TEXTURE_MAX_ANISOTROPY;
+		break;
+	case GL_MODELVIEW_MATRIX:
+		for(int i = 0; i < 16; i++)
+		{
+			params[i] = modelView.current()[i % 4][i / 4];
+		}
+		break;
+	case GL_PROJECTION_MATRIX:
+		for(int i = 0; i < 16; i++)
+		{
+			params[i] = projection.current()[i % 4][i / 4];
+		}
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getIntegerv(GLenum pname, GLint *params)
+{
+	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application. You may find it in
+	// Context::getFloatv.
+	switch(pname)
+	{
+	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
+	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
+	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:    *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
+	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
+	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
+	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
+	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
+	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
+	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:  *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
+	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
+	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
+	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
+	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
+//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+	case GL_DRAW_FRAMEBUFFER_BINDING:         *params = mState.drawFramebuffer;               break;
+	case GL_READ_FRAMEBUFFER_BINDING:         *params = mState.readFramebuffer;               break;
+	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
+	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
+	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
+	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
+	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
+	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:  *params = mState.fragmentShaderDerivativeHint; break;
+	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
+	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
+	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
+	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
+	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
+	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
+	case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.stencilBackMask;               break;
+	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
+	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
+	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
+	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
+	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
+	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
+	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
+	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
+	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
+	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
+	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
+	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
+	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
+	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
+	case GL_STENCIL_BACK_WRITEMASK:           *params = mState.stencilBackWritemask;          break;
+	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
+	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
+	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
+	case GL_MAX_ARRAY_TEXTURE_LAYERS:         *params = 0;                                    break;
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
+	case GL_MAX_SAMPLES:                      *params = IMPLEMENTATION_MAX_SAMPLES;           break;
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			int width, height, samples;
+
+			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
+			{
+				switch(pname)
+				{
+				case GL_SAMPLE_BUFFERS:
+					if(samples > 1)
+					{
+						*params = 1;
+					}
+					else
+					{
+						*params = 0;
+					}
+					break;
+				case GL_SAMPLES:
+					*params = samples;
+					break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE:   *params = IMPLEMENTATION_COLOR_READ_TYPE;   break;
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;
+	case GL_MAX_VIEWPORT_DIMS:
+		{
+			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
+			params[0] = maxDimension;
+			params[1] = maxDimension;
+		}
+		break;
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		{
+			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
+			{
+				params[i] = compressedTextureFormats[i];
+			}
+		}
+		break;
+	case GL_VIEWPORT:
+		params[0] = mState.viewportX;
+		params[1] = mState.viewportY;
+		params[2] = mState.viewportWidth;
+		params[3] = mState.viewportHeight;
+		break;
+	case GL_SCISSOR_BOX:
+		params[0] = mState.scissorX;
+		params[1] = mState.scissorY;
+		params[2] = mState.scissorWidth;
+		params[3] = mState.scissorHeight;
+		break;
+	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
+	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
+
+			if(colorbuffer)
+			{
+				switch(pname)
+				{
+				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
+				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
+				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
+				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_DEPTH_BITS:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+
+			if(depthbuffer)
+			{
+				*params = depthbuffer->getDepthSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_STENCIL_BITS:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+
+			if(stencilbuffer)
+			{
+				*params = stencilbuffer->getStencilSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_TEXTURE_BINDING_2D:
+		{
+			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+			{
+				error(GL_INVALID_OPERATION);
+				return false;
+			}
+
+			*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
+		}
+		break;
+	case GL_TEXTURE_BINDING_CUBE_MAP:
+		{
+			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+			{
+				error(GL_INVALID_OPERATION);
+				return false;
+			}
+
+			*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
+		}
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		{
+			*type = GL_INT;
+			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
+		}
+		break;
+	case GL_SHADER_BINARY_FORMATS:
+		{
+			*type = GL_INT;
+			*numParams = 0;
+		}
+		break;
+	case GL_MAX_VERTEX_ATTRIBS:
+	case GL_MAX_VERTEX_UNIFORM_VECTORS:
+	case GL_MAX_VARYING_VECTORS:
+	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+	case GL_MAX_TEXTURE_IMAGE_UNITS:
+	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+	case GL_MAX_RENDERBUFFER_SIZE:
+	case GL_NUM_SHADER_BINARY_FORMATS:
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+	case GL_ARRAY_BUFFER_BINDING:
+	case GL_FRAMEBUFFER_BINDING:
+	case GL_RENDERBUFFER_BINDING:
+	case GL_CURRENT_PROGRAM:
+	case GL_PACK_ALIGNMENT:
+	case GL_UNPACK_ALIGNMENT:
+	case GL_GENERATE_MIPMAP_HINT:
+	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+	case GL_DEPTH_BITS:
+	case GL_STENCIL_BITS:
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+	case GL_CULL_FACE_MODE:
+	case GL_FRONT_FACE:
+	case GL_ACTIVE_TEXTURE:
+	case GL_STENCIL_FUNC:
+	case GL_STENCIL_VALUE_MASK:
+	case GL_STENCIL_REF:
+	case GL_STENCIL_FAIL:
+	case GL_STENCIL_PASS_DEPTH_FAIL:
+	case GL_STENCIL_PASS_DEPTH_PASS:
+	case GL_STENCIL_BACK_FUNC:
+	case GL_STENCIL_BACK_VALUE_MASK:
+	case GL_STENCIL_BACK_REF:
+	case GL_STENCIL_BACK_FAIL:
+	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+	case GL_DEPTH_FUNC:
+	case GL_BLEND_SRC_RGB:
+	case GL_BLEND_SRC_ALPHA:
+	case GL_BLEND_DST_RGB:
+	case GL_BLEND_DST_ALPHA:
+	case GL_BLEND_EQUATION_RGB:
+	case GL_BLEND_EQUATION_ALPHA:
+	case GL_STENCIL_WRITEMASK:
+	case GL_STENCIL_BACK_WRITEMASK:
+	case GL_STENCIL_CLEAR_VALUE:
+	case GL_SUBPIXEL_BITS:
+	case GL_MAX_TEXTURE_SIZE:
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+	case GL_TEXTURE_BINDING_2D:
+	case GL_TEXTURE_BINDING_CUBE_MAP:
+	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+	case GL_MAX_ARRAY_TEXTURE_LAYERS:
+		{
+			*type = GL_INT;
+			*numParams = 1;
+		}
+		break;
+	case GL_MAX_SAMPLES:
+		{
+			*type = GL_INT;
+			*numParams = 1;
+		}
+		break;
+	case GL_MAX_VIEWPORT_DIMS:
+		{
+			*type = GL_INT;
+			*numParams = 2;
+		}
+		break;
+	case GL_VIEWPORT:
+	case GL_SCISSOR_BOX:
+		{
+			*type = GL_INT;
+			*numParams = 4;
+		}
+		break;
+	case GL_SHADER_COMPILER:
+	case GL_SAMPLE_COVERAGE_INVERT:
+	case GL_DEPTH_WRITEMASK:
+	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
+	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
+	case GL_SAMPLE_COVERAGE:
+	case GL_SCISSOR_TEST:
+	case GL_STENCIL_TEST:
+	case GL_DEPTH_TEST:
+	case GL_BLEND:
+	case GL_DITHER:
+		{
+			*type = GL_BOOL;
+			*numParams = 1;
+		}
+		break;
+	case GL_COLOR_WRITEMASK:
+		{
+			*type = GL_BOOL;
+			*numParams = 4;
+		}
+		break;
+	case GL_POLYGON_OFFSET_FACTOR:
+	case GL_POLYGON_OFFSET_UNITS:
+	case GL_SAMPLE_COVERAGE_VALUE:
+	case GL_DEPTH_CLEAR_VALUE:
+	case GL_LINE_WIDTH:
+		{
+			*type = GL_FLOAT;
+			*numParams = 1;
+		}
+		break;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+	case GL_ALIASED_POINT_SIZE_RANGE:
+	case GL_DEPTH_RANGE:
+		{
+			*type = GL_FLOAT;
+			*numParams = 2;
+		}
+		break;
+	case GL_COLOR_CLEAR_VALUE:
+	case GL_BLEND_COLOR:
+		{
+			*type = GL_FLOAT;
+			*numParams = 4;
+		}
+		break;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+		*type = GL_FLOAT;
+		*numParams = 1;
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
+bool Context::applyRenderTarget()
+{
+	Framebuffer *framebuffer = getDrawFramebuffer();
+	int width, height, samples;
+
+	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+	}
+
+	Image *renderTarget = framebuffer->getRenderTarget();
+	device->setRenderTarget(0, renderTarget);
+	if(renderTarget) renderTarget->release();
+
+	Image *depthStencil = framebuffer->getDepthStencil();
+	device->setDepthStencilSurface(depthStencil);
+	if(depthStencil) depthStencil->release();
+
+	Viewport viewport;
+	float zNear = clamp01(mState.zNear);
+	float zFar = clamp01(mState.zFar);
+
+	viewport.x0 = mState.viewportX;
+	viewport.y0 = mState.viewportY;
+	viewport.width = mState.viewportWidth;
+	viewport.height = mState.viewportHeight;
+	viewport.minZ = zNear;
+	viewport.maxZ = zFar;
+
+	device->setViewport(viewport);
+
+	if(mState.scissorTestEnabled)
+	{
+		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
+		scissor.clip(0, 0, width, height);
+
+		device->setScissorRect(scissor);
+		device->setScissorEnable(true);
+	}
+	else
+	{
+		device->setScissorEnable(false);
+	}
+
+	Program *program = getCurrentProgram();
+
+	if(program)
+	{
+		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
+		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
+		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
+		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
+	}
+
+	return true;
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
+void Context::applyState(GLenum drawMode)
+{
+	Framebuffer *framebuffer = getDrawFramebuffer();
+
+	if(mState.cullFaceEnabled)
+	{
+		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
+	}
+	else
+	{
+		device->setCullMode(sw::CULL_NONE);
+	}
+
+	if(mDepthStateDirty)
+	{
+		if(mState.depthTestEnabled)
+		{
+			device->setDepthBufferEnable(true);
+			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
+		}
+		else
+		{
+			device->setDepthBufferEnable(false);
+		}
+
+		mDepthStateDirty = false;
+	}
+
+	if(mBlendStateDirty)
+	{
+		if(mState.blendEnabled)
+		{
+			device->setAlphaBlendEnable(true);
+			device->setSeparateAlphaBlendEnable(true);
+
+			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
+
+			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
+			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
+			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
+
+			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
+			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
+			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
+		}
+		else
+		{
+			device->setAlphaBlendEnable(false);
+		}
+
+		mBlendStateDirty = false;
+	}
+
+	if(mColorLogicOperatorDirty)
+	{
+		if(mState.colorLogicOpEnabled)
+		{
+			device->setColorLogicOpEnabled(true);
+			device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation));
+		}
+		else
+		{
+			device->setColorLogicOpEnabled(false);
+		}
+
+		mColorLogicOperatorDirty = false;
+	}
+
+	if(mStencilStateDirty || mFrontFaceDirty)
+	{
+		if(mState.stencilTestEnabled && framebuffer->hasStencil())
+		{
+			device->setStencilEnable(true);
+			device->setTwoSidedStencil(true);
+
+			if(mState.stencilWritemask != mState.stencilBackWritemask ||
+			   mState.stencilRef != mState.stencilBackRef ||
+			   mState.stencilMask != mState.stencilBackMask)
+			{
+				ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
+				return error(GL_INVALID_OPERATION);
+			}
+
+			// get the maximum size of the stencil ref
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
+
+			if(mState.frontFace == GL_CCW)
+			{
+				device->setStencilWriteMask(mState.stencilWritemask);
+				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+				device->setStencilMask(mState.stencilMask);
+
+				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
+				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+
+				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
+				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
+
+				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
+				device->setStencilMaskCCW(mState.stencilBackMask);
+
+				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
+				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
+				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
+			}
+			else
+			{
+				device->setStencilWriteMaskCCW(mState.stencilWritemask);
+				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+				device->setStencilMaskCCW(mState.stencilMask);
+
+				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
+				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+
+				device->setStencilWriteMask(mState.stencilBackWritemask);
+				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
+
+				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
+				device->setStencilMask(mState.stencilBackMask);
+
+				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
+				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
+				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
+			}
+		}
+		else
+		{
+			device->setStencilEnable(false);
+		}
+
+		mStencilStateDirty = false;
+		mFrontFaceDirty = false;
+	}
+
+	if(mMaskStateDirty)
+	{
+		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
+		device->setDepthWriteEnable(mState.depthMask);
+
+		mMaskStateDirty = false;
+	}
+
+	if(mPolygonOffsetStateDirty)
+	{
+		if(mState.polygonOffsetFillEnabled)
+		{
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+			if(depthbuffer)
+			{
+				device->setSlopeDepthBias(mState.polygonOffsetFactor);
+				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
+				device->setDepthBias(depthBias);
+			}
+		}
+		else
+		{
+			device->setSlopeDepthBias(0);
+			device->setDepthBias(0);
+		}
+
+		mPolygonOffsetStateDirty = false;
+	}
+
+	if(mSampleStateDirty)
+	{
+		if(mState.sampleAlphaToCoverageEnabled)
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
+		}
+		else
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
+		}
+
+		if(mState.sampleCoverageEnabled)
+		{
+			unsigned int mask = 0;
+			if(mState.sampleCoverageValue != 0)
+			{
+				int width, height, samples;
+				framebuffer->completeness(width, height, samples);
+
+				float threshold = 0.5f;
+
+				for(int i = 0; i < samples; i++)
+				{
+					mask <<= 1;
+
+					if((i + 1) * mState.sampleCoverageValue >= threshold)
+					{
+						threshold += 1.0f;
+						mask |= 1;
+					}
+				}
+			}
+
+			if(mState.sampleCoverageInvert)
+			{
+				mask = ~mask;
+			}
+
+			device->setMultiSampleMask(mask);
+		}
+		else
+		{
+			device->setMultiSampleMask(0xFFFFFFFF);
+		}
+
+		mSampleStateDirty = false;
+	}
+
+	if(mDitherStateDirty)
+	{
+	//	UNIMPLEMENTED();   // FIXME
+
+		mDitherStateDirty = false;
+	}
+}
+
+GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
+{
+	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
+
+	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
+	if(err != GL_NO_ERROR)
+	{
+		return err;
+	}
+
+	Program *program = getCurrentProgram();
+
+	device->resetInputStreams(false);
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(program && program->getAttributeStream(i) == -1)
+		{
+			continue;
+		}
+
+		sw::Resource *resource = attributes[i].vertexBuffer;
+		const void *buffer = (char*)resource->data() + attributes[i].offset;
+
+		int stride = attributes[i].stride;
+
+		buffer = (char*)buffer + stride * base;
+
+		sw::Stream attribute(resource, buffer, stride);
+
+		attribute.type = attributes[i].type;
+		attribute.count = attributes[i].count;
+		attribute.normalized = attributes[i].normalized;
+
+		int stream = program ? program->getAttributeStream(i) : i;
+		device->setInputStream(stream, attribute);
+	}
+
+	return GL_NO_ERROR;
+}
+
+// Applies the indices and element array bindings
+GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
+
+	if(err == GL_NO_ERROR)
+	{
+		device->setIndexBuffer(indexInfo->indexBuffer);
+	}
+
+	return err;
+}
+
+// Applies the shaders and shader constants
+void Context::applyShaders()
+{
+	Program *programObject = getCurrentProgram();
+	if(!programObject)
+	{
+		device->setVertexShader(0);
+		device->setPixelShader(0);
+		return;
+	}
+	sw::VertexShader *vertexShader = programObject->getVertexShader();
+	sw::PixelShader *pixelShader = programObject->getPixelShader();
+
+	device->setVertexShader(vertexShader);
+	device->setPixelShader(pixelShader);
+
+	if(programObject->getSerial() != mAppliedProgramSerial)
+	{
+		programObject->dirtyAllUniforms();
+		mAppliedProgramSerial = programObject->getSerial();
+	}
+
+	programObject->applyUniforms();
+}
+
+void Context::applyTextures()
+{
+	applyTextures(sw::SAMPLER_PIXEL);
+	//applyTextures(sw::SAMPLER_VERTEX);
+}
+
+void Context::applyTextures(sw::SamplerType samplerType)
+{
+	Program *programObject = getCurrentProgram();
+
+	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
+
+	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
+	{
+		int textureUnit = programObject ? programObject->getSamplerMapping(samplerType, samplerIndex) : samplerIndex;   // OpenGL texture image unit index
+
+		if(textureUnit != -1)
+		{
+			TextureType textureType = programObject ? programObject->getSamplerTextureType(samplerType, samplerIndex) : TEXTURE_2D;
+
+			Texture *texture = getSamplerTexture(textureUnit, textureType);
+
+			if(envEnable[samplerIndex] && texture->isSamplerComplete())
+			{
+				GLenum wrapS = texture->getWrapS();
+				GLenum wrapT = texture->getWrapT();
+				GLenum minFilter = texture->getMinFilter();
+				GLenum magFilter = texture->getMagFilter();
+				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
+
+				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
+				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
+
+				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
+				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
+				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
+
+				applyTexture(samplerType, samplerIndex, texture);
+
+				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE);
+				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
+				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
+				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
+
+				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE);
+				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
+				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
+				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
+
+				//device->setConstantColor(0, sw::Color<float>(0.0f, 0.0f, 0.0f, 0.0f));
+			}
+			else
+			{
+				applyTexture(samplerType, samplerIndex, nullptr);
+
+				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
+				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
+				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
+				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
+
+				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
+				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
+				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
+				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
+			}
+		}
+		else
+		{
+			applyTexture(samplerType, samplerIndex, nullptr);
+		}
+	}
+}
+
+void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
+{
+	Program *program = getCurrentProgram();
+	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
+	bool textureUsed = false;
+
+	if(type == sw::SAMPLER_PIXEL)
+	{
+		textureUsed = program ? program->getPixelShader()->usesSampler(index) : true;
+	}
+	else if(type == sw::SAMPLER_VERTEX)
+	{
+		textureUsed = program ? program->getVertexShader()->usesSampler(index) : false;
+	}
+	else UNREACHABLE(type);
+
+	sw::Resource *resource = nullptr;
+
+	if(baseTexture && textureUsed)
+	{
+		resource = baseTexture->getResource();
+	}
+
+	device->setTextureResource(sampler, resource);
+
+	if(baseTexture && textureUsed)
+	{
+		int levelCount = baseTexture->getLevelCount();
+
+		if(baseTexture->getTarget() == GL_TEXTURE_2D)
+		{
+			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
+
+			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+			{
+				int surfaceLevel = mipmapLevel;
+
+				if(surfaceLevel < 0)
+				{
+					surfaceLevel = 0;
+				}
+				else if(surfaceLevel >= levelCount)
+				{
+					surfaceLevel = levelCount - 1;
+				}
+
+				Image *surface = texture->getImage(surfaceLevel);
+				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
+			}
+		}
+		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
+		{
+			for(int face = 0; face < 6; face++)
+			{
+				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
+
+				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+				{
+					int surfaceLevel = mipmapLevel;
+
+					if(surfaceLevel < 0)
+					{
+						surfaceLevel = 0;
+					}
+					else if(surfaceLevel >= levelCount)
+					{
+						surfaceLevel = levelCount - 1;
+					}
+
+					Image *surface = cubeTexture->getImage(face, surfaceLevel);
+					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
+				}
+			}
+		}
+		else UNIMPLEMENTED();
+	}
+	else
+	{
+		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
+	}
+}
+
+void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+{
+	Framebuffer *framebuffer = getReadFramebuffer();
+	int framebufferWidth, framebufferHeight, framebufferSamples;
+
+	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+	}
+
+	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
+
+	// Sized query sanity check
+	if(bufSize)
+	{
+		int requiredSize = outputPitch * height;
+		if(requiredSize > *bufSize)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	Image *renderTarget = framebuffer->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	sw::Rect rect = {x, y, x + width, y + height};
+	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
+	unsigned char *dest = (unsigned char*)pixels;
+	unsigned short *dest16 = (unsigned short*)pixels;
+	int inputPitch = (int)renderTarget->getPitch();
+
+	for(int j = 0; j < rect.y1 - rect.y0; j++)
+	{
+		if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+		   format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
+		{
+			// Fast path for EXT_read_format_bgra, given an RGBA source buffer
+			// Note that buffers with no alpha go through the slow path below
+			memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);
+		}
+		else
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				float r;
+				float g;
+				float b;
+				float a;
+
+				switch(renderTarget->getInternalFormat())
+				{
+				case sw::FORMAT_R5G6B5:
+					{
+						unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
+
+						a = 1.0f;
+						b = (rgb & 0x001F) * (1.0f / 0x001F);
+						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
+						r = (rgb & 0xF800) * (1.0f / 0xF800);
+					}
+					break;
+				case sw::FORMAT_A1R5G5B5:
+					{
+						unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
+
+						a = (argb & 0x8000) ? 1.0f : 0.0f;
+						b = (argb & 0x001F) * (1.0f / 0x001F);
+						g = (argb & 0x03E0) * (1.0f / 0x03E0);
+						r = (argb & 0x7C00) * (1.0f / 0x7C00);
+					}
+					break;
+				case sw::FORMAT_A8R8G8B8:
+					{
+						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
+						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
+						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
+					}
+					break;
+				case sw::FORMAT_X8R8G8B8:
+					{
+						unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+						a = 1.0f;
+						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
+						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
+					}
+					break;
+				case sw::FORMAT_A2R10G10B10:
+					{
+						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
+						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
+						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
+						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
+					}
+					break;
+				case sw::FORMAT_A32B32G32R32F:
+					{
+						r = *((float*)(source + 16 * i + j * inputPitch) + 0);
+						g = *((float*)(source + 16 * i + j * inputPitch) + 1);
+						b = *((float*)(source + 16 * i + j * inputPitch) + 2);
+						a = *((float*)(source + 16 * i + j * inputPitch) + 3);
+					}
+					break;
+				case sw::FORMAT_A16B16G16R16F:
+					{
+						r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);
+						g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);
+						b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);
+						a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);
+					}
+					break;
+				default:
+					UNIMPLEMENTED();   // FIXME
+					UNREACHABLE(renderTarget->getInternalFormat());
+				}
+
+				switch(format)
+				{
+				case GL_RGBA:
+					switch(type)
+					{
+					case GL_UNSIGNED_BYTE:
+						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
+						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
+						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				case GL_BGRA_EXT:
+					switch(type)
+					{
+					case GL_UNSIGNED_BYTE:
+						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
+						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
+						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+						break;
+					case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+						// this type is packed as follows:
+						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+						//  --------------------------------------------------------------------------------
+						// |       4th         |        3rd         |        2nd        |   1st component   |
+						//  --------------------------------------------------------------------------------
+						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+						dest16[i + j * outputPitch / sizeof(unsigned short)] =
+							((unsigned short)(15 * a + 0.5f) << 12)|
+							((unsigned short)(15 * r + 0.5f) << 8) |
+							((unsigned short)(15 * g + 0.5f) << 4) |
+							((unsigned short)(15 * b + 0.5f) << 0);
+						break;
+					case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+						// this type is packed as follows:
+						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+						//  --------------------------------------------------------------------------------
+						// | 4th |          3rd           |           2nd          |      1st component     |
+						//  --------------------------------------------------------------------------------
+						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+						dest16[i + j * outputPitch / sizeof(unsigned short)] =
+							((unsigned short)(     a + 0.5f) << 15) |
+							((unsigned short)(31 * r + 0.5f) << 10) |
+							((unsigned short)(31 * g + 0.5f) << 5) |
+							((unsigned short)(31 * b + 0.5f) << 0);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				case GL_RGB:   // IMPLEMENTATION_COLOR_READ_FORMAT
+					switch(type)
+					{
+					case GL_UNSIGNED_SHORT_5_6_5:   // IMPLEMENTATION_COLOR_READ_TYPE
+						dest16[i + j * outputPitch / sizeof(unsigned short)] =
+							((unsigned short)(31 * b + 0.5f) << 0) |
+							((unsigned short)(63 * g + 0.5f) << 5) |
+							((unsigned short)(31 * r + 0.5f) << 11);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				default: UNREACHABLE(format);
+				}
+			}
+		}
+	}
+
+	renderTarget->unlock();
+	renderTarget->release();
+}
+
+void Context::clear(GLbitfield mask)
+{
+	Framebuffer *framebuffer = getDrawFramebuffer();
+
+	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	float depth = clamp01(mState.depthClearValue);
+	int stencil = mState.stencilClearValue & 0x000000FF;
+
+	if(mask & GL_COLOR_BUFFER_BIT)
+	{
+		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
+		                        (mState.colorMaskGreen ? 0x2 : 0) |
+		                        (mState.colorMaskBlue ? 0x4 : 0) |
+		                        (mState.colorMaskAlpha ? 0x8 : 0);
+
+		if(rgbaMask != 0)
+		{
+			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
+		}
+	}
+
+	if(mask & GL_DEPTH_BUFFER_BIT)
+	{
+		if(mState.depthMask != 0)
+		{
+			device->clearDepth(depth);
+		}
+	}
+
+	if(mask & GL_STENCIL_BUFFER_BIT)
+	{
+		if(mState.stencilWritemask != 0)
+		{
+			device->clearStencil(stencil, mState.stencilWritemask);
+		}
+	}
+}
+
+void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	if(!mState.currentProgram)
+	{
+		const sw::Matrix Z(1, 0, 0, 0,
+		                   0, 1, 0, 0,
+		                   0, 0, 0.5, 0.5,
+		                   0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]
+
+		device->setProjectionMatrix(Z * projection.current());
+		device->setViewMatrix(modelView.current());
+		device->setTextureMatrix(0, texture[0].current());
+		device->setTextureMatrix(1, texture[1].current());
+		device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
+		device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
+		device->setTexGen(0, sw::TEXGEN_NONE);
+		device->setTexGen(1, sw::TEXGEN_NONE);
+	}
+
+	PrimitiveType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	GLenum err = applyVertexBuffer(0, first, count);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	applyShaders();
+	applyTextures();
+
+	if(getCurrentProgram() && !getCurrentProgram()->validateSamplers(false))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(!cullSkipsDraw(mode))
+	{
+		device->drawPrimitive(primitiveType, primitiveCount);
+	}
+}
+
+void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+	if(!mState.currentProgram)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(!indices && !mState.elementArrayBuffer)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	PrimitiveType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	TranslatedIndexData indexInfo;
+	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	applyShaders();
+	applyTextures();
+
+	if(!getCurrentProgram()->validateSamplers(false))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(!cullSkipsDraw(mode))
+	{
+		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
+	}
+}
+
+void Context::finish()
+{
+	device->finish();
+}
+
+void Context::flush()
+{
+	// We don't queue anything without processing it as fast as possible
+}
+
+void Context::recordInvalidEnum()
+{
+	mInvalidEnum = true;
+}
+
+void Context::recordInvalidValue()
+{
+	mInvalidValue = true;
+}
+
+void Context::recordInvalidOperation()
+{
+	mInvalidOperation = true;
+}
+
+void Context::recordOutOfMemory()
+{
+	mOutOfMemory = true;
+}
+
+void Context::recordInvalidFramebufferOperation()
+{
+	mInvalidFramebufferOperation = true;
+}
+
+// Get one of the recorded errors and clear its flag, if any.
+GLenum Context::getError()
+{
+	if(mInvalidEnum)
+	{
+		mInvalidEnum = false;
+
+		return GL_INVALID_ENUM;
+	}
+
+	if(mInvalidValue)
+	{
+		mInvalidValue = false;
+
+		return GL_INVALID_VALUE;
+	}
+
+	if(mInvalidOperation)
+	{
+		mInvalidOperation = false;
+
+		return GL_INVALID_OPERATION;
+	}
+
+	if(mOutOfMemory)
+	{
+		mOutOfMemory = false;
+
+		return GL_OUT_OF_MEMORY;
+	}
+
+	if(mInvalidFramebufferOperation)
+	{
+		mInvalidFramebufferOperation = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION;
+	}
+
+	return GL_NO_ERROR;
+}
+
+int Context::getSupportedMultisampleCount(int requested)
+{
+	int supported = 0;
+
+	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
+	{
+		if(supported >= requested)
+		{
+			return supported;
+		}
+
+		supported = multisampleCount[i];
+	}
+
+	return supported;
+}
+
+void Context::detachBuffer(GLuint buffer)
+{
+	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
+	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
+
+	if(mState.arrayBuffer.name() == buffer)
+	{
+		mState.arrayBuffer = nullptr;
+	}
+
+	if(mState.elementArrayBuffer.name() == buffer)
+	{
+		mState.elementArrayBuffer = nullptr;
+	}
+
+	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+	{
+		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
+		{
+			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
+		}
+	}
+}
+
+void Context::detachTexture(GLuint texture)
+{
+	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
+	// rebound to texture object zero
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+		{
+			if(mState.samplerTexture[type][sampler].name() == texture)
+			{
+				mState.samplerTexture[type][sampler] = nullptr;
+			}
+		}
+	}
+
+	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
+	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
+	// image was attached in the currently bound framebuffer.
+
+	Framebuffer *readFramebuffer = getReadFramebuffer();
+	Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+	if(readFramebuffer)
+	{
+		readFramebuffer->detachTexture(texture);
+	}
+
+	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
+	{
+		drawFramebuffer->detachTexture(texture);
+	}
+}
+
+void Context::detachFramebuffer(GLuint framebuffer)
+{
+	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
+	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
+
+	if(mState.readFramebuffer == framebuffer)
+	{
+		bindReadFramebuffer(0);
+	}
+
+	if(mState.drawFramebuffer == framebuffer)
+	{
+		bindDrawFramebuffer(0);
+	}
+}
+
+void Context::detachRenderbuffer(GLuint renderbuffer)
+{
+	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
+	// had been executed with the target RENDERBUFFER and name of zero.
+
+	if(mState.renderbuffer.name() == renderbuffer)
+	{
+		bindRenderbuffer(0);
+	}
+
+	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
+	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
+	// point to which this image was attached in the currently bound framebuffer.
+
+	Framebuffer *readFramebuffer = getReadFramebuffer();
+	Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+	if(readFramebuffer)
+	{
+		readFramebuffer->detachRenderbuffer(renderbuffer);
+	}
+
+	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
+	{
+		drawFramebuffer->detachRenderbuffer(renderbuffer);
+	}
+}
+
+bool Context::cullSkipsDraw(GLenum drawMode)
+{
+	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
+}
+
+bool Context::isTriangleMode(GLenum drawMode)
+{
+	switch(drawMode)
+	{
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		return true;
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+		return false;
+	default: UNREACHABLE(drawMode);
+	}
+
+	return false;
+}
+
+void Context::setVertexAttrib(GLuint index, float x, float y, float z, float w)
+{
+	ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+	mState.vertexAttribute[index].mCurrentValue[0] = x;
+	mState.vertexAttribute[index].mCurrentValue[1] = y;
+	mState.vertexAttribute[index].mCurrentValue[2] = z;
+	mState.vertexAttribute[index].mCurrentValue[3] = w;
+
+	mVertexDataManager->dirtyCurrentValue(index);
+}
+
+void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                              GLbitfield mask)
+{
+	Framebuffer *readFramebuffer = getReadFramebuffer();
+	Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+	int readBufferWidth, readBufferHeight, readBufferSamples;
+	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
+
+	if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
+	   !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+	}
+
+	if(drawBufferSamples > 1)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	sw::SliceRect sourceRect;
+	sw::SliceRect destRect;
+
+	if(srcX0 < srcX1)
+	{
+		sourceRect.x0 = srcX0;
+		sourceRect.x1 = srcX1;
+		destRect.x0 = dstX0;
+		destRect.x1 = dstX1;
+	}
+	else
+	{
+		sourceRect.x0 = srcX1;
+		destRect.x0 = dstX1;
+		sourceRect.x1 = srcX0;
+		destRect.x1 = dstX0;
+	}
+
+	if(srcY0 < srcY1)
+	{
+		sourceRect.y0 = srcY0;
+		destRect.y0 = dstY0;
+		sourceRect.y1 = srcY1;
+		destRect.y1 = dstY1;
+	}
+	else
+	{
+		sourceRect.y0 = srcY1;
+		destRect.y0 = dstY1;
+		sourceRect.y1 = srcY0;
+		destRect.y1 = dstY0;
+	}
+
+	sw::Rect sourceScissoredRect = sourceRect;
+	sw::Rect destScissoredRect = destRect;
+
+	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
+	{
+		if(destRect.x0 < mState.scissorX)
+		{
+			int xDiff = mState.scissorX - destRect.x0;
+			destScissoredRect.x0 = mState.scissorX;
+			sourceScissoredRect.x0 += xDiff;
+		}
+
+		if(destRect.x1 > mState.scissorX + mState.scissorWidth)
+		{
+			int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
+			destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
+			sourceScissoredRect.x1 -= xDiff;
+		}
+
+		if(destRect.y0 < mState.scissorY)
+		{
+			int yDiff = mState.scissorY - destRect.y0;
+			destScissoredRect.y0 = mState.scissorY;
+			sourceScissoredRect.y0 += yDiff;
+		}
+
+		if(destRect.y1 > mState.scissorY + mState.scissorHeight)
+		{
+			int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
+			destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
+			sourceScissoredRect.y1 -= yDiff;
+		}
+	}
+
+	sw::Rect sourceTrimmedRect = sourceScissoredRect;
+	sw::Rect destTrimmedRect = destScissoredRect;
+
+	// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
+	// the actual draw and read surfaces.
+	if(sourceTrimmedRect.x0 < 0)
+	{
+		int xDiff = 0 - sourceTrimmedRect.x0;
+		sourceTrimmedRect.x0 = 0;
+		destTrimmedRect.x0 += xDiff;
+	}
+
+	if(sourceTrimmedRect.x1 > readBufferWidth)
+	{
+		int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
+		sourceTrimmedRect.x1 = readBufferWidth;
+		destTrimmedRect.x1 -= xDiff;
+	}
+
+	if(sourceTrimmedRect.y0 < 0)
+	{
+		int yDiff = 0 - sourceTrimmedRect.y0;
+		sourceTrimmedRect.y0 = 0;
+		destTrimmedRect.y0 += yDiff;
+	}
+
+	if(sourceTrimmedRect.y1 > readBufferHeight)
+	{
+		int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
+		sourceTrimmedRect.y1 = readBufferHeight;
+		destTrimmedRect.y1 -= yDiff;
+	}
+
+	if(destTrimmedRect.x0 < 0)
+	{
+		int xDiff = 0 - destTrimmedRect.x0;
+		destTrimmedRect.x0 = 0;
+		sourceTrimmedRect.x0 += xDiff;
+	}
+
+	if(destTrimmedRect.x1 > drawBufferWidth)
+	{
+		int xDiff = destTrimmedRect.x1 - drawBufferWidth;
+		destTrimmedRect.x1 = drawBufferWidth;
+		sourceTrimmedRect.x1 -= xDiff;
+	}
+
+	if(destTrimmedRect.y0 < 0)
+	{
+		int yDiff = 0 - destTrimmedRect.y0;
+		destTrimmedRect.y0 = 0;
+		sourceTrimmedRect.y0 += yDiff;
+	}
+
+	if(destTrimmedRect.y1 > drawBufferHeight)
+	{
+		int yDiff = destTrimmedRect.y1 - drawBufferHeight;
+		destTrimmedRect.y1 = drawBufferHeight;
+		sourceTrimmedRect.y1 -= yDiff;
+	}
+
+	bool partialBufferCopy = false;
+
+	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
+	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
+	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
+	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
+	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
+	{
+		partialBufferCopy = true;
+	}
+
+	bool blitRenderTarget = false;
+	bool blitDepthStencil = false;
+
+	if(mask & GL_COLOR_BUFFER_BIT)
+	{
+		const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
+		                           readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
+		const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
+		                           drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
+		if(!validReadType || !validDrawType ||
+		   readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())
+		{
+			ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(partialBufferCopy && readBufferSamples > 1)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		blitRenderTarget = true;
+	}
+
+	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+	{
+		Renderbuffer *readDSBuffer = nullptr;
+		Renderbuffer *drawDSBuffer = nullptr;
+
+		// We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
+		// both a depth and stencil buffer, it will be the same buffer.
+
+		if(mask & GL_DEPTH_BUFFER_BIT)
+		{
+			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
+			{
+				if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
+				   readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+
+				blitDepthStencil = true;
+				readDSBuffer = readFramebuffer->getDepthbuffer();
+				drawDSBuffer = drawFramebuffer->getDepthbuffer();
+			}
+		}
+
+		if(mask & GL_STENCIL_BUFFER_BIT)
+		{
+			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
+			{
+				if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
+				   readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+
+				blitDepthStencil = true;
+				readDSBuffer = readFramebuffer->getStencilbuffer();
+				drawDSBuffer = drawFramebuffer->getStencilbuffer();
+			}
+		}
+
+		if(partialBufferCopy)
+		{
+			ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
+			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
+		}
+
+		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
+		   (readDSBuffer && readDSBuffer->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	if(blitRenderTarget || blitDepthStencil)
+	{
+		if(blitRenderTarget)
+		{
+			Image *readRenderTarget = readFramebuffer->getRenderTarget();
+			Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
+
+			bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
+
+			readRenderTarget->release();
+			drawRenderTarget->release();
+
+			if(!success)
+			{
+				ERR("BlitFramebufferANGLE failed.");
+				return;
+			}
+		}
+
+		if(blitDepthStencil)
+		{
+			bool success = device->stretchRect(readFramebuffer->getDepthStencil(), nullptr, drawFramebuffer->getDepthStencil(), nullptr, false);
+
+			if(!success)
+			{
+				ERR("BlitFramebufferANGLE failed.");
+				return;
+			}
+		}
+	}
+}
+
+void Context::setMatrixMode(GLenum mode)
+{
+	matrixMode = mode;
+}
+
+sw::MatrixStack &Context::currentMatrixStack()
+{
+	switch(matrixMode)
+	{
+	case GL_MODELVIEW:  return modelView;                     break;
+	case GL_PROJECTION: return projection;                    break;
+	case GL_TEXTURE:    return texture[mState.activeSampler]; break;
+	default:            UNREACHABLE(matrixMode); return modelView;      break;
+	}
+}
+
+void Context::loadIdentity()
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().identity();
+}
+
+void Context::pushMatrix()
+{
+	//if(drawing)
+	//{
+	//    return error(GL_INVALID_OPERATION);
+	//}
+
+	if(!currentMatrixStack().push())
+	{
+		return error(GL_STACK_OVERFLOW);
+	}
+}
+
+void Context::popMatrix()
+{
+	//if(drawing)
+	//{
+	//    return error(GL_INVALID_OPERATION);
+	//}
+
+	if(!currentMatrixStack().pop())
+	{
+		return error(GL_STACK_OVERFLOW);
+	}
+}
+
+void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().rotate(angle, x, y, z);
+}
+
+void Context::translate(GLfloat x, GLfloat y, GLfloat z)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().translate(x, y, z);
+}
+
+void Context::scale(GLfloat x, GLfloat y, GLfloat z)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().scale(x, y, z);
+}
+
+void Context::multiply(const GLdouble *m)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().multiply(m);
+}
+
+void Context::multiply(const GLfloat *m)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().multiply(m);
+}
+
+void Context::frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
+}
+
+void Context::ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
+}
+
+void Context::setLightingEnabled(bool enable)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	device->setLightingEnable(enable);
+}
+
+void Context::setFogEnabled(bool enable)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	device->setFogEnable(enable);
+}
+
+void Context::setAlphaTestEnabled(bool enable)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	device->setAlphaTestEnable(enable);
+}
+
+void Context::alphaFunc(GLenum func, GLclampf ref)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	switch(func)
+	{
+	case GL_NEVER:    device->setAlphaCompare(sw::ALPHA_NEVER);        break;
+	case GL_LESS:     device->setAlphaCompare(sw::ALPHA_LESS);         break;
+	case GL_EQUAL:    device->setAlphaCompare(sw::ALPHA_EQUAL);        break;
+	case GL_LEQUAL:   device->setAlphaCompare(sw::ALPHA_LESSEQUAL);    break;
+	case GL_GREATER:  device->setAlphaCompare(sw::ALPHA_GREATER);      break;
+	case GL_NOTEQUAL: device->setAlphaCompare(sw::ALPHA_NOTEQUAL);     break;
+	case GL_GEQUAL:   device->setAlphaCompare(sw::ALPHA_GREATEREQUAL); break;
+	case GL_ALWAYS:   device->setAlphaCompare(sw::ALPHA_ALWAYS);       break;
+	default: UNREACHABLE(func);
+	}
+
+	device->setAlphaReference(gl::clamp01(ref));
+}
+
+void Context::setTexture2DEnabled(bool enable)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	envEnable[mState.activeSampler] = enable;
+}
+
+void Context::setShadeModel(GLenum mode)
+{
+	//if(drawing)
+	//{
+	//    return error(GL_INVALID_OPERATION);
+	//}
+
+	switch(mode)
+	{
+	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
+	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
+	default: return error(GL_INVALID_ENUM);
+	}
+}
+
+void Context::setLightEnabled(int index, bool enable)
+{
+	device->setLightEnable(index, enable);
+}
+
+void Context::setNormalizeNormalsEnabled(bool enable)
+{
+	device->setNormalizeNormals(enable);
+}
+
+GLuint Context::genLists(GLsizei range)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION, 0);
+	}
+
+	int firstIndex = std::max(1u, firstFreeIndex);
+	for(; true; firstIndex++)
+	{
+		int empty = 0;
+		for(; empty < range; empty++)
+		{
+			if(displayList[firstIndex + empty] != 0)
+			{
+				break;
+			}
+		}
+
+		if(empty == range)
+		{
+			for(int i = firstIndex; i < firstIndex + range; i++)
+			{
+				displayList[i] = new DisplayList();
+			}
+
+			if(firstIndex == firstFreeIndex)
+			{
+				firstFreeIndex = firstIndex + range;
+			}
+
+			return firstIndex;
+		}
+	}
+
+	return 0;
+}
+
+void Context::newList(GLuint list, GLenum mode)
+{
+	if(drawing || listIndex != 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	ASSERT(!this->list);
+	this->list = new DisplayList();
+
+	listIndex = list;
+	listMode = mode;
+}
+
+void Context::endList()
+{
+	if(drawing || listIndex == 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	ASSERT(list);
+	delete displayList[listIndex];
+	displayList[listIndex] = list;
+	list = 0;
+
+	listIndex = 0;
+	listMode = 0;
+}
+
+void Context::callList(GLuint list)
+{
+	// As per GL specifications, if the list does not exist, it is ignored
+	if(displayList[list])
+	{
+		displayList[list]->call();
+	}
+}
+
+void Context::deleteList(GLuint list)
+{
+	delete displayList[list];
+	displayList[list] = 0;
+	displayList.erase(list);
+	firstFreeIndex = std::min(firstFreeIndex , list);
+}
+
+void Context::listCommand(Command *command)
+{
+	ASSERT(list);
+	list->list.push_back(command);
+
+	if(listMode == GL_COMPILE_AND_EXECUTE)
+	{
+		listMode = 0;
+		command->call();
+		listMode = GL_COMPILE_AND_EXECUTE;
+	}
+}
+
+void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
+	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
+	      index, size, type, normalized, stride, ptr);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
+		context->setVertexAttribArrayEnabled(index, ptr != 0);
+	}
+}
+
+void Context::captureAttribs()
+{
+	memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute));
+}
+
+void Context::captureDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	ASSERT(first == 0);   // FIXME: UNIMPLEMENTED!
+
+	for(GLuint i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		GLint size = mState.vertexAttribute[i].mSize;
+		GLenum type = mState.vertexAttribute[i].mType;
+		GLboolean normalized = mState.vertexAttribute[i].mNormalized;
+		GLsizei stride = mState.vertexAttribute[i].mStride;
+		const GLvoid *pointer = mState.vertexAttribute[i].mPointer;
+
+		size_t length = count * mState.vertexAttribute[i].stride();
+
+		if(mState.vertexAttribute[i].mArrayEnabled)
+		{
+			ASSERT(pointer);   // FIXME: Add to condition?
+			const int padding = 1024;   // For SIMD processing of vertices   // FIXME: Still necessary?
+			void *buffer = new unsigned char[length + padding];
+			memcpy(buffer, pointer, length);
+
+			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)buffer));
+		}
+		else
+		{
+			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)0));
+		}
+	}
+}
+
+void Context::restoreAttribs()
+{
+	memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute));
+}
+
+void Context::clientActiveTexture(GLenum texture)
+{
+	clientTexture = texture;
+}
+
+GLenum Context::getClientActiveTexture() const
+{
+	return clientTexture;
+}
+
+unsigned int Context::getActiveTexture() const
+{
+	return mState.activeSampler;
+}
+
+void Context::begin(GLenum mode)
+{
+	if(drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	drawing = true;
+	drawMode = mode;
+
+	vertex.clear();
+}
+
+void Context::position(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	InVertex v;
+
+	v.P.x = x;
+	v.P.y = y;
+	v.P.z = z;
+	v.P.w = w;
+	v.C.x = mState.vertexAttribute[sw::Color0].mCurrentValue[0];
+	v.C.y = mState.vertexAttribute[sw::Color0].mCurrentValue[1];
+	v.C.z = mState.vertexAttribute[sw::Color0].mCurrentValue[2];
+	v.C.w = mState.vertexAttribute[sw::Color0].mCurrentValue[3];
+	v.N.x = mState.vertexAttribute[sw::Normal].mCurrentValue[0];
+	v.N.y = mState.vertexAttribute[sw::Normal].mCurrentValue[1];
+	v.N.z = mState.vertexAttribute[sw::Normal].mCurrentValue[2];
+	v.N.w = mState.vertexAttribute[sw::Normal].mCurrentValue[3];
+	v.T0.x = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0];
+	v.T0.y = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1];
+	v.T0.z = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2];
+	v.T0.w = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3];
+	v.T1.x = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0];
+	v.T1.y = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1];
+	v.T1.z = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2];
+	v.T1.w = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3];
+
+	vertex.push_back(v);
+}
+
+void Context::end()
+{
+	if(!drawing)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	const sw::Matrix Z(1, 0, 0, 0,
+	                   0, 1, 0, 0,
+	                   0, 0, 0.5, 0.5,
+	                   0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]
+
+	device->setProjectionMatrix(Z * projection.current());
+	device->setViewMatrix(modelView.current());
+	device->setTextureMatrix(0, texture[0].current());
+	device->setTextureMatrix(1, texture[1].current());
+	device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
+	device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
+
+	captureAttribs();
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mState.vertexAttribute[i].mArrayEnabled = false;
+	}
+
+	setVertexAttribState(sw::Position, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].P);
+	setVertexAttribState(sw::Normal, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].N);
+	setVertexAttribState(sw::Color0, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].C);
+	setVertexAttribState(sw::TexCoord0, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T0);
+	setVertexAttribState(sw::TexCoord1, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T1);
+
+	mState.vertexAttribute[sw::Position].mArrayEnabled = true;
+	mState.vertexAttribute[sw::Normal].mArrayEnabled = true;
+	mState.vertexAttribute[sw::Color0].mArrayEnabled = true;
+	mState.vertexAttribute[sw::TexCoord0].mArrayEnabled = true;
+	mState.vertexAttribute[sw::TexCoord1].mArrayEnabled = true;
+
+	applyState(drawMode);
+
+	GLenum err = applyVertexBuffer(0, 0, vertex.size());
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	applyTextures();
+
+	switch(drawMode)
+	{
+	case GL_POINTS:
+		UNIMPLEMENTED();
+		break;
+	case GL_LINES:
+		UNIMPLEMENTED();
+		break;
+	case GL_LINE_STRIP:
+		UNIMPLEMENTED();
+		break;
+	case GL_LINE_LOOP:
+		UNIMPLEMENTED();
+		break;
+	case GL_TRIANGLES:
+		UNIMPLEMENTED();
+		break;
+	case GL_TRIANGLE_STRIP:
+		device->drawPrimitive(DRAW_TRIANGLESTRIP, vertex.size() - 2);
+		break;
+	case GL_TRIANGLE_FAN:
+		UNIMPLEMENTED();
+		break;
+	case GL_QUADS:
+		UNIMPLEMENTED();
+		break;
+	case GL_QUAD_STRIP:
+		UNIMPLEMENTED();
+		break;
+	case GL_POLYGON:
+		UNIMPLEMENTED();
+		break;
+	default:
+		UNREACHABLE(drawMode);
+	}
+
+	restoreAttribs();
+
+	drawing = false;
+}
+
+void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled)
+{
+	if(mState.colorLogicOpEnabled != colorLogicOpEnabled)
+	{
+		mState.colorLogicOpEnabled = colorLogicOpEnabled;
+		mColorLogicOperatorDirty = true;
+	}
+}
+
+bool Context::isColorLogicOpEnabled()
+{
+	return mState.colorLogicOpEnabled;
+}
+
+void Context::setLogicalOperation(GLenum logicalOperation)
+{
+	if(mState.logicalOperation != logicalOperation)
+	{
+		mState.logicalOperation = logicalOperation;
+		mColorLogicOperatorDirty = true;
+	}
+}
+
+void Context::setColorMaterialEnabled(bool enable)
+{
+	device->setColorVertexEnable(enable);
+}
+
+void Context::setColorMaterialMode(GLenum mode)
+{
+	switch(mode)
+	{
+	case GL_EMISSION:
+		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
+		break;
+	case GL_AMBIENT:
+		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
+		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+		break;
+	case GL_DIFFUSE:
+		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
+		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+		break;
+	case GL_SPECULAR:
+		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
+		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+		break;
+	case GL_AMBIENT_AND_DIFFUSE:
+		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
+		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
+		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+		break;
+	default:
+		UNREACHABLE(mode);
+	}
+}
+
+Device *Context::getDevice()
+{
+	return device;
+}
+
+}
diff --git a/src/OpenGL/libGL/Context.h b/src/OpenGL/libGL/Context.h
index 74ecb6c..877d768 100644
--- a/src/OpenGL/libGL/Context.h
+++ b/src/OpenGL/libGL/Context.h
@@ -1,824 +1,827 @@
-// 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.

-//

-

-// Context.h: Defines the Context class, managing all GL state and performing

-// rendering operations.

-

-#ifndef LIBGL_CONTEXT_H_

-#define LIBGL_CONTEXT_H_

-

-#include "ResourceManager.h"

-#include "common/NameSpace.hpp"

-#include "common/Object.hpp"

-#include "Image.hpp"

-#include "Renderer/Sampler.hpp"

-#include "Renderer/Vertex.hpp"

-#include "common/MatrixStack.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#include <map>

-#include <list>

-#include <vector>

-

-namespace gl

-{

-	class Display;

-	class Surface;

-	class Config;

-

-	class Command

-	{

-	public:

-		Command() {};

-		virtual ~Command() {};

-

-		virtual void call() = 0;

-	};

-

-	class Command0 : public Command

-	{

-	public:

-		Command0(void (APIENTRY *function)())

-			: function(function)

-		{

-		}

-

-		virtual void call()

-		{

-			function();

-		}

-

-		void (APIENTRY *function)();

-	};

-

-	template<typename A1>

-	class Command1 : public Command

-	{

-	public:

-		Command1(void (APIENTRY *function)(A1), A1 arg1)

-			: function(function)

-			, argument1(arg1)

-		{

-		}

-

-		virtual void call()

-		{

-			function(argument1);

-		}

-

-		void (APIENTRY *function)(A1);

-		A1 argument1;

-	};

-

-	template<typename A1, typename A2>

-	class Command2 : public Command

-	{

-	public:

-		Command2(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)

-			: function(function)

-			, argument1(arg1)

-			, argument2(arg2)

-		{

-		}

-

-		virtual void call()

-		{

-			function(argument1, argument2);

-		}

-

-		void (APIENTRY *function)(A1, A2);

-		A1 argument1;

-		A2 argument2;

-	};

-

-    template<typename A1, typename A2, typename A3>

-	class Command3 : public Command

-	{

-	public:

-		Command3(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)

-			: function(function)

-			, argument1(arg1)

-			, argument2(arg2)

-            , argument3(arg3)

-		{

-		}

-

-		virtual void call()

-		{

-			function(argument1, argument2, argument3);

-		}

-

-		void (APIENTRY *function)(A1, A2, A3);

-		A1 argument1;

-		A2 argument2;

-        A3 argument3;

-	};

-

-	template<typename A1, typename A2, typename A3, typename A4>

-	class Command4 : public Command

-	{

-	public:

-		Command4(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)

-			: function(function)

-			, argument1(arg1)

-			, argument2(arg2)

-            , argument3(arg3)

-			, argument4(arg4)

-		{

-		}

-

-		virtual void call()

-		{

-			function(argument1, argument2, argument3, argument4);

-		}

-

-		void (APIENTRY *function)(A1, A2, A3, A4);

-		A1 argument1;

-		A2 argument2;

-        A3 argument3;

-		A4 argument4;

-	};

-

-	template<typename A1, typename A2, typename A3, typename A4, typename A5>

-	class Command5 : public Command

-	{

-	public:

-		Command5(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)

-			: function(function)

-			, argument1(arg1)

-			, argument2(arg2)

-            , argument3(arg3)

-			, argument4(arg4)

-			, argument5(arg5)

-		{

-		}

-

-		virtual void call()

-		{

-			function(argument1, argument2, argument3, argument4, argument5);

-		}

-

-		void (APIENTRY *function)(A1, A2, A3, A4, A5);

-		A1 argument1;

-		A2 argument2;

-        A3 argument3;

-		A4 argument4;

-		A5 argument5;

-	};

-

-	template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>

-	class Command6 : public Command

-	{

-	public:

-		Command6(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)

-			: function(function)

-			, argument1(arg1)

-			, argument2(arg2)

-            , argument3(arg3)

-			, argument4(arg4)

-			, argument5(arg5)

-			, argument6(arg6)

-		{

-		}

-

-		~Command6()

-		{

-			if(function == glVertexAttribArray)

-			{

-				delete[] argument6;

-			}

-		}

-

-		virtual void call()

-		{

-			function(argument1, argument2, argument3, argument4, argument5, argument6);

-		}

-

-		void (APIENTRY *function)(A1, A2, A3, A4, A5, A6);

-		A1 argument1;

-		A2 argument2;

-        A3 argument3;

-		A4 argument4;

-		A5 argument5;

-		A6 argument6;

-	};

-

-	inline Command0 *newCommand(void (APIENTRY *function)())

-	{

-		return new Command0(function);

-	}

-

-	template<typename A1>

-	Command1<A1> *newCommand(void (APIENTRY *function)(A1), A1 arg1)

-	{

-		return new Command1<A1>(function, arg1);

-	}

-

-	template<typename A1, typename A2>

-	Command2<A1, A2> *newCommand(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)

-	{

-		return new Command2<A1, A2>(function, arg1, arg2);

-	}

-

-    template<typename A1, typename A2, typename A3>

-	Command3<A1, A2, A3> *newCommand(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)

-	{

-		return new Command3<A1, A2, A3>(function, arg1, arg2, arg3);

-	}

-

-	template<typename A1, typename A2, typename A3, typename A4>

-	Command4<A1, A2, A3, A4> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)

-	{

-		return new Command4<A1, A2, A3, A4>(function, arg1, arg2, arg3, arg4);

-	}

-

-	template<typename A1, typename A2, typename A3, typename A4, typename A5>

-	Command5<A1, A2, A3, A4, A5> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)

-	{

-		return new Command5<A1, A2, A3, A4, A5>(function, arg1, arg2, arg3, arg4, arg5);

-	}

-

-	template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>

-	Command6<A1, A2, A3, A4, A5, A6> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)

-	{

-		return new Command6<A1, A2, A3, A4, A5, A6>(function, arg1, arg2, arg3, arg4, arg5, arg6);

-	}

-

-	class DisplayList

-	{

-	public:

-		DisplayList()

-		{

-		}

-

-		~DisplayList()

-		{

-			while(!list.empty())

-			{

-				delete list.back();

-				list.pop_back();

-			}

-		}

-

-		void call()

-		{

-			for(CommandList::iterator command = list.begin(); command != list.end(); command++)

-			{

-				(*command)->call();

-			}

-		}

-

-		typedef std::list<Command*> CommandList;

-		CommandList list;

-	};

-

-struct TranslatedAttribute;

-struct TranslatedIndexData;

-

-class Device;

-class Buffer;

-class Shader;

-class Program;

-class Texture;

-class Texture2D;

-class TextureCubeMap;

-class Framebuffer;

-class Renderbuffer;

-class RenderbufferStorage;

-class Colorbuffer;

-class Depthbuffer;

-class StreamingIndexBuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-class VertexDataManager;

-class IndexDataManager;

-class Fence;

-class Query;

-

-enum

-{

-    MAX_VERTEX_ATTRIBS = 9,

-	MAX_UNIFORM_VECTORS = 256,   // Device limit

-    MAX_VERTEX_UNIFORM_VECTORS = sw::VERTEX_UNIFORM_VECTORS - 3,   // Reserve space for gl_DepthRange

-    MAX_VARYING_VECTORS = 10,

-    MAX_TEXTURE_IMAGE_UNITS = 2,

-    MAX_VERTEX_TEXTURE_IMAGE_UNITS = 1,

-    MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,

-    MAX_FRAGMENT_UNIFORM_VECTORS = sw::FRAGMENT_UNIFORM_VECTORS - 3,    // Reserve space for gl_DepthRange

-    MAX_DRAW_BUFFERS = 1,

-

-    IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,

-    IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5

-};

-

-const GLenum compressedTextureFormats[] =

-{

-#if (S3TC_SUPPORT)

-	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,

-	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,

-	GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,

-	GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,

-#endif

-};

-

-const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);

-

-const GLint multisampleCount[] = {4, 2, 1};

-const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);

-const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];

-

-const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;

-const float ALIASED_LINE_WIDTH_RANGE_MAX = 128.0f;

-const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;

-const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;

-const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;

-

-enum QueryType

-{

-    QUERY_ANY_SAMPLES_PASSED,

-    QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE,

-

-    QUERY_TYPE_COUNT

-};

-

-struct Color

-{

-    float red;

-    float green;

-    float blue;

-    float alpha;

-};

-

-// Helper structure describing a single vertex attribute

-class VertexAttribute

-{

-  public:

-    VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)

-    {

-        mCurrentValue[0] = 0.0f;

-        mCurrentValue[1] = 0.0f;

-        mCurrentValue[2] = 0.0f;

-        mCurrentValue[3] = 1.0f;

-    }

-

-    int typeSize() const

-    {

-        switch(mType)

-        {

-        case GL_BYTE:           return mSize * sizeof(GLbyte);

-        case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);

-        case GL_SHORT:          return mSize * sizeof(GLshort);

-        case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);

-        case GL_FIXED:          return mSize * sizeof(GLfixed);

-        case GL_FLOAT:          return mSize * sizeof(GLfloat);

-        default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);

-        }

-    }

-

-    GLsizei stride() const

-    {

-        return mStride ? mStride : typeSize();

-    }

-

-    // From glVertexAttribPointer

-    GLenum mType;

-    GLint mSize;

-    bool mNormalized;

-    GLsizei mStride;   // 0 means natural stride

-

-    union

-    {

-        const void *mPointer;

-        intptr_t mOffset;

-    };

-

-    BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.

-

-    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray

-    float mCurrentValue[4];   // From glVertexAttrib

-};

-

-typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];

-

-// Helper structure to store all raw state

-struct State

-{

-    Color colorClearValue;

-    GLclampf depthClearValue;

-    int stencilClearValue;

-

-    bool cullFaceEnabled;

-    GLenum cullMode;

-    GLenum frontFace;

-    bool depthTestEnabled;

-    GLenum depthFunc;

-    bool blendEnabled;

-    GLenum sourceBlendRGB;

-    GLenum destBlendRGB;

-    GLenum sourceBlendAlpha;

-    GLenum destBlendAlpha;

-    GLenum blendEquationRGB;

-    GLenum blendEquationAlpha;

-    Color blendColor;

-    bool stencilTestEnabled;

-    GLenum stencilFunc;

-    GLint stencilRef;

-    GLuint stencilMask;

-    GLenum stencilFail;

-    GLenum stencilPassDepthFail;

-    GLenum stencilPassDepthPass;

-    GLuint stencilWritemask;

-    GLenum stencilBackFunc;

-    GLint stencilBackRef;

-    GLuint stencilBackMask;

-    GLenum stencilBackFail;

-    GLenum stencilBackPassDepthFail;

-    GLenum stencilBackPassDepthPass;

-    GLuint stencilBackWritemask;

-    bool polygonOffsetFillEnabled;

-    GLfloat polygonOffsetFactor;

-    GLfloat polygonOffsetUnits;

-    bool sampleAlphaToCoverageEnabled;

-    bool sampleCoverageEnabled;

-    GLclampf sampleCoverageValue;

-    bool sampleCoverageInvert;

-    bool scissorTestEnabled;

-    bool ditherEnabled;

-	bool colorLogicOpEnabled;

-	GLenum logicalOperation;

-

-    GLfloat lineWidth;

-

-    GLenum generateMipmapHint;

-    GLenum fragmentShaderDerivativeHint;

-

-    GLint viewportX;

-    GLint viewportY;

-    GLsizei viewportWidth;

-    GLsizei viewportHeight;

-    float zNear;

-    float zFar;

-

-    GLint scissorX;

-    GLint scissorY;

-    GLsizei scissorWidth;

-    GLsizei scissorHeight;

-

-    bool colorMaskRed;

-    bool colorMaskGreen;

-    bool colorMaskBlue;

-    bool colorMaskAlpha;

-    bool depthMask;

-

-    unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0

-    BindingPointer<Buffer> arrayBuffer;

-    BindingPointer<Buffer> elementArrayBuffer;

-    GLuint readFramebuffer;

-    GLuint drawFramebuffer;

-    BindingPointer<Renderbuffer> renderbuffer;

-    GLuint currentProgram;

-

-    VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];

-    BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];

-	BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];

-

-    GLint unpackAlignment;

-    GLint packAlignment;

-};

-

-class Context

-{

-public:

-    Context(const Context *shareContext);

-

-    ~Context();

-

-    void makeCurrent(Surface *surface);

-

-    void markAllStateDirty();

-

-    // State manipulation

-    void setClearColor(float red, float green, float blue, float alpha);

-    void setClearDepth(float depth);

-    void setClearStencil(int stencil);

-

-    void setCullFaceEnabled(bool enabled);

-    bool isCullFaceEnabled() const;

-    void setCullMode(GLenum mode);

-    void setFrontFace(GLenum front);

-

-    void setDepthTestEnabled(bool enabled);

-    bool isDepthTestEnabled() const;

-    void setDepthFunc(GLenum depthFunc);

-    void setDepthRange(float zNear, float zFar);

-

-    void setBlendEnabled(bool enabled);

-    bool isBlendEnabled() const;

-    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);

-    void setBlendColor(float red, float green, float blue, float alpha);

-    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);

-

-    void setStencilTestEnabled(bool enabled);

-    bool isStencilTestEnabled() const;

-    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);

-    void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);

-    void setStencilWritemask(GLuint stencilWritemask);

-    void setStencilBackWritemask(GLuint stencilBackWritemask);

-    void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);

-    void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);

-

-    void setPolygonOffsetFillEnabled(bool enabled);

-    bool isPolygonOffsetFillEnabled() const;

-    void setPolygonOffsetParams(GLfloat factor, GLfloat units);

-

-    void setSampleAlphaToCoverageEnabled(bool enabled);

-    bool isSampleAlphaToCoverageEnabled() const;

-    void setSampleCoverageEnabled(bool enabled);

-    bool isSampleCoverageEnabled() const;

-    void setSampleCoverageParams(GLclampf value, bool invert);

-

-    void setDitherEnabled(bool enabled);

-    bool isDitherEnabled() const;

-

-    void setLineWidth(GLfloat width);

-

-    void setGenerateMipmapHint(GLenum hint);

-    void setFragmentShaderDerivativeHint(GLenum hint);

-

-    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-	void setScissorTestEnabled(bool enabled);

-    bool isScissorTestEnabled() const;

-    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-    void setColorMask(bool red, bool green, bool blue, bool alpha);

-    void setDepthMask(bool mask);

-

-    void setActiveSampler(unsigned int active);

-

-    GLuint getReadFramebufferName() const;

-    GLuint getDrawFramebufferName() const;

-    GLuint getRenderbufferName() const;

-

-	GLuint getActiveQuery(GLenum target) const;

-

-    GLuint getArrayBufferName() const;

-

-    void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);

-    const VertexAttribute &getVertexAttribState(unsigned int attribNum);

-    void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,

-                              bool normalized, GLsizei stride, const void *pointer);

-    const void *getVertexAttribPointer(unsigned int attribNum) const;

-

-    const VertexAttributeArray &getVertexAttributes();

-

-    void setUnpackAlignment(GLint alignment);

-    GLint getUnpackAlignment() const;

-

-    void setPackAlignment(GLint alignment);

-    GLint getPackAlignment() const;

-

-    // These create  and destroy methods are merely pass-throughs to

-    // ResourceManager, which owns these object types

-    GLuint createBuffer();

-    GLuint createShader(GLenum type);

-    GLuint createProgram();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-

-    void deleteBuffer(GLuint buffer);

-    void deleteShader(GLuint shader);

-    void deleteProgram(GLuint program);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-

-    // Framebuffers are owned by the Context, so these methods do not pass through

-    GLuint createFramebuffer();

-    void deleteFramebuffer(GLuint framebuffer);

-

-    // Fences are owned by the Context

-    GLuint createFence();

-    void deleteFence(GLuint fence);

-

-	// Queries are owned by the Context

-    GLuint createQuery();

-    void deleteQuery(GLuint query);

-

-    void bindArrayBuffer(GLuint buffer);

-    void bindElementArrayBuffer(GLuint buffer);

-    void bindTexture2D(GLuint texture);

-    void bindTextureCubeMap(GLuint texture);

-    void bindReadFramebuffer(GLuint framebuffer);

-    void bindDrawFramebuffer(GLuint framebuffer);

-    void bindRenderbuffer(GLuint renderbuffer);

-    void useProgram(GLuint program);

-

-	void beginQuery(GLenum target, GLuint query);

-    void endQuery(GLenum target);

-

-    void setFramebufferZero(Framebuffer *framebuffer);

-

-    void setRenderbufferStorage(RenderbufferStorage *renderbuffer);

-

-    void setVertexAttrib(GLuint index, float x, float y, float z, float w);

-

-    Buffer *getBuffer(GLuint handle);

-    Fence *getFence(GLuint handle);

-    Shader *getShader(GLuint handle);

-    Program *getProgram(GLuint handle);

-    Texture *getTexture(GLuint handle);

-    Framebuffer *getFramebuffer(GLuint handle);

-    Renderbuffer *getRenderbuffer(GLuint handle);

-	Query *getQuery(GLuint handle, bool create, GLenum type);

-

-    Buffer *getArrayBuffer();

-    Buffer *getElementArrayBuffer();

-    Program *getCurrentProgram();

-    Texture2D *getTexture2D(GLenum target);

-    TextureCubeMap *getTextureCubeMap();

-    Texture *getSamplerTexture(unsigned int sampler, TextureType type);

-    Framebuffer *getReadFramebuffer();

-    Framebuffer *getDrawFramebuffer();

-

-    bool getFloatv(GLenum pname, GLfloat *params);

-    bool getIntegerv(GLenum pname, GLint *params);

-    bool getBooleanv(GLenum pname, GLboolean *params);

-

-    bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);

-

-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);

-    void clear(GLbitfield mask);

-    void drawArrays(GLenum mode, GLint first, GLsizei count);

-    void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);

-    void finish();

-    void flush();

-

-    void recordInvalidEnum();

-    void recordInvalidValue();

-    void recordInvalidOperation();

-    void recordOutOfMemory();

-    void recordInvalidFramebufferOperation();

-

-    GLenum getError();

-

-    static int getSupportedMultisampleCount(int requested);

-

-    void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,

-                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                         GLbitfield mask);

-

-    void setMatrixMode(GLenum mode);

-    void loadIdentity();

-    void pushMatrix();

-    void popMatrix();

-    void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

-    void translate(GLfloat x, GLfloat y, GLfloat z);

-	void scale(GLfloat x, GLfloat y, GLfloat z);

-	void multiply(const GLdouble *m);

-    void multiply(const GLfloat *m);

-	void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);

-    void ortho(double left, double right, double bottom, double top, double zNear, double zFar);   // FIXME: GLdouble

-

-    void setLightingEnabled(bool enabled);

-    void setFogEnabled(bool enabled);

-	void setAlphaTestEnabled(bool enabled);

-	void alphaFunc(GLenum func, GLclampf ref);

-    void setTexture2DEnabled(bool enabled);

-	void setShadeModel(GLenum mode);

-    void setLightEnabled(int index, bool enable);

-	void setNormalizeNormalsEnabled(bool enable);

-

-	GLuint genLists(GLsizei range);

-	void newList(GLuint list, GLenum mode);

-	void endList();

-	void callList(GLuint list);

-	void deleteList(GLuint list);

-	GLuint getListIndex() {return listIndex;}

-	GLenum getListMode() {return listMode;}

-	void listCommand(Command *command);

-

-	void captureAttribs();

-    void captureDrawArrays(GLenum mode, GLint first, GLsizei count);

-	void restoreAttribs();

-	void clientActiveTexture(GLenum texture);

-	GLenum getClientActiveTexture() const;

-	unsigned int getActiveTexture() const;

-

-    void begin(GLenum mode);

-    void position(GLfloat x, GLfloat y, GLfloat z, GLfloat w);

-    void end();

-

-    void setColorMaterialEnabled(bool enable);

-    void setColorMaterialMode(GLenum mode);

-

-	void setColorLogicOpEnabled(bool colorLogicOpEnabled);

-	bool isColorLogicOpEnabled();

-	void setLogicalOperation(GLenum logicalOperation);

-

-	Device *getDevice();

-

-private:

-    bool applyRenderTarget();

-    void applyState(GLenum drawMode);

-    GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);

-    GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);

-    void applyShaders();

-    void applyTextures();

-    void applyTextures(sw::SamplerType type);

-	void applyTexture(sw::SamplerType type, int sampler, Texture *texture);

-

-    void detachBuffer(GLuint buffer);

-    void detachTexture(GLuint texture);

-    void detachFramebuffer(GLuint framebuffer);

-    void detachRenderbuffer(GLuint renderbuffer);

-

-    bool cullSkipsDraw(GLenum drawMode);

-    bool isTriangleMode(GLenum drawMode);

-

-    State mState;

-

-    BindingPointer<Texture2D> mTexture2DZero;

-    BindingPointer<Texture2D> mProxyTexture2DZero;

-    BindingPointer<TextureCubeMap> mTextureCubeMapZero;

-

-	gl::NameSpace<Framebuffer> mFramebufferNameSpace;

-	gl::NameSpace<Fence, 0> mFenceNameSpace;

-	gl::NameSpace<Query> mQueryNameSpace;

-

-    VertexDataManager *mVertexDataManager;

-    IndexDataManager *mIndexDataManager;

-

-    // Recorded errors

-    bool mInvalidEnum;

-    bool mInvalidValue;

-    bool mInvalidOperation;

-    bool mOutOfMemory;

-    bool mInvalidFramebufferOperation;

-

-    bool mHasBeenCurrent;

-

-    unsigned int mAppliedProgramSerial;

-

-    // state caching flags

-    bool mDepthStateDirty;

-    bool mMaskStateDirty;

-    bool mPixelPackingStateDirty;

-    bool mBlendStateDirty;

-    bool mStencilStateDirty;

-    bool mPolygonOffsetStateDirty;

-    bool mSampleStateDirty;

-    bool mFrontFaceDirty;

-    bool mDitherStateDirty;

-	bool mColorLogicOperatorDirty;

-

-	Device *device;

-    ResourceManager *mResourceManager;

-

-	sw::MatrixStack &currentMatrixStack();

-	GLenum matrixMode;

-    sw::MatrixStack modelView;

-	sw::MatrixStack projection;

-	sw::MatrixStack texture[8];

-

-	GLenum listMode;

-	//std::map<GLuint, GLuint> listMap;

-	std::map<GLuint, DisplayList*> displayList;

-    DisplayList *list;

-	GLuint listIndex;

-	GLuint firstFreeIndex;

-

-	GLenum clientTexture;

-

-    bool drawing;

-    GLenum drawMode;

-

-	struct InVertex

-	{

-		sw::float4 P;    // Position

-		sw::float4 N;    // Normal

-		sw::float4 C;    // Color

-		sw::float4 T0;   // Texture coordinate

-		sw::float4 T1;

-	};

-

-    std::vector<InVertex> vertex;

-

-	VertexAttribute clientAttribute[MAX_VERTEX_ATTRIBS];

-

-    bool envEnable[8];

-};

-}

-

-#endif   // INCLUDE_CONTEXT_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Context.h: Defines the Context class, managing all GL state and performing
+// rendering operations.
+
+#ifndef LIBGL_CONTEXT_H_
+#define LIBGL_CONTEXT_H_
+
+#include "ResourceManager.h"
+#include "common/NameSpace.hpp"
+#include "common/Object.hpp"
+#include "Image.hpp"
+#include "Renderer/Sampler.hpp"
+#include "Renderer/Vertex.hpp"
+#include "common/MatrixStack.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#include <map>
+#include <list>
+#include <vector>
+
+namespace gl
+{
+	class Display;
+	class Surface;
+	class Config;
+
+	class Command
+	{
+	public:
+		Command() {};
+		virtual ~Command() {};
+
+		virtual void call() = 0;
+	};
+
+	class Command0 : public Command
+	{
+	public:
+		Command0(void (APIENTRY *function)())
+			: function(function)
+		{
+		}
+
+		virtual void call()
+		{
+			function();
+		}
+
+		void (APIENTRY *function)();
+	};
+
+	template<typename A1>
+	class Command1 : public Command
+	{
+	public:
+		Command1(void (APIENTRY *function)(A1), A1 arg1)
+			: function(function)
+			, argument1(arg1)
+		{
+		}
+
+		virtual void call()
+		{
+			function(argument1);
+		}
+
+		void (APIENTRY *function)(A1);
+		A1 argument1;
+	};
+
+	template<typename A1, typename A2>
+	class Command2 : public Command
+	{
+	public:
+		Command2(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)
+			: function(function)
+			, argument1(arg1)
+			, argument2(arg2)
+		{
+		}
+
+		virtual void call()
+		{
+			function(argument1, argument2);
+		}
+
+		void (APIENTRY *function)(A1, A2);
+		A1 argument1;
+		A2 argument2;
+	};
+
+	template<typename A1, typename A2, typename A3>
+	class Command3 : public Command
+	{
+	public:
+		Command3(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)
+			: function(function)
+			, argument1(arg1)
+			, argument2(arg2)
+			, argument3(arg3)
+		{
+		}
+
+		virtual void call()
+		{
+			function(argument1, argument2, argument3);
+		}
+
+		void (APIENTRY *function)(A1, A2, A3);
+		A1 argument1;
+		A2 argument2;
+		A3 argument3;
+	};
+
+	template<typename A1, typename A2, typename A3, typename A4>
+	class Command4 : public Command
+	{
+	public:
+		Command4(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)
+			: function(function)
+			, argument1(arg1)
+			, argument2(arg2)
+			, argument3(arg3)
+			, argument4(arg4)
+		{
+		}
+
+		virtual void call()
+		{
+			function(argument1, argument2, argument3, argument4);
+		}
+
+		void (APIENTRY *function)(A1, A2, A3, A4);
+		A1 argument1;
+		A2 argument2;
+		A3 argument3;
+		A4 argument4;
+	};
+
+	template<typename A1, typename A2, typename A3, typename A4, typename A5>
+	class Command5 : public Command
+	{
+	public:
+		Command5(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
+			: function(function)
+			, argument1(arg1)
+			, argument2(arg2)
+			, argument3(arg3)
+			, argument4(arg4)
+			, argument5(arg5)
+		{
+		}
+
+		virtual void call()
+		{
+			function(argument1, argument2, argument3, argument4, argument5);
+		}
+
+		void (APIENTRY *function)(A1, A2, A3, A4, A5);
+		A1 argument1;
+		A2 argument2;
+		A3 argument3;
+		A4 argument4;
+		A5 argument5;
+	};
+
+	template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+	class Command6 : public Command
+	{
+	public:
+		Command6(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)
+			: function(function)
+			, argument1(arg1)
+			, argument2(arg2)
+			, argument3(arg3)
+			, argument4(arg4)
+			, argument5(arg5)
+			, argument6(arg6)
+		{
+		}
+
+		~Command6()
+		{
+			if(function == glVertexAttribArray)
+			{
+				delete[] argument6;
+			}
+		}
+
+		virtual void call()
+		{
+			function(argument1, argument2, argument3, argument4, argument5, argument6);
+		}
+
+		void (APIENTRY *function)(A1, A2, A3, A4, A5, A6);
+		A1 argument1;
+		A2 argument2;
+		A3 argument3;
+		A4 argument4;
+		A5 argument5;
+		A6 argument6;
+	};
+
+	inline Command0 *newCommand(void (APIENTRY *function)())
+	{
+		return new Command0(function);
+	}
+
+	template<typename A1>
+	Command1<A1> *newCommand(void (APIENTRY *function)(A1), A1 arg1)
+	{
+		return new Command1<A1>(function, arg1);
+	}
+
+	template<typename A1, typename A2>
+	Command2<A1, A2> *newCommand(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)
+	{
+		return new Command2<A1, A2>(function, arg1, arg2);
+	}
+
+	template<typename A1, typename A2, typename A3>
+	Command3<A1, A2, A3> *newCommand(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)
+	{
+		return new Command3<A1, A2, A3>(function, arg1, arg2, arg3);
+	}
+
+	template<typename A1, typename A2, typename A3, typename A4>
+	Command4<A1, A2, A3, A4> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)
+	{
+		return new Command4<A1, A2, A3, A4>(function, arg1, arg2, arg3, arg4);
+	}
+
+	template<typename A1, typename A2, typename A3, typename A4, typename A5>
+	Command5<A1, A2, A3, A4, A5> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
+	{
+		return new Command5<A1, A2, A3, A4, A5>(function, arg1, arg2, arg3, arg4, arg5);
+	}
+
+	template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+	Command6<A1, A2, A3, A4, A5, A6> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)
+	{
+		return new Command6<A1, A2, A3, A4, A5, A6>(function, arg1, arg2, arg3, arg4, arg5, arg6);
+	}
+
+	class DisplayList
+	{
+	public:
+		DisplayList()
+		{
+		}
+
+		~DisplayList()
+		{
+			while(!list.empty())
+			{
+				delete list.back();
+				list.pop_back();
+			}
+		}
+
+		void call()
+		{
+			for(CommandList::iterator command = list.begin(); command != list.end(); command++)
+			{
+				(*command)->call();
+			}
+		}
+
+		typedef std::list<Command*> CommandList;
+		CommandList list;
+	};
+
+struct TranslatedAttribute;
+struct TranslatedIndexData;
+
+class Device;
+class Buffer;
+class Shader;
+class Program;
+class Texture;
+class Texture2D;
+class TextureCubeMap;
+class Framebuffer;
+class Renderbuffer;
+class RenderbufferStorage;
+class Colorbuffer;
+class Depthbuffer;
+class StreamingIndexBuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+class VertexDataManager;
+class IndexDataManager;
+class Fence;
+class Query;
+
+enum
+{
+	MAX_VERTEX_ATTRIBS = 9,
+	MAX_UNIFORM_VECTORS = 256,   // Device limit
+	MAX_VERTEX_UNIFORM_VECTORS = sw::VERTEX_UNIFORM_VECTORS - 3,   // Reserve space for gl_DepthRange
+	MAX_VARYING_VECTORS = 10,
+	MAX_TEXTURE_IMAGE_UNITS = 2,
+	MAX_VERTEX_TEXTURE_IMAGE_UNITS = 1,
+	MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,
+	MAX_FRAGMENT_UNIFORM_VECTORS = sw::FRAGMENT_UNIFORM_VECTORS - 3,    // Reserve space for gl_DepthRange
+	MAX_DRAW_BUFFERS = 1,
+
+	IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
+	IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
+};
+
+const GLenum compressedTextureFormats[] =
+{
+#if (S3TC_SUPPORT)
+	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+	GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+	GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+#endif
+};
+
+const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
+
+const GLint multisampleCount[] = {4, 2, 1};
+const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);
+const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];
+
+const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
+const float ALIASED_LINE_WIDTH_RANGE_MAX = 128.0f;
+const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;
+const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;
+const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;
+
+enum QueryType
+{
+	QUERY_ANY_SAMPLES_PASSED,
+	QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE,
+
+	QUERY_TYPE_COUNT
+};
+
+struct Color
+{
+	float red;
+	float green;
+	float blue;
+	float alpha;
+};
+
+// Helper structure describing a single vertex attribute
+class VertexAttribute
+{
+public:
+	VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(nullptr), mArrayEnabled(false)
+	{
+		mCurrentValue[0] = 0.0f;
+		mCurrentValue[1] = 0.0f;
+		mCurrentValue[2] = 0.0f;
+		mCurrentValue[3] = 1.0f;
+	}
+
+	int typeSize() const
+	{
+		switch(mType)
+		{
+		case GL_BYTE:           return mSize * sizeof(GLbyte);
+		case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);
+		case GL_SHORT:          return mSize * sizeof(GLshort);
+		case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
+		case GL_FIXED:          return mSize * sizeof(GLfixed);
+		case GL_FLOAT:          return mSize * sizeof(GLfloat);
+		default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);
+		}
+	}
+
+	GLsizei stride() const
+	{
+		return mStride ? mStride : typeSize();
+	}
+
+	// From glVertexAttribPointer
+	GLenum mType;
+	GLint mSize;
+	bool mNormalized;
+	GLsizei mStride;   // 0 means natural stride
+
+	union
+	{
+		const void *mPointer;
+		intptr_t mOffset;
+	};
+
+	BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
+
+	bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
+	float mCurrentValue[4];   // From glVertexAttrib
+};
+
+typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
+
+// Helper structure to store all raw state
+struct State
+{
+	Color colorClearValue;
+	GLclampf depthClearValue;
+	int stencilClearValue;
+
+	bool cullFaceEnabled;
+	GLenum cullMode;
+	GLenum frontFace;
+	bool depthTestEnabled;
+	GLenum depthFunc;
+	bool blendEnabled;
+	GLenum sourceBlendRGB;
+	GLenum destBlendRGB;
+	GLenum sourceBlendAlpha;
+	GLenum destBlendAlpha;
+	GLenum blendEquationRGB;
+	GLenum blendEquationAlpha;
+	Color blendColor;
+	bool stencilTestEnabled;
+	GLenum stencilFunc;
+	GLint stencilRef;
+	GLuint stencilMask;
+	GLenum stencilFail;
+	GLenum stencilPassDepthFail;
+	GLenum stencilPassDepthPass;
+	GLuint stencilWritemask;
+	GLenum stencilBackFunc;
+	GLint stencilBackRef;
+	GLuint stencilBackMask;
+	GLenum stencilBackFail;
+	GLenum stencilBackPassDepthFail;
+	GLenum stencilBackPassDepthPass;
+	GLuint stencilBackWritemask;
+	bool polygonOffsetFillEnabled;
+	GLfloat polygonOffsetFactor;
+	GLfloat polygonOffsetUnits;
+	bool sampleAlphaToCoverageEnabled;
+	bool sampleCoverageEnabled;
+	GLclampf sampleCoverageValue;
+	bool sampleCoverageInvert;
+	bool scissorTestEnabled;
+	bool ditherEnabled;
+	bool colorLogicOpEnabled;
+	GLenum logicalOperation;
+
+	GLfloat lineWidth;
+
+	GLenum generateMipmapHint;
+	GLenum fragmentShaderDerivativeHint;
+
+	GLint viewportX;
+	GLint viewportY;
+	GLsizei viewportWidth;
+	GLsizei viewportHeight;
+	float zNear;
+	float zFar;
+
+	GLint scissorX;
+	GLint scissorY;
+	GLsizei scissorWidth;
+	GLsizei scissorHeight;
+
+	bool colorMaskRed;
+	bool colorMaskGreen;
+	bool colorMaskBlue;
+	bool colorMaskAlpha;
+	bool depthMask;
+
+	unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0
+	BindingPointer<Buffer> arrayBuffer;
+	BindingPointer<Buffer> elementArrayBuffer;
+	GLuint readFramebuffer;
+	GLuint drawFramebuffer;
+	BindingPointer<Renderbuffer> renderbuffer;
+	GLuint currentProgram;
+
+	VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
+	BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+	BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
+
+	GLint unpackAlignment;
+	GLint packAlignment;
+};
+
+class Context
+{
+public:
+	Context(const Context *shareContext);
+
+	~Context();
+
+	void makeCurrent(Surface *surface);
+
+	void markAllStateDirty();
+
+	// State manipulation
+	void setClearColor(float red, float green, float blue, float alpha);
+	void setClearDepth(float depth);
+	void setClearStencil(int stencil);
+
+	void setCullFaceEnabled(bool enabled);
+	bool isCullFaceEnabled() const;
+	void setCullMode(GLenum mode);
+	void setFrontFace(GLenum front);
+
+	void setDepthTestEnabled(bool enabled);
+	bool isDepthTestEnabled() const;
+	void setDepthFunc(GLenum depthFunc);
+	void setDepthRange(float zNear, float zFar);
+
+	void setBlendEnabled(bool enabled);
+	bool isBlendEnabled() const;
+	void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
+	void setBlendColor(float red, float green, float blue, float alpha);
+	void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
+
+	void setStencilTestEnabled(bool enabled);
+	bool isStencilTestEnabled() const;
+	void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
+	void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
+	void setStencilWritemask(GLuint stencilWritemask);
+	void setStencilBackWritemask(GLuint stencilBackWritemask);
+	void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
+	void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);
+
+	void setPolygonOffsetFillEnabled(bool enabled);
+	bool isPolygonOffsetFillEnabled() const;
+	void setPolygonOffsetParams(GLfloat factor, GLfloat units);
+
+	void setSampleAlphaToCoverageEnabled(bool enabled);
+	bool isSampleAlphaToCoverageEnabled() const;
+	void setSampleCoverageEnabled(bool enabled);
+	bool isSampleCoverageEnabled() const;
+	void setSampleCoverageParams(GLclampf value, bool invert);
+
+	void setDitherEnabled(bool enabled);
+	bool isDitherEnabled() const;
+
+	void setLineWidth(GLfloat width);
+
+	void setGenerateMipmapHint(GLenum hint);
+	void setFragmentShaderDerivativeHint(GLenum hint);
+
+	void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setScissorTestEnabled(bool enabled);
+	bool isScissorTestEnabled() const;
+	void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setColorMask(bool red, bool green, bool blue, bool alpha);
+	void setDepthMask(bool mask);
+
+	void setActiveSampler(unsigned int active);
+
+	GLuint getReadFramebufferName() const;
+	GLuint getDrawFramebufferName() const;
+	GLuint getRenderbufferName() const;
+
+	GLuint getActiveQuery(GLenum target) const;
+
+	GLuint getArrayBufferName() const;
+
+	void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);
+	const VertexAttribute &getVertexAttribState(unsigned int attribNum);
+	void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
+	                          bool normalized, GLsizei stride, const void *pointer);
+	const void *getVertexAttribPointer(unsigned int attribNum) const;
+
+	const VertexAttributeArray &getVertexAttributes();
+
+	void setUnpackAlignment(GLint alignment);
+	GLint getUnpackAlignment() const;
+
+	void setPackAlignment(GLint alignment);
+	GLint getPackAlignment() const;
+
+	// These create  and destroy methods are merely pass-throughs to
+	// ResourceManager, which owns these object types
+	GLuint createBuffer();
+	GLuint createShader(GLenum type);
+	GLuint createProgram();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+
+	void deleteBuffer(GLuint buffer);
+	void deleteShader(GLuint shader);
+	void deleteProgram(GLuint program);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+
+	// Framebuffers are owned by the Context, so these methods do not pass through
+	GLuint createFramebuffer();
+	void deleteFramebuffer(GLuint framebuffer);
+
+	// Fences are owned by the Context
+	GLuint createFence();
+	void deleteFence(GLuint fence);
+
+	// Queries are owned by the Context
+	GLuint createQuery();
+	void deleteQuery(GLuint query);
+
+	void bindArrayBuffer(GLuint buffer);
+	void bindElementArrayBuffer(GLuint buffer);
+	void bindTexture2D(GLuint texture);
+	void bindTextureCubeMap(GLuint texture);
+	void bindReadFramebuffer(GLuint framebuffer);
+	void bindDrawFramebuffer(GLuint framebuffer);
+	void bindRenderbuffer(GLuint renderbuffer);
+	void useProgram(GLuint program);
+
+	void beginQuery(GLenum target, GLuint query);
+	void endQuery(GLenum target);
+
+	void setFramebufferZero(Framebuffer *framebuffer);
+
+	void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
+
+	void setVertexAttrib(GLuint index, float x, float y, float z, float w);
+
+	Buffer *getBuffer(GLuint handle);
+	Fence *getFence(GLuint handle);
+	Shader *getShader(GLuint handle);
+	Program *getProgram(GLuint handle);
+	Texture *getTexture(GLuint handle);
+	Framebuffer *getFramebuffer(GLuint handle);
+	Renderbuffer *getRenderbuffer(GLuint handle);
+	Query *getQuery(GLuint handle, bool create, GLenum type);
+
+	Buffer *getArrayBuffer();
+	Buffer *getElementArrayBuffer();
+	Program *getCurrentProgram();
+	Texture2D *getTexture2D(GLenum target);
+	TextureCubeMap *getTextureCubeMap();
+	Texture *getSamplerTexture(unsigned int sampler, TextureType type);
+	Framebuffer *getReadFramebuffer();
+	Framebuffer *getDrawFramebuffer();
+
+	bool getFloatv(GLenum pname, GLfloat *params);
+	bool getIntegerv(GLenum pname, GLint *params);
+	bool getBooleanv(GLenum pname, GLboolean *params);
+
+	bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
+
+	void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
+	void clear(GLbitfield mask);
+	void drawArrays(GLenum mode, GLint first, GLsizei count);
+	void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
+	void finish();
+	void flush();
+
+	void recordInvalidEnum();
+	void recordInvalidValue();
+	void recordInvalidOperation();
+	void recordOutOfMemory();
+	void recordInvalidFramebufferOperation();
+
+	GLenum getError();
+
+	static int getSupportedMultisampleCount(int requested);
+
+	void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+	                     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+	                     GLbitfield mask);
+
+	void setMatrixMode(GLenum mode);
+	void loadIdentity();
+	void pushMatrix();
+	void popMatrix();
+	void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+	void translate(GLfloat x, GLfloat y, GLfloat z);
+	void scale(GLfloat x, GLfloat y, GLfloat z);
+	void multiply(const GLdouble *m);
+	void multiply(const GLfloat *m);
+	void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+	void ortho(double left, double right, double bottom, double top, double zNear, double zFar);   // FIXME: GLdouble
+
+	void setLightingEnabled(bool enabled);
+	void setFogEnabled(bool enabled);
+	void setAlphaTestEnabled(bool enabled);
+	void alphaFunc(GLenum func, GLclampf ref);
+	void setTexture2DEnabled(bool enabled);
+	void setShadeModel(GLenum mode);
+	void setLightEnabled(int index, bool enable);
+	void setNormalizeNormalsEnabled(bool enable);
+
+	GLuint genLists(GLsizei range);
+	void newList(GLuint list, GLenum mode);
+	void endList();
+	void callList(GLuint list);
+	void deleteList(GLuint list);
+	GLuint getListIndex() {return listIndex;}
+	GLenum getListMode() {return listMode;}
+	void listCommand(Command *command);
+
+	void captureAttribs();
+	void captureDrawArrays(GLenum mode, GLint first, GLsizei count);
+	void restoreAttribs();
+	void clientActiveTexture(GLenum texture);
+	GLenum getClientActiveTexture() const;
+	unsigned int getActiveTexture() const;
+
+	void begin(GLenum mode);
+	void position(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+	void end();
+
+	void setColorMaterialEnabled(bool enable);
+	void setColorMaterialMode(GLenum mode);
+
+	void setColorLogicOpEnabled(bool colorLogicOpEnabled);
+	bool isColorLogicOpEnabled();
+	void setLogicalOperation(GLenum logicalOperation);
+
+	Device *getDevice();
+
+private:
+	bool applyRenderTarget();
+	void applyState(GLenum drawMode);
+	GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);
+	GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+	void applyShaders();
+	void applyTextures();
+	void applyTextures(sw::SamplerType type);
+	void applyTexture(sw::SamplerType type, int sampler, Texture *texture);
+
+	void detachBuffer(GLuint buffer);
+	void detachTexture(GLuint texture);
+	void detachFramebuffer(GLuint framebuffer);
+	void detachRenderbuffer(GLuint renderbuffer);
+
+	bool cullSkipsDraw(GLenum drawMode);
+	bool isTriangleMode(GLenum drawMode);
+
+	State mState;
+
+	BindingPointer<Texture2D> mTexture2DZero;
+	BindingPointer<Texture2D> mProxyTexture2DZero;
+	BindingPointer<TextureCubeMap> mTextureCubeMapZero;
+
+	gl::NameSpace<Framebuffer> mFramebufferNameSpace;
+	gl::NameSpace<Fence, 0> mFenceNameSpace;
+	gl::NameSpace<Query> mQueryNameSpace;
+
+	VertexDataManager *mVertexDataManager;
+	IndexDataManager *mIndexDataManager;
+
+	// Recorded errors
+	bool mInvalidEnum;
+	bool mInvalidValue;
+	bool mInvalidOperation;
+	bool mOutOfMemory;
+	bool mInvalidFramebufferOperation;
+
+	bool mHasBeenCurrent;
+
+	unsigned int mAppliedProgramSerial;
+
+	// state caching flags
+	bool mDepthStateDirty;
+	bool mMaskStateDirty;
+	bool mPixelPackingStateDirty;
+	bool mBlendStateDirty;
+	bool mStencilStateDirty;
+	bool mPolygonOffsetStateDirty;
+	bool mSampleStateDirty;
+	bool mFrontFaceDirty;
+	bool mDitherStateDirty;
+	bool mColorLogicOperatorDirty;
+
+	Device *device;
+	ResourceManager *mResourceManager;
+
+	sw::MatrixStack &currentMatrixStack();
+	GLenum matrixMode;
+	sw::MatrixStack modelView;
+	sw::MatrixStack projection;
+	sw::MatrixStack texture[8];
+
+	GLenum listMode;
+	//std::map<GLuint, GLuint> listMap;
+	std::map<GLuint, DisplayList*> displayList;
+	DisplayList *list;
+	GLuint listIndex;
+	GLuint firstFreeIndex;
+
+	GLenum clientTexture;
+
+	bool drawing;
+	GLenum drawMode;
+
+	struct InVertex
+	{
+		sw::float4 P;    // Position
+		sw::float4 N;    // Normal
+		sw::float4 C;    // Color
+		sw::float4 T0;   // Texture coordinate
+		sw::float4 T1;
+	};
+
+	std::vector<InVertex> vertex;
+
+	VertexAttribute clientAttribute[MAX_VERTEX_ATTRIBS];
+
+	bool envEnable[8];
+};
+}
+
+#endif   // INCLUDE_CONTEXT_H_
diff --git a/src/OpenGL/libGL/Device.cpp b/src/OpenGL/libGL/Device.cpp
index cdc9db7..2070e27 100644
--- a/src/OpenGL/libGL/Device.cpp
+++ b/src/OpenGL/libGL/Device.cpp
@@ -1,760 +1,763 @@
-// 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.

-//

-

-#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"

-

-namespace gl

-{

-	using namespace sw;

-

-	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)

-	{

-		depthStencil = 0;

-		renderTarget = 0;

-

-		setDepthBufferEnable(true);

-		setFillMode(FILL_SOLID);

-		setShadingMode(SHADING_GOURAUD);

-		setDepthWriteEnable(true);

-		setAlphaTestEnable(false);

-		setSourceBlendFactor(BLEND_ONE);

-		setDestBlendFactor(BLEND_ZERO);

-		setCullMode(CULL_COUNTERCLOCKWISE);

-		setDepthCompare(DEPTH_LESSEQUAL);

-		setAlphaReference(0.0f);

-		setAlphaCompare(ALPHA_ALWAYS);

-		setAlphaBlendEnable(false);

-		setFogEnable(false);

-		setSpecularEnable(false);

-		setFogColor(0);

-		setPixelFogMode(FOG_NONE);

-		setFogStart(0.0f);

-		setFogEnd(1.0f);

-		setFogDensity(1.0f);

-		setRangeFogEnable(false);

-		setStencilEnable(false);

-		setStencilFailOperation(OPERATION_KEEP);

-		setStencilZFailOperation(OPERATION_KEEP);

-		setStencilPassOperation(OPERATION_KEEP);

-		setStencilCompare(STENCIL_ALWAYS);

-		setStencilReference(0);

-		setStencilMask(0xFFFFFFFF);

-		setStencilWriteMask(0xFFFFFFFF);

-		setVertexFogMode(FOG_NONE);

-		setClipFlags(0);

-		setPointSize(1.0f);

-		setPointSizeMin(0.125f);

-        setPointSizeMax(8192.0f);

-		setColorWriteMask(0, 0x0000000F);

-		setBlendOperation(BLENDOP_ADD);

-		scissorEnable = false;

-		setSlopeDepthBias(0.0f);

-		setTwoSidedStencil(false);

-		setStencilFailOperationCCW(OPERATION_KEEP);

-		setStencilZFailOperationCCW(OPERATION_KEEP);

-		setStencilPassOperationCCW(OPERATION_KEEP);

-		setStencilCompareCCW(STENCIL_ALWAYS);

-		setColorWriteMask(1, 0x0000000F);

-		setColorWriteMask(2, 0x0000000F);

-		setColorWriteMask(3, 0x0000000F);

-		setBlendConstant(0xFFFFFFFF);

-		setWriteSRGB(false);

-		setDepthBias(0.0f);

-		setSeparateAlphaBlendEnable(false);

-		setSourceBlendFactorAlpha(BLEND_ONE);

-		setDestBlendFactorAlpha(BLEND_ZERO);

-		setBlendOperationAlpha(BLENDOP_ADD);

-		setPointSpriteEnable(true);

-		setColorLogicOpEnabled(false);

-		setLogicalOperation(LOGICALOP_COPY);

-

-		for(int i = 0; i < 16; i++)

-		{

-			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);

-			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);

-			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);

-			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);

-		}

-

-		for(int i = 0; i < 4; i++)

-		{

-			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);

-			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);

-			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);

-			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);

-		}

-

-		for(int i = 0; i < 6; i++)

-		{

-			float plane[4] = {0, 0, 0, 0};

-

-			setClipPlane(i, plane);

-		}

-

-		pixelShader = 0;

-		vertexShader = 0;

-

-		pixelShaderDirty = true;

-		pixelShaderConstantsFDirty = 0;

-		vertexShaderDirty = true;

-		vertexShaderConstantsFDirty = 0;

-

-		for(int i = 0; i < FRAGMENT_UNIFORM_VECTORS; i++)

-		{

-			float zero[4] = {0, 0, 0, 0};

-

-			setPixelShaderConstantF(i, zero, 1);

-		}

-

-		for(int i = 0; i < VERTEX_UNIFORM_VECTORS; i++)

-		{

-			float zero[4] = {0, 0, 0, 0};

-

-			setVertexShaderConstantF(i, zero, 1);

-		}

-

-		setLightingEnable(false);

-

-		setGlobalAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f));

-		setMaterialAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f));

-		setMaterialDiffuse(sw::Color<float>(0.8f, 0.8f, 0.8f, 1.0f));

-		setMaterialSpecular(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f));

-		setMaterialEmission(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f));

-

-		for(int i = 0; i < 8; i++)

-		{

-			setLightEnable(i, false);

-			setLightAttenuation(i, 1.0f, 0.0f, 0.0f);

-		}

-

-        setDiffuseMaterialSource(sw::MATERIAL_COLOR1);

-        setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-        setAmbientMaterialSource(sw::MATERIAL_COLOR1);

-        setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-	}

-

-	Device::~Device()

-	{

-		if(depthStencil)

-		{

-			depthStencil->release();

-			depthStencil = 0;

-		}

-

-		if(renderTarget)

-		{

-			renderTarget->release();

-			renderTarget = 0;

-		}

-

-		delete context;

-	}

-

-	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)

-	{

-		if(!renderTarget || !rgbaMask)

-		{

-			return;

-		}

-

-		sw::SliceRect clearRect = renderTarget->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		float rgba[4];

-		rgba[0] = red;

-		rgba[1] = green;

-		rgba[2] = blue;

-		rgba[3] = alpha;

-

-		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);

-	}

-

-	void Device::clearDepth(float z)

-	{

-		if(!depthStencil)

-		{

-			return;

-		}

-

-		z = clamp01(z);

-		sw::SliceRect clearRect = depthStencil->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	void Device::clearStencil(unsigned int stencil, unsigned int mask)

-	{

-		if(!depthStencil)

-		{

-			return;

-		}

-

-		sw::SliceRect clearRect = depthStencil->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		depthStencil->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return 0;

-		}

-

-		bool lockable = true;

-

-		switch(format)

-		{

-	//	case FORMAT_D15S1:

-		case FORMAT_D24S8:

-		case FORMAT_D24X8:

-	//	case FORMAT_D24X4S4:

-		case FORMAT_D24FS8:

-		case FORMAT_D32:

-		case FORMAT_D16:

-			lockable = false;

-			break;

-	//	case FORMAT_S8_LOCKABLE:

-	//	case FORMAT_D16_LOCKABLE:

-		case FORMAT_D32F_LOCKABLE:

-	//	case FORMAT_D32_LOCKABLE:

-		case FORMAT_DF24S8:

-		case FORMAT_DF16S8:

-			lockable = true;

-			break;

-		default:

-			UNREACHABLE(format);

-		}

-

-		Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return 0;

-		}

-

-		return surface;

-	}

-

-	Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return 0;

-		}

-

-		Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return 0;

-		}

-

-		return surface;

-	}

-

-	void Device::drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		DrawType drawType;

-

-		if(indexSize == 4)

-		{

-			switch(type)

-			{

-			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;

-			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;

-			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;

-			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP32;      break;

-			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;

-			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;

-			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;	  break;

-			default: UNREACHABLE(type);

-			}

-		}

-		else if(indexSize == 2)

-		{

-			switch(type)

-			{

-			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;

-			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;

-			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;

-			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP16;      break;

-			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;

-			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;

-			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;

-			default: UNREACHABLE(type);

-			}

-		}

-		else if(indexSize == 1)

-		{

-			switch(type)

-			{

-			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST8;     break;

-			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST8;      break;

-			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP8;     break;

-			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP8;      break;

-			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST8;  break;

-			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP8; break;

-			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN8;   break;

-			default: UNREACHABLE(type);

-			}

-		}

-		else UNREACHABLE(indexSize);

-

-		draw(drawType, indexOffset, primitiveCount);

-	}

-

-	void Device::drawPrimitive(PrimitiveType primitiveType, unsigned int primitiveCount)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		setIndexBuffer(0);

-

-		DrawType drawType;

-

-		switch(primitiveType)

-		{

-		case DRAW_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;

-		case DRAW_LINELIST:      drawType = sw::DRAW_LINELIST;      break;

-		case DRAW_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;

-		case DRAW_LINELOOP:      drawType = sw::DRAW_LINELOOP;      break;

-		case DRAW_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;

-		case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;

-		case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;

-        case DRAW_QUADLIST:      drawType = sw::DRAW_QUADLIST;      break;

-		default: UNREACHABLE(primitiveType);

-		}

-

-		draw(drawType, 0, primitiveCount);

-	}

-

-	void Device::setDepthStencilSurface(Image *depthStencil)

-	{

-		if(this->depthStencil == depthStencil)

-		{

-			return;

-		}

-

-		if(depthStencil)

-		{

-			depthStencil->addRef();

-		}

-

-		if(this->depthStencil)

-		{

-			this->depthStencil->release();

-		}

-

-		this->depthStencil = depthStencil;

-

-		setDepthBuffer(depthStencil);

-		setStencilBuffer(depthStencil);

-	}

-

-	void Device::setPixelShader(PixelShader *pixelShader)

-	{

-		this->pixelShader = pixelShader;

-		pixelShaderDirty = true;

-	}

-

-	void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)

-	{

-		for(unsigned int i = 0; i < count && startRegister + i < FRAGMENT_UNIFORM_VECTORS; i++)

-		{

-			pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];

-			pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];

-			pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];

-			pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];

-		}

-

-		pixelShaderConstantsFDirty = max(startRegister + count, pixelShaderConstantsFDirty);

-		pixelShaderDirty = true;   // Reload DEF constants

-	}

-

-	void Device::setScissorEnable(bool enable)

-	{

-		scissorEnable = enable;

-	}

-

-	void Device::setRenderTarget(int index, Image *renderTarget)

-	{

-		if(renderTarget)

-		{

-			renderTarget->addRef();

-		}

-

-		if(this->renderTarget)

-		{

-			this->renderTarget->release();

-		}

-

-		this->renderTarget = renderTarget;

-

-		Renderer::setRenderTarget(index, renderTarget);

-	}

-

-	void Device::setScissorRect(const sw::Rect &rect)

-	{

-		scissorRect = rect;

-	}

-

-	void Device::setVertexShader(VertexShader *vertexShader)

-	{

-		this->vertexShader = vertexShader;

-		vertexShaderDirty = true;

-	}

-

-	void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)

-	{

-		for(unsigned int i = 0; i < count && startRegister + i < VERTEX_UNIFORM_VECTORS; i++)

-		{

-			vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];

-			vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];

-			vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];

-			vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];

-		}

-

-		vertexShaderConstantsFDirty = max(startRegister + count, vertexShaderConstantsFDirty);

-		vertexShaderDirty = true;   // Reload DEF constants

-	}

-

-	void Device::setViewport(const Viewport &viewport)

-	{

-		this->viewport = viewport;

-	}

-

-	bool Device::stretchRect(Image *source, const sw::SliceRect *sourceRect, Image *dest, const sw::SliceRect *destRect, bool filter)

-	{

-		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))

-		{

-			ERR("Invalid parameters");

-			return false;

-		}

-

-		int sWidth = source->getWidth();

-		int sHeight = source->getHeight();

-		int dWidth = dest->getWidth();

-		int dHeight = dest->getHeight();

-

-		SliceRect sRect;

-		SliceRect dRect;

-

-		if(sourceRect)

-		{

-			sRect = *sourceRect;

-		}

-		else

-		{

-			sRect.y0 = 0;

-			sRect.x0 = 0;

-			sRect.y1 = sHeight;

-			sRect.x1 = sWidth;

-		}

-

-		if(destRect)

-		{

-			dRect = *destRect;

-		}

-		else

-		{

-			dRect.y0 = 0;

-			dRect.x0 = 0;

-			dRect.y1 = dHeight;

-			dRect.x1 = dWidth;

-		}

-

-		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);

-		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();

-		bool depthStencil = Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat());

-		bool alpha0xFF = false;

-

-		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||

-		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))

-		{

-			equalFormats = true;

-			alpha0xFF = true;

-		}

-

-		if(depthStencil)   // Copy entirely, internally   // FIXME: Check

-		{

-			if(source->hasDepth())

-			{

-				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);

-				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getInternalPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockInternal();

-				dest->unlockInternal();

-			}

-

-			if(source->hasStencil())

-			{

-				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC);

-				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getStencilPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockStencil();

-				dest->unlockStencil();

-			}

-		}

-		else if(!scaling && equalFormats)

-		{

-			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);

-			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);

-			unsigned int sourcePitch = source->getInternalPitchB();

-			unsigned int destPitch = dest->getInternalPitchB();

-

-			unsigned int width = dRect.x1 - dRect.x0;

-			unsigned int height = dRect.y1 - dRect.y0;

-			unsigned int bytes = width * Image::bytes(source->getInternalFormat());

-

-			for(unsigned int y = 0; y < height; y++)

-			{

-				memcpy(destBytes, sourceBytes, bytes);

-

-				if(alpha0xFF)

-				{

-					for(unsigned int x = 0; x < width; x++)

-					{

-						destBytes[4 * x + 3] = 0xFF;

-					}

-				}

-

-				sourceBytes += sourcePitch;

-				destBytes += destPitch;

-			}

-

-			source->unlockInternal();

-			dest->unlockInternal();

-		}

-		else

-		{

-			blit(source, sRect, dest, dRect, scaling && filter);

-		}

-

-		return true;

-	}

-

-	bool Device::bindResources()

-	{

-		if(!bindViewport())

-		{

-			return false;   // Zero-area target region

-		}

-

-		bindShaderConstants();

-

-		return true;

-	}

-

-	void Device::bindShaderConstants()

-	{

-		if(pixelShaderDirty)

-		{

-			if(pixelShader)

-			{

-				if(pixelShaderConstantsFDirty)

-				{

-					Renderer::setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);

-				}

-

-				Renderer::setPixelShader(pixelShader);   // Loads shader constants set with DEF

-				pixelShaderConstantsFDirty = pixelShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty

-			}

-			else

-			{

-				setPixelShader(0);

-			}

-

-			pixelShaderDirty = false;

-		}

-

-		if(vertexShaderDirty)

-		{

-			if(vertexShader)

-			{

-				if(vertexShaderConstantsFDirty)

-				{

-					Renderer::setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);

-				}

-

-				Renderer::setVertexShader(vertexShader);   // Loads shader constants set with DEF

-				vertexShaderConstantsFDirty = vertexShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty

-			}

-			else

-			{

-				setVertexShader(0);

-			}

-

-			vertexShaderDirty = false;

-		}

-	}

-

-	bool Device::bindViewport()

-	{

-		if(viewport.width <= 0 || viewport.height <= 0)

-		{

-			return false;

-		}

-

-		if(scissorEnable)

-		{

-			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)

-			{

-				return false;

-			}

-

-			sw::Rect scissor;

-			scissor.x0 = scissorRect.x0;

-			scissor.x1 = scissorRect.x1;

-			scissor.y0 = scissorRect.y0;

-			scissor.y1 = scissorRect.y1;

-

-			setScissor(scissor);

-		}

-		else

-		{

-			sw::Rect scissor;

-			scissor.x0 = viewport.x0;

-			scissor.x1 = viewport.x0 + viewport.width;

-			scissor.y0 = viewport.y0;

-			scissor.y1 = viewport.y0 + viewport.height;

-

-			if(renderTarget)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, renderTarget->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, renderTarget->getHeight());

-			}

-

-			if(depthStencil)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, depthStencil->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, depthStencil->getHeight());

-			}

-

-			setScissor(scissor);

-		}

-

-		sw::Viewport view;

-		view.x0 = (float)viewport.x0;

-		view.y0 = (float)viewport.y0;

-		view.width = (float)viewport.width;

-		view.height = (float)viewport.height;

-		view.minZ = viewport.minZ;

-		view.maxZ = viewport.maxZ;

-

-		Renderer::setViewport(view);

-

-		return true;

-	}

-

-	bool Device::validRectangle(const sw::Rect *rect, Image *surface)

-	{

-		if(!rect)

-		{

-			return true;

-		}

-

-		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)

-		{

-			return false;

-		}

-

-		if(rect->x0 < 0 || rect->y0 < 0)

-		{

-			return false;

-		}

-

-		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	void Device::finish()

-	{

-		synchronize();

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Device.hpp"
+
+#include "Image.hpp"
+#include "Texture.h"
+
+#include "Renderer/Renderer.hpp"
+#include "Renderer/Clipper.hpp"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+#include "Main/Config.hpp"
+#include "Main/FrameBuffer.hpp"
+#include "Common/Math.hpp"
+#include "Common/Configurator.hpp"
+#include "Common/Timer.hpp"
+#include "../common/debug.h"
+
+namespace gl
+{
+	using namespace sw;
+
+	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)
+	{
+		depthStencil = 0;
+		renderTarget = 0;
+
+		setDepthBufferEnable(true);
+		setFillMode(FILL_SOLID);
+		setShadingMode(SHADING_GOURAUD);
+		setDepthWriteEnable(true);
+		setAlphaTestEnable(false);
+		setSourceBlendFactor(BLEND_ONE);
+		setDestBlendFactor(BLEND_ZERO);
+		setCullMode(CULL_COUNTERCLOCKWISE);
+		setDepthCompare(DEPTH_LESSEQUAL);
+		setAlphaReference(0.0f);
+		setAlphaCompare(ALPHA_ALWAYS);
+		setAlphaBlendEnable(false);
+		setFogEnable(false);
+		setSpecularEnable(false);
+		setFogColor(0);
+		setPixelFogMode(FOG_NONE);
+		setFogStart(0.0f);
+		setFogEnd(1.0f);
+		setFogDensity(1.0f);
+		setRangeFogEnable(false);
+		setStencilEnable(false);
+		setStencilFailOperation(OPERATION_KEEP);
+		setStencilZFailOperation(OPERATION_KEEP);
+		setStencilPassOperation(OPERATION_KEEP);
+		setStencilCompare(STENCIL_ALWAYS);
+		setStencilReference(0);
+		setStencilMask(0xFFFFFFFF);
+		setStencilWriteMask(0xFFFFFFFF);
+		setVertexFogMode(FOG_NONE);
+		setClipFlags(0);
+		setPointSize(1.0f);
+		setPointSizeMin(0.125f);
+		setPointSizeMax(8192.0f);
+		setColorWriteMask(0, 0x0000000F);
+		setBlendOperation(BLENDOP_ADD);
+		scissorEnable = false;
+		setSlopeDepthBias(0.0f);
+		setTwoSidedStencil(false);
+		setStencilFailOperationCCW(OPERATION_KEEP);
+		setStencilZFailOperationCCW(OPERATION_KEEP);
+		setStencilPassOperationCCW(OPERATION_KEEP);
+		setStencilCompareCCW(STENCIL_ALWAYS);
+		setColorWriteMask(1, 0x0000000F);
+		setColorWriteMask(2, 0x0000000F);
+		setColorWriteMask(3, 0x0000000F);
+		setBlendConstant(0xFFFFFFFF);
+		setWriteSRGB(false);
+		setDepthBias(0.0f);
+		setSeparateAlphaBlendEnable(false);
+		setSourceBlendFactorAlpha(BLEND_ONE);
+		setDestBlendFactorAlpha(BLEND_ZERO);
+		setBlendOperationAlpha(BLENDOP_ADD);
+		setPointSpriteEnable(true);
+		setColorLogicOpEnabled(false);
+		setLogicalOperation(LOGICALOP_COPY);
+
+		for(int i = 0; i < 16; i++)
+		{
+			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);
+			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);
+			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);
+			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);
+		}
+
+		for(int i = 0; i < 4; i++)
+		{
+			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);
+			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);
+			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);
+			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);
+		}
+
+		for(int i = 0; i < 6; i++)
+		{
+			float plane[4] = {0, 0, 0, 0};
+
+			setClipPlane(i, plane);
+		}
+
+		pixelShader = 0;
+		vertexShader = 0;
+
+		pixelShaderDirty = true;
+		pixelShaderConstantsFDirty = 0;
+		vertexShaderDirty = true;
+		vertexShaderConstantsFDirty = 0;
+
+		for(int i = 0; i < FRAGMENT_UNIFORM_VECTORS; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			setPixelShaderConstantF(i, zero, 1);
+		}
+
+		for(int i = 0; i < VERTEX_UNIFORM_VECTORS; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			setVertexShaderConstantF(i, zero, 1);
+		}
+
+		setLightingEnable(false);
+
+		setGlobalAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f));
+		setMaterialAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f));
+		setMaterialDiffuse(sw::Color<float>(0.8f, 0.8f, 0.8f, 1.0f));
+		setMaterialSpecular(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f));
+		setMaterialEmission(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f));
+
+		for(int i = 0; i < 8; i++)
+		{
+			setLightEnable(i, false);
+			setLightAttenuation(i, 1.0f, 0.0f, 0.0f);
+		}
+
+		setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
+		setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+		setAmbientMaterialSource(sw::MATERIAL_COLOR1);
+		setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+	}
+
+	Device::~Device()
+	{
+		if(depthStencil)
+		{
+			depthStencil->release();
+			depthStencil = 0;
+		}
+
+		if(renderTarget)
+		{
+			renderTarget->release();
+			renderTarget = 0;
+		}
+
+		delete context;
+	}
+
+	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
+	{
+		if(!renderTarget || !rgbaMask)
+		{
+			return;
+		}
+
+		sw::SliceRect clearRect = renderTarget->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		float rgba[4];
+		rgba[0] = red;
+		rgba[1] = green;
+		rgba[2] = blue;
+		rgba[3] = alpha;
+
+		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);
+	}
+
+	void Device::clearDepth(float z)
+	{
+		if(!depthStencil)
+		{
+			return;
+		}
+
+		z = clamp01(z);
+		sw::SliceRect clearRect = depthStencil->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	void Device::clearStencil(unsigned int stencil, unsigned int mask)
+	{
+		if(!depthStencil)
+		{
+			return;
+		}
+
+		sw::SliceRect clearRect = depthStencil->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		depthStencil->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return 0;
+		}
+
+		bool lockable = true;
+
+		switch(format)
+		{
+	//	case FORMAT_D15S1:
+		case FORMAT_D24S8:
+		case FORMAT_D24X8:
+	//	case FORMAT_D24X4S4:
+		case FORMAT_D24FS8:
+		case FORMAT_D32:
+		case FORMAT_D16:
+			lockable = false;
+			break;
+	//	case FORMAT_S8_LOCKABLE:
+	//	case FORMAT_D16_LOCKABLE:
+		case FORMAT_D32F_LOCKABLE:
+	//	case FORMAT_D32_LOCKABLE:
+		case FORMAT_DF24S8:
+		case FORMAT_DF16S8:
+			lockable = true;
+			break;
+		default:
+			UNREACHABLE(format);
+		}
+
+		Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return 0;
+		}
+
+		return surface;
+	}
+
+	Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return 0;
+		}
+
+		Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return 0;
+		}
+
+		return surface;
+	}
+
+	void Device::drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		DrawType drawType;
+
+		if(indexSize == 4)
+		{
+			switch(type)
+			{
+			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;
+			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;
+			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;
+			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP32;      break;
+			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;
+			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
+			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;	  break;
+			default: UNREACHABLE(type);
+			}
+		}
+		else if(indexSize == 2)
+		{
+			switch(type)
+			{
+			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;
+			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;
+			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;
+			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP16;      break;
+			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;
+			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
+			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;
+			default: UNREACHABLE(type);
+			}
+		}
+		else if(indexSize == 1)
+		{
+			switch(type)
+			{
+			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST8;     break;
+			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST8;      break;
+			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP8;     break;
+			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP8;      break;
+			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST8;  break;
+			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP8; break;
+			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN8;   break;
+			default: UNREACHABLE(type);
+			}
+		}
+		else UNREACHABLE(indexSize);
+
+		draw(drawType, indexOffset, primitiveCount);
+	}
+
+	void Device::drawPrimitive(PrimitiveType primitiveType, unsigned int primitiveCount)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		setIndexBuffer(0);
+
+		DrawType drawType;
+
+		switch(primitiveType)
+		{
+		case DRAW_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;
+		case DRAW_LINELIST:      drawType = sw::DRAW_LINELIST;      break;
+		case DRAW_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;
+		case DRAW_LINELOOP:      drawType = sw::DRAW_LINELOOP;      break;
+		case DRAW_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;
+		case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
+		case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;
+		case DRAW_QUADLIST:      drawType = sw::DRAW_QUADLIST;      break;
+		default: UNREACHABLE(primitiveType);
+		}
+
+		draw(drawType, 0, primitiveCount);
+	}
+
+	void Device::setDepthStencilSurface(Image *depthStencil)
+	{
+		if(this->depthStencil == depthStencil)
+		{
+			return;
+		}
+
+		if(depthStencil)
+		{
+			depthStencil->addRef();
+		}
+
+		if(this->depthStencil)
+		{
+			this->depthStencil->release();
+		}
+
+		this->depthStencil = depthStencil;
+
+		setDepthBuffer(depthStencil);
+		setStencilBuffer(depthStencil);
+	}
+
+	void Device::setPixelShader(PixelShader *pixelShader)
+	{
+		this->pixelShader = pixelShader;
+		pixelShaderDirty = true;
+	}
+
+	void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		for(unsigned int i = 0; i < count && startRegister + i < FRAGMENT_UNIFORM_VECTORS; i++)
+		{
+			pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
+			pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
+			pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
+			pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
+		}
+
+		pixelShaderConstantsFDirty = max(startRegister + count, pixelShaderConstantsFDirty);
+		pixelShaderDirty = true;   // Reload DEF constants
+	}
+
+	void Device::setScissorEnable(bool enable)
+	{
+		scissorEnable = enable;
+	}
+
+	void Device::setRenderTarget(int index, Image *renderTarget)
+	{
+		if(renderTarget)
+		{
+			renderTarget->addRef();
+		}
+
+		if(this->renderTarget)
+		{
+			this->renderTarget->release();
+		}
+
+		this->renderTarget = renderTarget;
+
+		Renderer::setRenderTarget(index, renderTarget);
+	}
+
+	void Device::setScissorRect(const sw::Rect &rect)
+	{
+		scissorRect = rect;
+	}
+
+	void Device::setVertexShader(VertexShader *vertexShader)
+	{
+		this->vertexShader = vertexShader;
+		vertexShaderDirty = true;
+	}
+
+	void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		for(unsigned int i = 0; i < count && startRegister + i < VERTEX_UNIFORM_VECTORS; i++)
+		{
+			vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
+			vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
+			vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
+			vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
+		}
+
+		vertexShaderConstantsFDirty = max(startRegister + count, vertexShaderConstantsFDirty);
+		vertexShaderDirty = true;   // Reload DEF constants
+	}
+
+	void Device::setViewport(const Viewport &viewport)
+	{
+		this->viewport = viewport;
+	}
+
+	bool Device::stretchRect(Image *source, const sw::SliceRect *sourceRect, Image *dest, const sw::SliceRect *destRect, bool filter)
+	{
+		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		int sWidth = source->getWidth();
+		int sHeight = source->getHeight();
+		int dWidth = dest->getWidth();
+		int dHeight = dest->getHeight();
+
+		SliceRect sRect;
+		SliceRect dRect;
+
+		if(sourceRect)
+		{
+			sRect = *sourceRect;
+		}
+		else
+		{
+			sRect.y0 = 0;
+			sRect.x0 = 0;
+			sRect.y1 = sHeight;
+			sRect.x1 = sWidth;
+		}
+
+		if(destRect)
+		{
+			dRect = *destRect;
+		}
+		else
+		{
+			dRect.y0 = 0;
+			dRect.x0 = 0;
+			dRect.y1 = dHeight;
+			dRect.x1 = dWidth;
+		}
+
+		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
+		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
+		bool depthStencil = Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat());
+		bool alpha0xFF = false;
+
+		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||
+		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))
+		{
+			equalFormats = true;
+			alpha0xFF = true;
+		}
+
+		if(depthStencil)   // Copy entirely, internally   // FIXME: Check
+		{
+			if(source->hasDepth())
+			{
+				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getInternalPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockInternal();
+				dest->unlockInternal();
+			}
+
+			if(source->hasStencil())
+			{
+				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getStencilPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockStencil();
+				dest->unlockStencil();
+			}
+		}
+		else if(!scaling && equalFormats)
+		{
+			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);
+			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);
+			unsigned int sourcePitch = source->getInternalPitchB();
+			unsigned int destPitch = dest->getInternalPitchB();
+
+			unsigned int width = dRect.x1 - dRect.x0;
+			unsigned int height = dRect.y1 - dRect.y0;
+			unsigned int bytes = width * Image::bytes(source->getInternalFormat());
+
+			for(unsigned int y = 0; y < height; y++)
+			{
+				memcpy(destBytes, sourceBytes, bytes);
+
+				if(alpha0xFF)
+				{
+					for(unsigned int x = 0; x < width; x++)
+					{
+						destBytes[4 * x + 3] = 0xFF;
+					}
+				}
+
+				sourceBytes += sourcePitch;
+				destBytes += destPitch;
+			}
+
+			source->unlockInternal();
+			dest->unlockInternal();
+		}
+		else
+		{
+			blit(source, sRect, dest, dRect, scaling && filter);
+		}
+
+		return true;
+	}
+
+	bool Device::bindResources()
+	{
+		if(!bindViewport())
+		{
+			return false;   // Zero-area target region
+		}
+
+		bindShaderConstants();
+
+		return true;
+	}
+
+	void Device::bindShaderConstants()
+	{
+		if(pixelShaderDirty)
+		{
+			if(pixelShader)
+			{
+				if(pixelShaderConstantsFDirty)
+				{
+					Renderer::setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
+				}
+
+				Renderer::setPixelShader(pixelShader);   // Loads shader constants set with DEF
+				pixelShaderConstantsFDirty = pixelShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty
+			}
+			else
+			{
+				setPixelShader(0);
+			}
+
+			pixelShaderDirty = false;
+		}
+
+		if(vertexShaderDirty)
+		{
+			if(vertexShader)
+			{
+				if(vertexShaderConstantsFDirty)
+				{
+					Renderer::setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
+				}
+
+				Renderer::setVertexShader(vertexShader);   // Loads shader constants set with DEF
+				vertexShaderConstantsFDirty = vertexShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty
+			}
+			else
+			{
+				setVertexShader(0);
+			}
+
+			vertexShaderDirty = false;
+		}
+	}
+
+	bool Device::bindViewport()
+	{
+		if(viewport.width <= 0 || viewport.height <= 0)
+		{
+			return false;
+		}
+
+		if(scissorEnable)
+		{
+			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)
+			{
+				return false;
+			}
+
+			sw::Rect scissor;
+			scissor.x0 = scissorRect.x0;
+			scissor.x1 = scissorRect.x1;
+			scissor.y0 = scissorRect.y0;
+			scissor.y1 = scissorRect.y1;
+
+			setScissor(scissor);
+		}
+		else
+		{
+			sw::Rect scissor;
+			scissor.x0 = viewport.x0;
+			scissor.x1 = viewport.x0 + viewport.width;
+			scissor.y0 = viewport.y0;
+			scissor.y1 = viewport.y0 + viewport.height;
+
+			if(renderTarget)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, renderTarget->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, renderTarget->getHeight());
+			}
+
+			if(depthStencil)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, depthStencil->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, depthStencil->getHeight());
+			}
+
+			setScissor(scissor);
+		}
+
+		sw::Viewport view;
+		view.x0 = (float)viewport.x0;
+		view.y0 = (float)viewport.y0;
+		view.width = (float)viewport.width;
+		view.height = (float)viewport.height;
+		view.minZ = viewport.minZ;
+		view.maxZ = viewport.maxZ;
+
+		Renderer::setViewport(view);
+
+		return true;
+	}
+
+	bool Device::validRectangle(const sw::Rect *rect, Image *surface)
+	{
+		if(!rect)
+		{
+			return true;
+		}
+
+		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)
+		{
+			return false;
+		}
+
+		if(rect->x0 < 0 || rect->y0 < 0)
+		{
+			return false;
+		}
+
+		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	void Device::finish()
+	{
+		synchronize();
+	}
+}
diff --git a/src/OpenGL/libGL/Device.hpp b/src/OpenGL/libGL/Device.hpp
index e85d909..622ce01 100644
--- a/src/OpenGL/libGL/Device.hpp
+++ b/src/OpenGL/libGL/Device.hpp
@@ -1,100 +1,103 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef gl_Device_hpp

-#define gl_Device_hpp

-

-#include "Renderer/Renderer.hpp"

-

-namespace gl

-{

-	class Image;

-	class Texture;

-

-	enum PrimitiveType

-	{

-		DRAW_POINTLIST,

-		DRAW_LINELIST,

-		DRAW_LINESTRIP,

-		DRAW_LINELOOP,

-		DRAW_TRIANGLELIST,

-		DRAW_TRIANGLESTRIP,

-		DRAW_TRIANGLEFAN,

-        DRAW_QUADLIST

-	};

-

-	struct Viewport

-	{

-		int x0;

-		int y0;

-		unsigned int width;

-		unsigned int height;

-		float minZ;

-		float maxZ;

-	};

-

-	class Device : public sw::Renderer

-	{

-	public:

-		explicit Device(sw::Context *context);

-

-		virtual ~Device();

-

-		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);

-		virtual void clearDepth(float z);

-		virtual void clearStencil(unsigned int stencil, unsigned int mask);

-		virtual Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-		virtual Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);

-		virtual void drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize);

-		virtual void drawPrimitive(PrimitiveType primitiveType, unsigned int primiveCount);

-		virtual void setDepthStencilSurface(Image *newDepthStencil);

-		virtual void setPixelShader(sw::PixelShader *shader);

-		virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);

-		virtual void setScissorEnable(bool enable);

-		virtual void setRenderTarget(int index, Image *renderTarget);

-		virtual void setScissorRect(const sw::Rect &rect);

-		virtual void setVertexShader(sw::VertexShader *shader);

-		virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);

-		virtual void setViewport(const Viewport &viewport);

-

-		virtual bool stretchRect(Image *sourceSurface, const sw::SliceRect *sourceRect, Image *destSurface, const sw::SliceRect *destRect, bool filter);

-		virtual void finish();

-

-	private:

-		sw::Context *const context;

-

-		bool bindResources();

-		void bindShaderConstants();

-		bool bindViewport();   // Also adjusts for scissoring

-

-		bool validRectangle(const sw::Rect *rect, Image *surface);

-

-		Viewport viewport;

-		sw::Rect scissorRect;

-		bool scissorEnable;

-

-		sw::PixelShader *pixelShader;

-		sw::VertexShader *vertexShader;

-

-		bool pixelShaderDirty;

-		unsigned int pixelShaderConstantsFDirty;

-		bool vertexShaderDirty;

-		unsigned int vertexShaderConstantsFDirty;

-

-		float pixelShaderConstantF[sw::FRAGMENT_UNIFORM_VECTORS][4];

-		float vertexShaderConstantF[sw::VERTEX_UNIFORM_VECTORS][4];

-

-		Image *renderTarget;

-		Image *depthStencil;

-	};

-}

-

-#endif   // gl_Device_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef gl_Device_hpp
+#define gl_Device_hpp
+
+#include "Renderer/Renderer.hpp"
+
+namespace gl
+{
+	class Image;
+	class Texture;
+
+	enum PrimitiveType
+	{
+		DRAW_POINTLIST,
+		DRAW_LINELIST,
+		DRAW_LINESTRIP,
+		DRAW_LINELOOP,
+		DRAW_TRIANGLELIST,
+		DRAW_TRIANGLESTRIP,
+		DRAW_TRIANGLEFAN,
+		DRAW_QUADLIST
+	};
+
+	struct Viewport
+	{
+		int x0;
+		int y0;
+		unsigned int width;
+		unsigned int height;
+		float minZ;
+		float maxZ;
+	};
+
+	class Device : public sw::Renderer
+	{
+	public:
+		explicit Device(sw::Context *context);
+
+		virtual ~Device();
+
+		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
+		virtual void clearDepth(float z);
+		virtual void clearStencil(unsigned int stencil, unsigned int mask);
+		virtual Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+		virtual Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);
+		virtual void drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize);
+		virtual void drawPrimitive(PrimitiveType primitiveType, unsigned int primiveCount);
+		virtual void setDepthStencilSurface(Image *newDepthStencil);
+		virtual void setPixelShader(sw::PixelShader *shader);
+		virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+		virtual void setScissorEnable(bool enable);
+		virtual void setRenderTarget(int index, Image *renderTarget);
+		virtual void setScissorRect(const sw::Rect &rect);
+		virtual void setVertexShader(sw::VertexShader *shader);
+		virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+		virtual void setViewport(const Viewport &viewport);
+
+		virtual bool stretchRect(Image *sourceSurface, const sw::SliceRect *sourceRect, Image *destSurface, const sw::SliceRect *destRect, bool filter);
+		virtual void finish();
+
+	private:
+		sw::Context *const context;
+
+		bool bindResources();
+		void bindShaderConstants();
+		bool bindViewport();   // Also adjusts for scissoring
+
+		bool validRectangle(const sw::Rect *rect, Image *surface);
+
+		Viewport viewport;
+		sw::Rect scissorRect;
+		bool scissorEnable;
+
+		sw::PixelShader *pixelShader;
+		sw::VertexShader *vertexShader;
+
+		bool pixelShaderDirty;
+		unsigned int pixelShaderConstantsFDirty;
+		bool vertexShaderDirty;
+		unsigned int vertexShaderConstantsFDirty;
+
+		float pixelShaderConstantF[sw::FRAGMENT_UNIFORM_VECTORS][4];
+		float vertexShaderConstantF[sw::VERTEX_UNIFORM_VECTORS][4];
+
+		Image *renderTarget;
+		Image *depthStencil;
+	};
+}
+
+#endif   // gl_Device_hpp
diff --git a/src/OpenGL/libGL/Display.cpp b/src/OpenGL/libGL/Display.cpp
index cd22ae4..8c0f425 100644
--- a/src/OpenGL/libGL/Display.cpp
+++ b/src/OpenGL/libGL/Display.cpp
@@ -1,247 +1,250 @@
-// 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.

-//

-

-// Display.cpp: Implements the Display class, representing the abstract

-// display on which graphics are drawn.

-

-#include "Display.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "Device.hpp"

-#include "common/debug.h"

-

-#include <algorithm>

-#include <vector>

-#include <map>

-

-namespace gl

-{

-typedef std::map<NativeDisplayType, Display*> DisplayMap; 

-DisplayMap displays;

-

-Display *Display::getDisplay(NativeDisplayType displayId)

-{

-    if(displays.find(displayId) != displays.end())

-    {

-        return displays[displayId];

-    }

-

-    // FIXME: Check if displayId is a valid display device context

-    Display *display = new Display(displayId);

-

-    displays[displayId] = display;

-    return display;

-}

-

-Display::Display(NativeDisplayType displayId) : displayId(displayId)

-{

-    mMinSwapInterval = 1;

-    mMaxSwapInterval = 0;

-}

-

-Display::~Display()

-{

-    terminate();

-

-	displays.erase(displayId);

-}

-

-static void cpuid(int registers[4], int info)

-{

-	#if defined(_WIN32)

-        __cpuid(registers, info);

-    #else

-        __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));

-    #endif

-}

-

-static bool detectSSE()

-{

-	#if defined(__APPLE__)

-		int SSE = false;

-		size_t length = sizeof(SSE);

-		sysctlbyname("hw.optional.sse", &SSE, &length, 0, 0);

-		return SSE;

-	#else

-		int registers[4];

-		cpuid(registers, 1);

-		return (registers[3] & 0x02000000) != 0;

-	#endif

-}

-

-bool Display::initialize()

-{

-    if(isInitialized())

-    {

-        return true;

-    }

-

-	if(!detectSSE())

-	{

-		 return false;

-	}

-		

-    mMinSwapInterval = 0;

-    mMaxSwapInterval = 4;

-

-    if(!isInitialized())

-    {

-        terminate();

-

-        return false;

-    }

-

-    return true;

-}

-

-void Display::terminate()

-{

-    while(!mSurfaceSet.empty())

-    {

-        destroySurface(*mSurfaceSet.begin());

-    }

-

-    while(!mContextSet.empty())

-    {

-        destroyContext(*mContextSet.begin());

-    }

-}

-

-gl::Context *Display::createContext(const gl::Context *shareContext)

-{

-    gl::Context *context = new gl::Context(shareContext);

-    mContextSet.insert(context);

-

-    return context;

-}

-

-void Display::destroySurface(Surface *surface)

-{

-    delete surface;

-    mSurfaceSet.erase(surface);

-}

-

-void Display::destroyContext(gl::Context *context)

-{

-    delete context;

-

-	if(context == gl::getContext())

-	{

-		gl::makeCurrent(NULL, NULL, NULL);

-	}

-

-    mContextSet.erase(context);

-}

-

-bool Display::isInitialized() const

-{

-    return mMinSwapInterval <= mMaxSwapInterval;

-}

-

-bool Display::isValidContext(gl::Context *context)

-{

-    return mContextSet.find(context) != mContextSet.end();

-}

-

-bool Display::isValidSurface(Surface *surface)

-{

-    return mSurfaceSet.find(surface) != mSurfaceSet.end();

-}

-

-bool Display::isValidWindow(NativeWindowType window)

-{

-	#if defined(_WIN32)

-		return IsWindow(window) == TRUE;

-	#else

-		XWindowAttributes windowAttributes;

-		Status status = XGetWindowAttributes(displayId, window, &windowAttributes);

-			

-		return status == True;

-	#endif

-}

-

-GLint Display::getMinSwapInterval()

-{

-    return mMinSwapInterval;

-}

-

-GLint Display::getMaxSwapInterval()

-{

-    return mMaxSwapInterval;

-}

-

-Surface *Display::getPrimarySurface()

-{

-    if(mSurfaceSet.size() == 0)

-	{

-		Surface *surface = new Surface(this, WindowFromDC(displayId));

-

-		if(!surface->initialize())

-		{

-			delete surface;

-			return 0;

-		}

-

-		mSurfaceSet.insert(surface);

-

-		gl::setCurrentDrawSurface(surface);

-	}

-

-    return *mSurfaceSet.begin();

-}

-

-NativeDisplayType Display::getNativeDisplay() const

-{

-	return displayId;

-}

-

-DisplayMode Display::getDisplayMode() const

-{

-	DisplayMode displayMode = {0};

-

-	#if defined(_WIN32)

-		HDC deviceContext = GetDC(0);

-	

-		displayMode.width = ::GetDeviceCaps(deviceContext, HORZRES);

-		displayMode.height = ::GetDeviceCaps(deviceContext, VERTRES);

-		unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);

-	

-		switch(bpp)

-		{

-		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;

-		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;

-		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;

-		default:

-			ASSERT(false);   // Unexpected display mode color depth

-		}

-	

-		ReleaseDC(0, deviceContext);

-	#else

-		Screen *screen = XDefaultScreenOfDisplay(displayId);

-		displayMode.width = XWidthOfScreen(screen);

-		displayMode.height = XHeightOfScreen(screen);

-		unsigned int bpp = XPlanesOfScreen(screen);

-

-		switch(bpp)

-		{

-		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;

-		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;

-		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;

-		default:

-			ASSERT(false);   // Unexpected display mode color depth

-		}

-	#endif

-

-	return displayMode;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Display.cpp: Implements the Display class, representing the abstract
+// display on which graphics are drawn.
+
+#include "Display.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "Device.hpp"
+#include "common/debug.h"
+
+#include <algorithm>
+#include <vector>
+#include <map>
+
+namespace gl
+{
+typedef std::map<NativeDisplayType, Display*> DisplayMap;
+DisplayMap displays;
+
+Display *Display::getDisplay(NativeDisplayType displayId)
+{
+	if(displays.find(displayId) != displays.end())
+	{
+		return displays[displayId];
+	}
+
+	// FIXME: Check if displayId is a valid display device context
+	Display *display = new Display(displayId);
+
+	displays[displayId] = display;
+	return display;
+}
+
+Display::Display(NativeDisplayType displayId) : displayId(displayId)
+{
+	mMinSwapInterval = 1;
+	mMaxSwapInterval = 0;
+}
+
+Display::~Display()
+{
+	terminate();
+
+	displays.erase(displayId);
+}
+
+static void cpuid(int registers[4], int info)
+{
+	#if defined(_WIN32)
+		__cpuid(registers, info);
+	#else
+		__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
+	#endif
+}
+
+static bool detectSSE()
+{
+	#if defined(__APPLE__)
+		int SSE = false;
+		size_t length = sizeof(SSE);
+		sysctlbyname("hw.optional.sse", &SSE, &length, 0, 0);
+		return SSE;
+	#else
+		int registers[4];
+		cpuid(registers, 1);
+		return (registers[3] & 0x02000000) != 0;
+	#endif
+}
+
+bool Display::initialize()
+{
+	if(isInitialized())
+	{
+		return true;
+	}
+
+	if(!detectSSE())
+	{
+		 return false;
+	}
+
+	mMinSwapInterval = 0;
+	mMaxSwapInterval = 4;
+
+	if(!isInitialized())
+	{
+		terminate();
+
+		return false;
+	}
+
+	return true;
+}
+
+void Display::terminate()
+{
+	while(!mSurfaceSet.empty())
+	{
+		destroySurface(*mSurfaceSet.begin());
+	}
+
+	while(!mContextSet.empty())
+	{
+		destroyContext(*mContextSet.begin());
+	}
+}
+
+gl::Context *Display::createContext(const gl::Context *shareContext)
+{
+	gl::Context *context = new gl::Context(shareContext);
+	mContextSet.insert(context);
+
+	return context;
+}
+
+void Display::destroySurface(Surface *surface)
+{
+	delete surface;
+	mSurfaceSet.erase(surface);
+}
+
+void Display::destroyContext(gl::Context *context)
+{
+	delete context;
+
+	if(context == gl::getContext())
+	{
+		gl::makeCurrent(nullptr, nullptr, nullptr);
+	}
+
+	mContextSet.erase(context);
+}
+
+bool Display::isInitialized() const
+{
+	return mMinSwapInterval <= mMaxSwapInterval;
+}
+
+bool Display::isValidContext(gl::Context *context)
+{
+	return mContextSet.find(context) != mContextSet.end();
+}
+
+bool Display::isValidSurface(Surface *surface)
+{
+	return mSurfaceSet.find(surface) != mSurfaceSet.end();
+}
+
+bool Display::isValidWindow(NativeWindowType window)
+{
+	#if defined(_WIN32)
+		return IsWindow(window) == TRUE;
+	#else
+		XWindowAttributes windowAttributes;
+		Status status = XGetWindowAttributes(displayId, window, &windowAttributes);
+
+		return status == True;
+	#endif
+}
+
+GLint Display::getMinSwapInterval()
+{
+	return mMinSwapInterval;
+}
+
+GLint Display::getMaxSwapInterval()
+{
+	return mMaxSwapInterval;
+}
+
+Surface *Display::getPrimarySurface()
+{
+	if(mSurfaceSet.size() == 0)
+	{
+		Surface *surface = new Surface(this, WindowFromDC(displayId));
+
+		if(!surface->initialize())
+		{
+			delete surface;
+			return 0;
+		}
+
+		mSurfaceSet.insert(surface);
+
+		gl::setCurrentDrawSurface(surface);
+	}
+
+	return *mSurfaceSet.begin();
+}
+
+NativeDisplayType Display::getNativeDisplay() const
+{
+	return displayId;
+}
+
+DisplayMode Display::getDisplayMode() const
+{
+	DisplayMode displayMode = {0};
+
+	#if defined(_WIN32)
+		HDC deviceContext = GetDC(0);
+
+		displayMode.width = ::GetDeviceCaps(deviceContext, HORZRES);
+		displayMode.height = ::GetDeviceCaps(deviceContext, VERTRES);
+		unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);
+
+		switch(bpp)
+		{
+		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
+		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
+		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
+		default:
+			ASSERT(false);   // Unexpected display mode color depth
+		}
+
+		ReleaseDC(0, deviceContext);
+	#else
+		Screen *screen = XDefaultScreenOfDisplay(displayId);
+		displayMode.width = XWidthOfScreen(screen);
+		displayMode.height = XHeightOfScreen(screen);
+		unsigned int bpp = XPlanesOfScreen(screen);
+
+		switch(bpp)
+		{
+		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
+		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
+		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
+		default:
+			ASSERT(false);   // Unexpected display mode color depth
+		}
+	#endif
+
+	return displayMode;
+}
+
+}
diff --git a/src/OpenGL/libGL/Display.h b/src/OpenGL/libGL/Display.h
index 06e8604..c3c26a4 100644
--- a/src/OpenGL/libGL/Display.h
+++ b/src/OpenGL/libGL/Display.h
@@ -1,78 +1,81 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Display.h: Defines the Display class, representing the abstract

-// display on which graphics are drawn.

-

-#ifndef INCLUDE_DISPLAY_H_

-#define INCLUDE_DISPLAY_H_

-

-#include "Surface.h"

-#include "Context.h"

-#include "Device.hpp"

-

-#include <set>

-

-namespace gl

-{

-	struct DisplayMode

-	{

-		unsigned int width;

-		unsigned int height;

-		sw::Format format;

-	};

-

-	class Display

-	{

-	public:

-		~Display();

-

-		static Display *getDisplay(NativeDisplayType displayId);

-

-		bool initialize();

-		void terminate();

-

-		Context *createContext(const Context *shareContext);

-

-		void destroySurface(Surface *surface);

-		void destroyContext(Context *context);

-

-		bool isInitialized() const;

-		bool isValidContext(Context *context);

-		bool isValidSurface(Surface *surface);

-		bool isValidWindow(NativeWindowType window);

-

-		GLint getMinSwapInterval();

-		GLint getMaxSwapInterval();

-

-        virtual Surface *getPrimarySurface();

-

-		NativeDisplayType getNativeDisplay() const;

-

-	private:

-		Display(NativeDisplayType displayId);

-		

-		DisplayMode getDisplayMode() const;

-

-		const NativeDisplayType displayId;

-

-		GLint mMaxSwapInterval;

-		GLint mMinSwapInterval;

-    

-		typedef std::set<Surface*> SurfaceSet;

-		SurfaceSet mSurfaceSet;

-

-		typedef std::set<Context*> ContextSet;

-		ContextSet mContextSet;

-	};

-}

-

-#endif   // INCLUDE_DISPLAY_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Display.h: Defines the Display class, representing the abstract
+// display on which graphics are drawn.
+
+#ifndef INCLUDE_DISPLAY_H_
+#define INCLUDE_DISPLAY_H_
+
+#include "Surface.h"
+#include "Context.h"
+#include "Device.hpp"
+
+#include <set>
+
+namespace gl
+{
+	struct DisplayMode
+	{
+		unsigned int width;
+		unsigned int height;
+		sw::Format format;
+	};
+
+	class Display
+	{
+	public:
+		~Display();
+
+		static Display *getDisplay(NativeDisplayType displayId);
+
+		bool initialize();
+		void terminate();
+
+		Context *createContext(const Context *shareContext);
+
+		void destroySurface(Surface *surface);
+		void destroyContext(Context *context);
+
+		bool isInitialized() const;
+		bool isValidContext(Context *context);
+		bool isValidSurface(Surface *surface);
+		bool isValidWindow(NativeWindowType window);
+
+		GLint getMinSwapInterval();
+		GLint getMaxSwapInterval();
+
+		virtual Surface *getPrimarySurface();
+
+		NativeDisplayType getNativeDisplay() const;
+
+	private:
+		Display(NativeDisplayType displayId);
+
+		DisplayMode getDisplayMode() const;
+
+		const NativeDisplayType displayId;
+
+		GLint mMaxSwapInterval;
+		GLint mMinSwapInterval;
+
+		typedef std::set<Surface*> SurfaceSet;
+		SurfaceSet mSurfaceSet;
+
+		typedef std::set<Context*> ContextSet;
+		ContextSet mContextSet;
+	};
+}
+
+#endif   // INCLUDE_DISPLAY_H_
diff --git a/src/OpenGL/libGL/Fence.cpp b/src/OpenGL/libGL/Fence.cpp
index cdd1c8d..a59013e 100644
--- a/src/OpenGL/libGL/Fence.cpp
+++ b/src/OpenGL/libGL/Fence.cpp
@@ -1,115 +1,118 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.

-

-#include "Fence.h"

-

-#include "main.h"

-#include "Common/Thread.hpp"

-

-namespace gl

-{

-

-Fence::Fence()

-{ 

-    mQuery = false;

-    mCondition = GL_NONE;

-    mStatus = GL_FALSE;

-}

-

-Fence::~Fence()

-{

-    mQuery = false;

-}

-

-GLboolean Fence::isFence()

-{

-    // GL_NV_fence spec:

-    // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.

-    return mQuery;

-}

-

-void Fence::setFence(GLenum condition)

-{

-    if(condition != GL_ALL_COMPLETED_NV)

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    mQuery = true;

-    mCondition = condition;

-    mStatus = GL_FALSE;

-}

-

-GLboolean Fence::testFence()

-{

-    if(!mQuery)

-    {

-        return error(GL_INVALID_OPERATION, GL_TRUE);

-    }

-

-    // The current assumtion is that no matter where the fence is placed, it is

-    // done by the time it is tested, which is similar to Context::flush(), since

-    // we don't queue anything without processing it as fast as possible.

-    mStatus = GL_TRUE;

-

-    return mStatus;

-}

-

-void Fence::finishFence()

-{

-    if(!mQuery)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    while(!testFence())

-    {

-        sw::Thread::yield();

-    }

-}

-

-void Fence::getFenceiv(GLenum pname, GLint *params)

-{

-    if(!mQuery)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    switch (pname)

-    {

-    case GL_FENCE_STATUS_NV:

-		{

-			// GL_NV_fence spec:

-			// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV

-			// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.

-			if(mStatus)

-			{

-				params[0] = GL_TRUE;

-				return;

-			}

-            

-			mStatus = testFence();

-

-			params[0] = mStatus;            

-			break;

-		}

-    case GL_FENCE_CONDITION_NV:

-        params[0] = mCondition;

-        break;

-    default:

-        return error(GL_INVALID_ENUM);

-        break;

-    }

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.
+
+#include "Fence.h"
+
+#include "main.h"
+#include "Common/Thread.hpp"
+
+namespace gl
+{
+
+Fence::Fence()
+{ 
+	mQuery = false;
+	mCondition = GL_NONE;
+	mStatus = GL_FALSE;
+}
+
+Fence::~Fence()
+{
+	mQuery = false;
+}
+
+GLboolean Fence::isFence()
+{
+	// GL_NV_fence spec:
+	// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
+	return mQuery;
+}
+
+void Fence::setFence(GLenum condition)
+{
+	if(condition != GL_ALL_COMPLETED_NV)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	mQuery = true;
+	mCondition = condition;
+	mStatus = GL_FALSE;
+}
+
+GLboolean Fence::testFence()
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION, GL_TRUE);
+	}
+
+	// The current assumtion is that no matter where the fence is placed, it is
+	// done by the time it is tested, which is similar to Context::flush(), since
+	// we don't queue anything without processing it as fast as possible.
+	mStatus = GL_TRUE;
+
+	return mStatus;
+}
+
+void Fence::finishFence()
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	while(!testFence())
+	{
+		sw::Thread::yield();
+	}
+}
+
+void Fence::getFenceiv(GLenum pname, GLint *params)
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	switch(pname)
+	{
+	case GL_FENCE_STATUS_NV:
+		{
+			// GL_NV_fence spec:
+			// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
+			// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+			if(mStatus)
+			{
+				params[0] = GL_TRUE;
+				return;
+			}
+
+			mStatus = testFence();
+
+			params[0] = mStatus;            
+			break;
+		}
+	case GL_FENCE_CONDITION_NV:
+		params[0] = mCondition;
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+		break;
+	}
+}
+
+}
diff --git a/src/OpenGL/libGL/Fence.h b/src/OpenGL/libGL/Fence.h
index 26f20c8..f7270eb 100644
--- a/src/OpenGL/libGL/Fence.h
+++ b/src/OpenGL/libGL/Fence.h
@@ -1,45 +1,48 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Fence.h: Defines the Fence class, which supports the GL_NV_fence extension.

-

-#ifndef LIBGL_FENCE_H_

-#define LIBGL_FENCE_H_

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-

-class Fence

-{

-  public:

-    Fence();

-    virtual ~Fence();

-

-    GLboolean isFence();

-    void setFence(GLenum condition);

-    GLboolean testFence();

-    void finishFence();

-    void getFenceiv(GLenum pname, GLint *params);

-

-  private:

-    bool mQuery;

-    GLenum mCondition;

-    GLboolean mStatus;

-};

-

-}

-

-#endif   // LIBGL_FENCE_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Fence.h: Defines the Fence class, which supports the GL_NV_fence extension.
+
+#ifndef LIBGL_FENCE_H_
+#define LIBGL_FENCE_H_
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+
+class Fence
+{
+public:
+	Fence();
+	virtual ~Fence();
+
+	GLboolean isFence();
+	void setFence(GLenum condition);
+	GLboolean testFence();
+	void finishFence();
+	void getFenceiv(GLenum pname, GLint *params);
+
+private:
+	bool mQuery;
+	GLenum mCondition;
+	GLboolean mStatus;
+};
+
+}
+
+#endif   // LIBGL_FENCE_H_
diff --git a/src/OpenGL/libGL/Framebuffer.cpp b/src/OpenGL/libGL/Framebuffer.cpp
index 220da2d..1bef3fb 100644
--- a/src/OpenGL/libGL/Framebuffer.cpp
+++ b/src/OpenGL/libGL/Framebuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
 // objects and related functionality.
@@ -31,19 +34,19 @@
 
 Framebuffer::~Framebuffer()
 {
-	mColorbufferPointer = NULL;
-	mDepthbufferPointer = NULL;
-	mStencilbufferPointer = NULL;
+	mColorbufferPointer = nullptr;
+	mDepthbufferPointer = nullptr;
+	mStencilbufferPointer = nullptr;
 }
 
 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
 {
 	Context *context = getContext();
-	Renderbuffer *buffer = NULL;
+	Renderbuffer *buffer = nullptr;
 
 	if(type == GL_NONE)
 	{
-		buffer = NULL;
+		buffer = nullptr;
 	}
 	else if(type == GL_RENDERBUFFER)
 	{
@@ -81,19 +84,19 @@
 	if(mColorbufferPointer.name() == texture && IsTextureTarget(mColorbufferType))
 	{
 		mColorbufferType = GL_NONE;
-		mColorbufferPointer = NULL;
+		mColorbufferPointer = nullptr;
 	}
 
 	if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
 	{
 		mDepthbufferType = GL_NONE;
-		mDepthbufferPointer = NULL;
+		mDepthbufferPointer = nullptr;
 	}
 
 	if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType))
 	{
 		mStencilbufferType = GL_NONE;
-		mStencilbufferPointer = NULL;
+		mStencilbufferPointer = nullptr;
 	}
 }
 
@@ -102,19 +105,19 @@
 	if(mColorbufferPointer.name() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
 	{
 		mColorbufferType = GL_NONE;
-		mColorbufferPointer = NULL;
+		mColorbufferPointer = nullptr;
 	}
 
 	if(mDepthbufferPointer.name() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
 	{
 		mDepthbufferType = GL_NONE;
-		mDepthbufferPointer = NULL;
+		mDepthbufferPointer = nullptr;
 	}
 
 	if(mStencilbufferPointer.name() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
 	{
 		mStencilbufferType = GL_NONE;
-		mStencilbufferPointer = NULL;
+		mStencilbufferPointer = nullptr;
 	}
 }
 
@@ -129,7 +132,7 @@
 		return colorbuffer->getRenderTarget();
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 // Increments refcount on surface.
@@ -137,7 +140,7 @@
 Image *Framebuffer::getDepthStencil()
 {
 	Renderbuffer *depthstencilbuffer = mDepthbufferPointer;
-	
+
 	if(!depthstencilbuffer)
 	{
 		depthstencilbuffer = mStencilbufferPointer;
@@ -148,7 +151,7 @@
 		return depthstencilbuffer->getRenderTarget();
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 Renderbuffer *Framebuffer::getColorbuffer()
@@ -275,8 +278,8 @@
 		samples = colorbuffer->getSamples();
 	}
 
-	Renderbuffer *depthbuffer = NULL;
-	Renderbuffer *stencilbuffer = NULL;
+	Renderbuffer *depthbuffer = nullptr;
+	Renderbuffer *stencilbuffer = nullptr;
 
 	if(mDepthbufferType != GL_NONE)
 	{
diff --git a/src/OpenGL/libGL/Framebuffer.h b/src/OpenGL/libGL/Framebuffer.h
index cab9f42..06dc8fe 100644
--- a/src/OpenGL/libGL/Framebuffer.h
+++ b/src/OpenGL/libGL/Framebuffer.h
@@ -1,92 +1,95 @@
-// 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.

-//

-

-// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer

-// objects and related functionality.

-

-#ifndef LIBGL_FRAMEBUFFER_H_

-#define LIBGL_FRAMEBUFFER_H_

-

-#include "common/Object.hpp"

-#include "Image.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-class Renderbuffer;

-class Colorbuffer;

-class Depthbuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-

-class Framebuffer

-{

-public:

-    Framebuffer();

-

-    virtual ~Framebuffer();

-

-    void setColorbuffer(GLenum type, GLuint colorbuffer);

-    void setDepthbuffer(GLenum type, GLuint depthbuffer);

-    void setStencilbuffer(GLenum type, GLuint stencilbuffer);

-

-    void detachTexture(GLuint texture);

-    void detachRenderbuffer(GLuint renderbuffer);

-

-    Image *getRenderTarget();

-    Image *getDepthStencil();

-

-    Renderbuffer *getColorbuffer();

-    Renderbuffer *getDepthbuffer();

-    Renderbuffer *getStencilbuffer();

-

-    GLenum getColorbufferType();

-    GLenum getDepthbufferType();

-    GLenum getStencilbufferType();

-

-    GLuint getColorbufferName();

-    GLuint getDepthbufferName();

-    GLuint getStencilbufferName();

-

-    bool hasStencil();

-

-	virtual GLenum completeness();

-	GLenum completeness(int &width, int &height, int &samples);

-

-protected:

-    GLenum mColorbufferType;

-    BindingPointer<Renderbuffer> mColorbufferPointer;

-

-    GLenum mDepthbufferType;

-    BindingPointer<Renderbuffer> mDepthbufferPointer;

-

-    GLenum mStencilbufferType;

-    BindingPointer<Renderbuffer> mStencilbufferPointer;

-

-private:

-    Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;

-};

-

-class DefaultFramebuffer : public Framebuffer

-{

-public:

-    DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);

-

-    virtual GLenum completeness();

-};

-

-}

-

-#endif   // LIBGL_FRAMEBUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer
+// objects and related functionality.
+
+#ifndef LIBGL_FRAMEBUFFER_H_
+#define LIBGL_FRAMEBUFFER_H_
+
+#include "common/Object.hpp"
+#include "Image.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+class Renderbuffer;
+class Colorbuffer;
+class Depthbuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+
+class Framebuffer
+{
+public:
+	Framebuffer();
+
+	virtual ~Framebuffer();
+
+	void setColorbuffer(GLenum type, GLuint colorbuffer);
+	void setDepthbuffer(GLenum type, GLuint depthbuffer);
+	void setStencilbuffer(GLenum type, GLuint stencilbuffer);
+
+	void detachTexture(GLuint texture);
+	void detachRenderbuffer(GLuint renderbuffer);
+
+	Image *getRenderTarget();
+	Image *getDepthStencil();
+
+	Renderbuffer *getColorbuffer();
+	Renderbuffer *getDepthbuffer();
+	Renderbuffer *getStencilbuffer();
+
+	GLenum getColorbufferType();
+	GLenum getDepthbufferType();
+	GLenum getStencilbufferType();
+
+	GLuint getColorbufferName();
+	GLuint getDepthbufferName();
+	GLuint getStencilbufferName();
+
+	bool hasStencil();
+
+	virtual GLenum completeness();
+	GLenum completeness(int &width, int &height, int &samples);
+
+protected:
+	GLenum mColorbufferType;
+	BindingPointer<Renderbuffer> mColorbufferPointer;
+
+	GLenum mDepthbufferType;
+	BindingPointer<Renderbuffer> mDepthbufferPointer;
+
+	GLenum mStencilbufferType;
+	BindingPointer<Renderbuffer> mStencilbufferPointer;
+
+private:
+	Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
+};
+
+class DefaultFramebuffer : public Framebuffer
+{
+public:
+	DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+
+	virtual GLenum completeness();
+};
+
+}
+
+#endif   // LIBGL_FRAMEBUFFER_H_
diff --git a/src/OpenGL/libGL/Image.cpp b/src/OpenGL/libGL/Image.cpp
index c444434..49204f5 100644
--- a/src/OpenGL/libGL/Image.cpp
+++ b/src/OpenGL/libGL/Image.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Image.hpp"
 
@@ -72,7 +75,7 @@
 	{
 		return width;
 	}
-	
+
 	int Image::getHeight()
 	{
 		return height;
@@ -82,17 +85,17 @@
 	{
 		return format;
 	}
-	
+
 	GLenum Image::getType()
 	{
 		return type;
 	}
-	
+
 	sw::Format Image::getInternalFormat()
 	{
 		return internalFormat;
 	}
-	
+
 	int Image::getMultiSampleDepth()
 	{
 		return multiSampleDepth;
@@ -135,11 +138,11 @@
 
 	sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
 	{
-        if(type == GL_NONE && format == GL_NONE)
-        {
-            return sw::FORMAT_NULL;
-        }
-        else
+		if(type == GL_NONE && format == GL_NONE)
+		{
+			return sw::FORMAT_NULL;
+		}
+		else
 		#if S3TC_SUPPORT
 		if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
 		   format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
@@ -216,10 +219,10 @@
 		{
 			return sw::FORMAT_R5G6B5;
 		}
-        else if(type == GL_UNSIGNED_INT_8_8_8_8_REV)
-        {
-            return sw::FORMAT_A8R8G8B8;
-        }
+		else if(type == GL_UNSIGNED_INT_8_8_8_8_REV)
+		{
+			return sw::FORMAT_A8R8G8B8;
+		}
 
 		else UNREACHABLE(type);
 
@@ -230,13 +233,13 @@
 	{
 		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
 		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
-		
+
 		if(buffer)
 		{
 			switch(type)
 			{
 			case GL_UNSIGNED_BYTE:
-            case GL_UNSIGNED_INT_8_8_8_8_REV:
+			case GL_UNSIGNED_INT_8_8_8_8_REV:
 				switch(format)
 				{
 				case GL_ALPHA:
@@ -364,7 +367,7 @@
 		{
 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = 0;
@@ -381,7 +384,7 @@
 		{
 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = 0;
@@ -409,7 +412,7 @@
 		{
 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = source[x];
@@ -426,7 +429,7 @@
 		{
 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = source[x];
@@ -443,7 +446,7 @@
 		{
 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
-        
+
 			memcpy(dest, source, width * 2);
 		}
 	}
@@ -454,7 +457,7 @@
 		{
 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = source[2*x+0];
@@ -471,7 +474,7 @@
 		{
 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = source[2*x+0];
@@ -488,7 +491,7 @@
 		{
 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = source[x * 3 + 2];
@@ -505,7 +508,7 @@
 		{
 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
-			
+
 			memcpy(dest, source, width * 2);
 		}
 	}
@@ -516,7 +519,7 @@
 		{
 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = source[x * 3 + 0];
@@ -533,7 +536,7 @@
 		{
 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				dest[4 * x + 0] = source[x * 3 + 0];
@@ -565,7 +568,7 @@
 		{
 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				unsigned short rgba = source[x];
@@ -583,7 +586,7 @@
 		{
 			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-			
+
 			for(int x = 0; x < width; x++)
 			{
 				unsigned short rgba = source[x];
@@ -601,7 +604,7 @@
 		{
 			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
 			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-			
+
 			memcpy(dest, source, width * 16);
 		}
 	}
@@ -612,7 +615,7 @@
 		{
 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8;
-			
+
 			memcpy(dest, source, width * 8);
 		}
 	}
@@ -623,7 +626,7 @@
 		{
 			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
 			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-			
+
 			memcpy(dest, source, width*4);
 		}
 	}
@@ -694,13 +697,13 @@
 		int rows = imageSize / inputPitch;
 		void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
 
-        if(buffer)
-        {
+		if(buffer)
+		{
 			for(int i = 0; i < rows; i++)
 			{
 				memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
 			}
-        }
+		}
 
 		unlock();
 	}
diff --git a/src/OpenGL/libGL/Image.hpp b/src/OpenGL/libGL/Image.hpp
index 8be53d9..9192c8e 100644
--- a/src/OpenGL/libGL/Image.hpp
+++ b/src/OpenGL/libGL/Image.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef gl_Image_hpp
 #define gl_Image_hpp
@@ -35,7 +38,7 @@
 		void *lock(unsigned int left, unsigned int top, sw::Lock lock);
 		unsigned int getPitch() const;
 		void unlock();
-		
+
 		int getWidth();
 		int getHeight();
 		GLenum getFormat();
diff --git a/src/OpenGL/libGL/IndexDataManager.cpp b/src/OpenGL/libGL/IndexDataManager.cpp
index 0981cb3..30d056e 100644
--- a/src/OpenGL/libGL/IndexDataManager.cpp
+++ b/src/OpenGL/libGL/IndexDataManager.cpp
@@ -1,259 +1,262 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// IndexDataManager.cpp: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#include "IndexDataManager.h"

-

-#include "Buffer.h"

-#include "common/debug.h"

-

-#include <string.h>

-#include <algorithm>

-

-namespace

-{

-    enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };

-}

-

-namespace gl

-{

-

-IndexDataManager::IndexDataManager()

-{

-    mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming index buffer.");

-    }

-}

-

-IndexDataManager::~IndexDataManager()

-{

-    delete mStreamingBuffer;

-}

-

-void copyIndices(GLenum type, const void *input, GLsizei count, void *output)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        memcpy(output, input, count * sizeof(GLubyte));

-    }

-    else if(type == GL_UNSIGNED_INT)

-    {

-        memcpy(output, input, count * sizeof(GLuint));

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        memcpy(output, input, count * sizeof(GLushort));

-    }

-    else UNREACHABLE(type);

-}

-

-template<class IndexType>

-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    *minIndex = indices[0];

-    *maxIndex = indices[0];

-

-    for(GLsizei i = 0; i < count; i++)

-    {

-        if(*minIndex > indices[i]) *minIndex = indices[i];

-        if(*maxIndex < indices[i]) *maxIndex = indices[i];

-    }

-}

-

-void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);

-    }

-    else if(type == GL_UNSIGNED_INT)

-    {

-        computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);

-    }

-    else UNREACHABLE(type);

-}

-

-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-    intptr_t offset = reinterpret_cast<intptr_t>(indices);

-    bool alignedOffset = false;

-

-    if(buffer != NULL)

-    {

-        switch(type)

-        {

-          case GL_UNSIGNED_BYTE:  alignedOffset = (offset % sizeof(GLubyte) == 0);  break;

-          case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;

-          case GL_UNSIGNED_INT:   alignedOffset = (offset % sizeof(GLuint) == 0);   break;

-          default: UNREACHABLE(type); alignedOffset = false;

-        }

-

-        if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))

-        {

-            return GL_INVALID_OPERATION;

-        }

-

-        indices = static_cast<const GLubyte*>(buffer->data()) + offset;

-    }

-

-    StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;

-

-	sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-    if(staticBuffer)

-    {

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = staticBuffer;

-		translated->indexOffset = offset;

-    }

-    else

-    {

-		unsigned int streamOffset = 0;

-        int convertCount = count;

-

-        streamingBuffer->reserveSpace(convertCount * typeSize(type), type);

-        void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);

-        

-        if(output == NULL)

-        {

-            ERR("Failed to map index buffer.");

-            return GL_OUT_OF_MEMORY;

-        }

-

-        copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);

-        streamingBuffer->unmap();

-

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = streamingBuffer->getResource();

-		translated->indexOffset = streamOffset;

-    }

-

-    return GL_NO_ERROR;

-}

-

-std::size_t IndexDataManager::typeSize(GLenum type)

-{

-    switch(type)

-    {

-    case GL_UNSIGNED_INT:   return sizeof(GLuint);

-    case GL_UNSIGNED_SHORT: return sizeof(GLushort);

-    case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);

-    default: UNREACHABLE(type); return sizeof(GLushort);

-    }

-}

-

-StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(nullptr), mBufferSize(initialSize)

-{

-	if(initialSize > 0)

-    {

-		mIndexBuffer = new sw::Resource(initialSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", initialSize);

-        }

-    }

-

-    mWritePosition = 0;

-}

-

-StreamingIndexBuffer::~StreamingIndexBuffer()

-{

-	if(mIndexBuffer)

-    {

-        mIndexBuffer->destruct();

-    }

-}

-

-void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mIndexBuffer)

-    {

-        mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;

-     

-        if(!mapPtr)

-        {

-            ERR(" Lock failed");

-            return NULL;

-        }

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingIndexBuffer::unmap()

-{

-    if(mIndexBuffer)

-    {

-        mIndexBuffer->unlock();

-    }

-}

-

-void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)

-{

-    if(requiredSpace > mBufferSize)

-    {

-        if(mIndexBuffer)

-        {

-            mIndexBuffer->destruct();

-            mIndexBuffer = 0;

-        }

-

-        mBufferSize = std::max(requiredSpace, 2 * mBufferSize);

-

-		mIndexBuffer = new sw::Resource(mBufferSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle

-    {

-		if(mIndexBuffer)

-		{

-			mIndexBuffer->destruct();

-			mIndexBuffer = new sw::Resource(mBufferSize + 16);

-		}

-

-        mWritePosition = 0;

-    }

-}

-

-sw::Resource *StreamingIndexBuffer::getResource() const

-{

-    return mIndexBuffer;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// IndexDataManager.cpp: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#include "IndexDataManager.h"
+
+#include "Buffer.h"
+#include "common/debug.h"
+
+#include <string.h>
+#include <algorithm>
+
+namespace
+{
+	enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
+}
+
+namespace gl
+{
+
+IndexDataManager::IndexDataManager()
+{
+	mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming index buffer.");
+	}
+}
+
+IndexDataManager::~IndexDataManager()
+{
+	delete mStreamingBuffer;
+}
+
+void copyIndices(GLenum type, const void *input, GLsizei count, void *output)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		memcpy(output, input, count * sizeof(GLubyte));
+	}
+	else if(type == GL_UNSIGNED_INT)
+	{
+		memcpy(output, input, count * sizeof(GLuint));
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		memcpy(output, input, count * sizeof(GLushort));
+	}
+	else UNREACHABLE(type);
+}
+
+template<class IndexType>
+void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	*minIndex = indices[0];
+	*maxIndex = indices[0];
+
+	for(GLsizei i = 0; i < count; i++)
+	{
+		if(*minIndex > indices[i]) *minIndex = indices[i];
+		if(*maxIndex < indices[i]) *maxIndex = indices[i];
+	}
+}
+
+void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+	}
+	else if(type == GL_UNSIGNED_INT)
+	{
+		computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
+	}
+	else UNREACHABLE(type);
+}
+
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	intptr_t offset = reinterpret_cast<intptr_t>(indices);
+	bool alignedOffset = false;
+
+	if(buffer)
+	{
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:  alignedOffset = (offset % sizeof(GLubyte) == 0);  break;
+		case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
+		case GL_UNSIGNED_INT:   alignedOffset = (offset % sizeof(GLuint) == 0);   break;
+		default: UNREACHABLE(type); alignedOffset = false;
+		}
+
+		if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		indices = static_cast<const GLubyte*>(buffer->data()) + offset;
+	}
+
+	StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;
+
+	sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr;
+
+	if(staticBuffer)
+	{
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = staticBuffer;
+		translated->indexOffset = offset;
+	}
+	else
+	{
+		unsigned int streamOffset = 0;
+		int convertCount = count;
+
+		streamingBuffer->reserveSpace(convertCount * typeSize(type), type);
+		void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);
+
+		if(!output)
+		{
+			ERR("Failed to map index buffer.");
+			return GL_OUT_OF_MEMORY;
+		}
+
+		copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
+		streamingBuffer->unmap();
+
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = streamingBuffer->getResource();
+		translated->indexOffset = streamOffset;
+	}
+
+	return GL_NO_ERROR;
+}
+
+std::size_t IndexDataManager::typeSize(GLenum type)
+{
+	switch(type)
+	{
+	case GL_UNSIGNED_INT:   return sizeof(GLuint);
+	case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+	case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);
+	default: UNREACHABLE(type); return sizeof(GLushort);
+	}
+}
+
+StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(nullptr), mBufferSize(initialSize)
+{
+	if(initialSize > 0)
+	{
+		mIndexBuffer = new sw::Resource(initialSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", initialSize);
+		}
+	}
+
+	mWritePosition = 0;
+}
+
+StreamingIndexBuffer::~StreamingIndexBuffer()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->destruct();
+	}
+}
+
+void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = nullptr;
+
+	if(mIndexBuffer)
+	{
+		mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;
+
+		if(!mapPtr)
+		{
+			ERR(" Lock failed");
+			return nullptr;
+		}
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingIndexBuffer::unmap()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->unlock();
+	}
+}
+
+void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)
+{
+	if(requiredSpace > mBufferSize)
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = 0;
+		}
+
+		mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
+
+		mIndexBuffer = new sw::Resource(mBufferSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = new sw::Resource(mBufferSize + 16);
+		}
+
+		mWritePosition = 0;
+	}
+}
+
+sw::Resource *StreamingIndexBuffer::getResource() const
+{
+	return mIndexBuffer;
+}
+
+}
diff --git a/src/OpenGL/libGL/IndexDataManager.h b/src/OpenGL/libGL/IndexDataManager.h
index c22bd7d..d1d6e54 100644
--- a/src/OpenGL/libGL/IndexDataManager.h
+++ b/src/OpenGL/libGL/IndexDataManager.h
@@ -1,71 +1,74 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// IndexDataManager.h: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#ifndef LIBGL_INDEXDATAMANAGER_H_

-#define LIBGL_INDEXDATAMANAGER_H_

-

-#include "Context.h"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-

-struct TranslatedIndexData

-{

-    unsigned int minIndex;

-    unsigned int maxIndex;

-    unsigned int indexOffset;

-

-    sw::Resource *indexBuffer;

-};

-

-class StreamingIndexBuffer

-{

-  public:

-    StreamingIndexBuffer(unsigned int initialSize);

-    virtual ~StreamingIndexBuffer();

-

-    void *map(unsigned int requiredSpace, unsigned int *offset);

-	void unmap();

-    void reserveSpace(unsigned int requiredSpace, GLenum type);

-

-	sw::Resource *getResource() const;

-

-  private:

-    sw::Resource *mIndexBuffer;

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-};

-

-class IndexDataManager

-{

-  public:

-    IndexDataManager();

-    virtual ~IndexDataManager();

-

-    GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);

-

-	static std::size_t typeSize(GLenum type);

-

-  private:

-    StreamingIndexBuffer *mStreamingBuffer;

-};

-

-}

-

-#endif   // LIBGL_INDEXDATAMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// IndexDataManager.h: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#ifndef LIBGL_INDEXDATAMANAGER_H_
+#define LIBGL_INDEXDATAMANAGER_H_
+
+#include "Context.h"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+
+struct TranslatedIndexData
+{
+	unsigned int minIndex;
+	unsigned int maxIndex;
+	unsigned int indexOffset;
+
+	sw::Resource *indexBuffer;
+};
+
+class StreamingIndexBuffer
+{
+public:
+	StreamingIndexBuffer(unsigned int initialSize);
+	virtual ~StreamingIndexBuffer();
+
+	void *map(unsigned int requiredSpace, unsigned int *offset);
+	void unmap();
+	void reserveSpace(unsigned int requiredSpace, GLenum type);
+
+	sw::Resource *getResource() const;
+
+private:
+	sw::Resource *mIndexBuffer;
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+};
+
+class IndexDataManager
+{
+public:
+	IndexDataManager();
+	virtual ~IndexDataManager();
+
+	GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
+
+	static std::size_t typeSize(GLenum type);
+
+private:
+	StreamingIndexBuffer *mStreamingBuffer;
+};
+
+}
+
+#endif   // LIBGL_INDEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGL/Program.cpp b/src/OpenGL/libGL/Program.cpp
index 4e4f2b5..a8f91d2 100644
--- a/src/OpenGL/libGL/Program.cpp
+++ b/src/OpenGL/libGL/Program.cpp
@@ -1,2290 +1,2293 @@
-// 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.

-//

-

-// Program.cpp: Implements the Program class. Implements GL program objects

-// and related functionality.

-

-#include "Program.h"

-

-#include "main.h"

-#include "Shader.h"

-#include "utilities.h"

-#include "common/debug.h"

-#include "Shader/PixelShader.hpp"

-#include "Shader/VertexShader.hpp"

-

-#include <string>

-#include <stdlib.h>

-

-namespace gl

-{

-	unsigned int Program::currentSerial = 1;

-

-	std::string str(int i)

-	{

-		char buffer[20];

-		sprintf(buffer, "%d", i);

-		return buffer;

-	}

-

-	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) : type(type), precision(precision), name(name), arraySize(arraySize)

-	{

-		int bytes = UniformTypeSize(type) * size();

-		data = new unsigned char[bytes];

-		memset(data, 0, bytes);

-		dirty = true;

-

-		psRegisterIndex = -1;

-		vsRegisterIndex = -1;

-	}

-

-	Uniform::~Uniform()

-	{

-		delete[] data;

-	}

-

-	bool Uniform::isArray() const

-	{

-		return arraySize >= 1;

-	}

-

-	int Uniform::size() const

-	{

-		return arraySize > 0 ? arraySize : 1;

-	}

-

-	int Uniform::registerCount() const

-	{

-		return size() * VariableRowCount(type);

-	}

-

-	UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)

-	{

-	}

-

-	Program::Program(ResourceManager *manager, GLuint handle) : resourceManager(manager), handle(handle), serial(issueSerial())

-	{

-		device = getDevice();

-

-		fragmentShader = 0;

-		vertexShader = 0;

-		pixelBinary = 0;

-		vertexBinary = 0;

-

-		infoLog = 0;

-		validated = false;

-

-		unlink();

-

-		orphaned = false;

-		referenceCount = 0;

-	}

-

-	Program::~Program()

-	{

-		unlink();

-

-		if(vertexShader)

-		{

-			vertexShader->release();

-		}

-

-		if(fragmentShader)

-		{

-			fragmentShader->release();

-		}

-	}

-

-	bool Program::attachShader(Shader *shader)

-	{

-		if(shader->getType() == GL_VERTEX_SHADER)

-		{

-			if(vertexShader)

-			{

-				return false;

-			}

-

-			vertexShader = (VertexShader*)shader;

-			vertexShader->addRef();

-		}

-		else if(shader->getType() == GL_FRAGMENT_SHADER)

-		{

-			if(fragmentShader)

-			{

-				return false;

-			}

-

-			fragmentShader = (FragmentShader*)shader;

-			fragmentShader->addRef();

-		}

-		else UNREACHABLE(shader->getType());

-

-		return true;

-	}

-

-	bool Program::detachShader(Shader *shader)

-	{

-		if(shader->getType() == GL_VERTEX_SHADER)

-		{

-			if(vertexShader != shader)

-			{

-				return false;

-			}

-

-			vertexShader->release();

-			vertexShader = 0;

-		}

-		else if(shader->getType() == GL_FRAGMENT_SHADER)

-		{

-			if(fragmentShader != shader)

-			{

-				return false;

-			}

-

-			fragmentShader->release();

-			fragmentShader = 0;

-		}

-		else UNREACHABLE(shader->getType());

-

-		return true;

-	}

-

-	int Program::getAttachedShadersCount() const

-	{

-		return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);

-	}

-

-	sw::PixelShader *Program::getPixelShader()

-	{

-		return pixelBinary;

-	}

-

-	sw::VertexShader *Program::getVertexShader()

-	{

-		return vertexBinary;

-	}

-

-	void Program::bindAttributeLocation(GLuint index, const char *name)

-	{

-		if(index < MAX_VERTEX_ATTRIBS)

-		{

-			for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-			{

-				attributeBinding[i].erase(name);

-			}

-

-			attributeBinding[index].insert(name);

-		}

-	}

-

-	GLuint Program::getAttributeLocation(const char *name)

-	{

-		if(name)

-		{

-			for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)

-			{

-				if(linkedAttribute[index].name == std::string(name))

-				{

-					return index;

-				}

-			}

-		}

-

-		return -1;

-	}

-

-	int Program::getAttributeStream(int attributeIndex)

-	{

-		ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);

-    

-		return attributeStream[attributeIndex];

-	}

-

-	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)

-	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)

-	{

-		GLuint logicalTextureUnit = -1;

-

-		switch(type)

-		{

-		case sw::SAMPLER_PIXEL:

-			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));

-

-			if(samplersPS[samplerIndex].active)

-			{

-				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;

-			}

-			break;

-		case sw::SAMPLER_VERTEX:

-			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));

-

-			if(samplersVS[samplerIndex].active)

-			{

-				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;

-			}

-			break;

-		default: UNREACHABLE(type);

-		}

-

-		if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)

-		{

-			return logicalTextureUnit;

-		}

-

-		return -1;

-	}

-

-	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)

-	TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)

-	{

-		switch(type)

-		{

-		case sw::SAMPLER_PIXEL:

-			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));

-			ASSERT(samplersPS[samplerIndex].active);

-			return samplersPS[samplerIndex].textureType;

-		case sw::SAMPLER_VERTEX:

-			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));

-			ASSERT(samplersVS[samplerIndex].active);

-			return samplersVS[samplerIndex].textureType;

-		default: UNREACHABLE(type);

-		}

-

-		return TEXTURE_2D;

-	}

-

-	GLint Program::getUniformLocation(std::string name)

-	{

-		int subscript = 0;

-

-		// Strip any trailing array operator and retrieve the subscript

-		size_t open = name.find_last_of('[');

-		size_t close = name.find_last_of(']');

-		if(open != std::string::npos && close == name.length() - 1)

-		{

-			subscript = atoi(name.substr(open + 1).c_str());

-			name.erase(open);

-		}

-

-		unsigned int numUniforms = uniformIndex.size();

-		for(unsigned int location = 0; location < numUniforms; location++)

-		{

-			if(uniformIndex[location].name == name &&

-			   uniformIndex[location].element == subscript)

-			{

-				return location;

-			}

-		}

-

-		return -1;

-	}

-

-	bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_FLOAT)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat),

-				   v, sizeof(GLfloat) * count);

-		}

-		else if(targetUniform->type == GL_BOOL)

-		{

-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element;

-

-			for(int i = 0; i < count; i++)

-			{

-				if(v[i] == 0.0f)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_FLOAT_VEC2)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 2,

-				   v, 2 * sizeof(GLfloat) * count);

-		}

-		else if(targetUniform->type == GL_BOOL_VEC2)

-		{

-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 2;

-

-			for(int i = 0; i < count * 2; i++)

-			{

-				if(v[i] == 0.0f)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-		}

-		else 

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_FLOAT_VEC3)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 3,

-				   v, 3 * sizeof(GLfloat) * count);

-		}

-		else if(targetUniform->type == GL_BOOL_VEC3)

-		{

-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 3;

-

-			for(int i = 0; i < count * 3; i++)

-			{

-				if(v[i] == 0.0f)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-		}

-		else 

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_FLOAT_VEC4)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,

-				   v, 4 * sizeof(GLfloat) * count);

-		}

-		else if(targetUniform->type == GL_BOOL_VEC4)

-		{

-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 4;

-

-			for(int i = 0; i < count * 4; i++)

-			{

-				if(v[i] == 0.0f)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-		}

-		else 

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		if(targetUniform->type != GL_FLOAT_MAT2)

-		{

-			return false;

-		}

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,

-			   value, 4 * sizeof(GLfloat) * count);

-

-		return true;

-	}

-

-	bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		if(targetUniform->type != GL_FLOAT_MAT3)

-		{

-			return false;

-		}

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 9,

-			   value, 9 * sizeof(GLfloat) * count);

-

-		return true;

-	}

-

-	bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		if(targetUniform->type != GL_FLOAT_MAT4)

-		{

-			return false;

-		}

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 16,

-			   value, 16 * sizeof(GLfloat) * count);

-

-		return true;

-	}

-

-	bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_INT ||

-		   targetUniform->type == GL_SAMPLER_2D ||

-		   targetUniform->type == GL_SAMPLER_CUBE)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),

-				   v, sizeof(GLint) * count);

-		}

-		else if(targetUniform->type == GL_BOOL)

-		{

-			GLboolean *boolParams = new GLboolean[count];

-

-			for(int i = 0; i < count; i++)

-			{

-				if(v[i] == 0)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),

-				   boolParams, sizeof(GLboolean) * count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_INT_VEC2)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 2,

-				   v, 2 * sizeof(GLint) * count);

-		}

-		else if(targetUniform->type == GL_BOOL_VEC2)

-		{

-			GLboolean *boolParams = new GLboolean[count * 2];

-

-			for(int i = 0; i < count * 2; i++)

-			{

-				if(v[i] == 0)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 2,

-				   boolParams, 2 * sizeof(GLboolean) * count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_INT_VEC3)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 3,

-				   v, 3 * sizeof(GLint) * count);

-		}

-		else if(targetUniform->type == GL_BOOL_VEC3)

-		{

-			GLboolean *boolParams = new GLboolean[count * 3];

-

-			for(int i = 0; i < count * 3; i++)

-			{

-				if(v[i] == 0)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 3,

-				   boolParams, 3 * sizeof(GLboolean) * count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-	

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_INT_VEC4)

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 4,

-				   v, 4 * sizeof(GLint) * count);

-		}

-		else if(targetUniform->type == GL_BOOL_VEC4)

-		{

-			GLboolean *boolParams = new GLboolean[count * 4];

-

-			for(int i = 0; i < count * 4; i++)

-			{

-				if(v[i] == 0)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 4,

-				   boolParams, 4 * sizeof(GLboolean) * count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		unsigned int count = UniformComponentCount(targetUniform->type);

-

-		// Sized query - ensure the provided buffer is large enough

-		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))

-		{

-			return false;

-		}

-

-		switch(UniformComponentType(targetUniform->type))

-		{

-		case GL_BOOL:

-			{

-				GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;

-				}

-			}

-			break;

-		case GL_FLOAT:

-			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),

-				   count * sizeof(GLfloat));

-			break;

-		case GL_INT:

-			{

-				GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (float)intParams[i];

-				}

-			}

-			break;

-		default: UNREACHABLE(targetUniform->type);

-		}

-

-		return true;

-	}

-

-	bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		unsigned int count = UniformComponentCount(targetUniform->type);

-

-		// Sized query - ensure the provided buffer is large enough

-		if(bufSize && static_cast<unsigned int>(*bufSize) < count *sizeof(GLint))

-		{

-			return false;

-		}

-

-		switch(UniformComponentType(targetUniform->type))

-		{

-		case GL_BOOL:

-			{

-				GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (GLint)boolParams[i];

-				}

-			}

-			break;

-		case GL_FLOAT:

-			{

-				GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (GLint)floatParams[i];

-				}

-			}

-			break;

-		case GL_INT:

-			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),

-				   count * sizeof(GLint));

-			break;

-		default: UNREACHABLE(targetUniform->type);

-		}

-

-		return true;

-	}

-

-	void Program::dirtyAllUniforms()

-	{

-		unsigned int numUniforms = uniforms.size();

-		for(unsigned int index = 0; index < numUniforms; index++)

-		{

-			uniforms[index]->dirty = true;

-		}

-	}

-

-	// Applies all the uniforms set for this program object to the device

-	void Program::applyUniforms()

-	{

-		unsigned int numUniforms = uniformIndex.size();

-		for(unsigned int location = 0; location < numUniforms; location++)

-		{

-			if(uniformIndex[location].element != 0)

-			{

-				continue;

-			}

-

-			Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-			if(targetUniform->dirty)

-			{

-				int size = targetUniform->size();

-				GLfloat *f = (GLfloat*)targetUniform->data;

-				GLint *i = (GLint*)targetUniform->data;

-				GLboolean *b = (GLboolean*)targetUniform->data;

-

-				switch(targetUniform->type)

-				{

-				case GL_BOOL:       applyUniform1bv(location, size, b);       break;

-				case GL_BOOL_VEC2:  applyUniform2bv(location, size, b);       break;

-				case GL_BOOL_VEC3:  applyUniform3bv(location, size, b);       break;

-				case GL_BOOL_VEC4:  applyUniform4bv(location, size, b);       break;

-				case GL_FLOAT:      applyUniform1fv(location, size, f);       break;

-				case GL_FLOAT_VEC2: applyUniform2fv(location, size, f);       break;

-				case GL_FLOAT_VEC3: applyUniform3fv(location, size, f);       break;

-				case GL_FLOAT_VEC4: applyUniform4fv(location, size, f);       break;

-				case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, size, f); break;

-				case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, size, f); break;

-				case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, size, f); break;

-				case GL_SAMPLER_2D:

-				case GL_SAMPLER_CUBE:

-				case GL_INT:        applyUniform1iv(location, size, i);       break;

-				case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;

-				case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;

-				case GL_INT_VEC4:   applyUniform4iv(location, size, i);       break;

-				default:

-					UNREACHABLE(targetUniform->type);

-				}

-

-				targetUniform->dirty = false;

-			}

-		}

-	}

-

-	// Packs varyings into generic varying registers.

-	// Returns the number of used varying registers, or -1 if unsuccesful

-	int Program::packVaryings(const glsl::Varying *packing[][4])

-	{

-		for(glsl::VaryingList::iterator varying = fragmentShader->varyings.begin(); varying != fragmentShader->varyings.end(); varying++)

-		{

-			int n = VariableRowCount(varying->type) * varying->size();

-			int m = VariableColumnCount(varying->type);

-			bool success = false;

-

-			if(m == 2 || m == 3 || m == 4)

-			{

-				for(int r = 0; r <= MAX_VARYING_VECTORS - n && !success; r++)

-				{

-					bool available = true;

-

-					for(int y = 0; y < n && available; y++)

-					{

-						for(int x = 0; x < m && available; x++)

-						{

-							if(packing[r + y][x])

-							{

-								available = false;

-							}

-						}

-					}

-

-					if(available)

-					{

-						varying->reg = r;

-						varying->col = 0;

-

-						for(int y = 0; y < n; y++)

-						{

-							for(int x = 0; x < m; x++)

-							{

-								packing[r + y][x] = &*varying;

-							}

-						}

-

-						success = true;

-					}

-				}

-

-				if(!success && m == 2)

-				{

-					for(int r = MAX_VARYING_VECTORS - n; r >= 0 && !success; r--)

-					{

-						bool available = true;

-

-						for(int y = 0; y < n && available; y++)

-						{

-							for(int x = 2; x < 4 && available; x++)

-							{

-								if(packing[r + y][x])

-								{

-									available = false;

-								}

-							}

-						}

-

-						if(available)

-						{

-							varying->reg = r;

-							varying->col = 2;

-

-							for(int y = 0; y < n; y++)

-							{

-								for(int x = 2; x < 4; x++)

-								{

-									packing[r + y][x] = &*varying;

-								}

-							}

-

-							success = true;

-						}

-					}

-				}

-			}

-			else if(m == 1)

-			{

-				int space[4] = {0};

-

-				for(int y = 0; y < MAX_VARYING_VECTORS; y++)

-				{

-					for(int x = 0; x < 4; x++)

-					{

-						space[x] += packing[y][x] ? 0 : 1;

-					}

-				}

-

-				int column = 0;

-

-				for(int x = 0; x < 4; x++)

-				{

-					if(space[x] >= n && space[x] < space[column])

-					{

-						column = x;

-					}

-				}

-

-				if(space[column] >= n)

-				{

-					for(int r = 0; r < MAX_VARYING_VECTORS; r++)

-					{

-						if(!packing[r][column])

-						{

-							varying->reg = r;

-

-							for(int y = r; y < r + n; y++)

-							{

-								packing[y][column] = &*varying;

-							}

-

-							break;

-						}

-					}

-

-					varying->col = column;

-

-					success = true;

-				}

-			}

-			else UNREACHABLE(m);

-

-			if(!success)

-			{

-				appendToInfoLog("Could not pack varying %s", varying->name.c_str());

-

-				return -1;

-			}

-		}

-

-		// Return the number of used registers

-		int registers = 0;

-

-		for(int r = 0; r < MAX_VARYING_VECTORS; r++)

-		{

-			if(packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])

-			{

-				registers++;

-			}

-		}

-

-		return registers;

-	}

-

-	bool Program::linkVaryings()

-	{

-		for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); input++)

-		{

-			bool matched = false;

-

-			for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); output++)

-			{

-				if(output->name == input->name)

-				{

-					if(output->type != input->type || output->size() != input->size())

-					{

-						appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());

-

-						return false;

-					}

-

-					matched = true;

-					break;

-				}

-			}

-

-			if(!matched)

-			{

-				appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());

-

-				return false;

-			}

-		}

-

-		glsl::VaryingList &psVaryings = fragmentShader->varyings;

-		glsl::VaryingList &vsVaryings = vertexShader->varyings;

-

-		for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); output++)

-		{

-			for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); input++)

-			{

-				if(output->name == input->name)

-				{

-					int in = input->reg;

-					int out = output->reg;

-					int components = VariableColumnCount(output->type);

-					int registers = VariableRowCount(output->type) * output->size();

-

-					ASSERT(in >= 0);

-

-					if(in + registers > MAX_VARYING_VECTORS)

-					{

-						appendToInfoLog("Too many varyings");

-						return false;

-					}

-

-					if(out >= 0)

-					{

-						if(out + registers > MAX_VARYING_VECTORS)

-						{

-							appendToInfoLog("Too many varyings");

-							return false;

-						}

-

-						for(int i = 0; i < registers; i++)

-						{

-							if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-							if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-							if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-							if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-						}

-					}

-					else   // Vertex varying is declared but not written to

-					{

-						for(int i = 0; i < registers; i++)

-						{

-							if(components >= 1) pixelBinary->semantic[in + i][0] = sw::Shader::Semantic();

-							if(components >= 2) pixelBinary->semantic[in + i][1] = sw::Shader::Semantic();

-							if(components >= 3) pixelBinary->semantic[in + i][2] = sw::Shader::Semantic();

-							if(components >= 4) pixelBinary->semantic[in + i][3] = sw::Shader::Semantic();					

-						}

-					}

-

-					break;

-				}

-			}

-		}

-

-		return true;

-	}

-

-	// Links the code of the vertex and pixel shader by matching up their varyings,

-	// compiling them into binaries, determining the attribute mappings, and collecting

-	// a list of uniforms

-	void Program::link()

-	{

-		unlink();

-

-		if(!fragmentShader || !fragmentShader->isCompiled())

-		{

-			return;

-		}

-

-		if(!vertexShader || !vertexShader->isCompiled())

-		{

-			return;

-		}

-

-		vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());

-		pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());

-			

-		if(!linkVaryings())

-		{

-			return;

-		}

-

-		if(!linkAttributes())

-		{

-			return;

-		}

-

-		if(!linkUniforms(fragmentShader))

-		{

-			return;

-		}

-

-		if(!linkUniforms(vertexShader))

-		{

-			return;

-		}

-

-		linked = true;   // Success

-	}

-

-	// Determines the mapping between GL attributes and vertex stream usage indices

-	bool Program::linkAttributes()

-	{

-		unsigned int usedLocations = 0;

-

-		// Link attributes that have a binding location

-		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)

-		{

-			int location = getAttributeBinding(attribute->name);

-

-			if(location != -1)   // Set by glBindAttribLocation

-			{

-				if(!linkedAttribute[location].name.empty())

-				{

-					// Multiple active attributes bound to the same location; not an error

-				}

-

-				linkedAttribute[location] = *attribute;

-

-				int rows = VariableRowCount(attribute->type);

-

-				if(rows + location > MAX_VERTEX_ATTRIBS)

-				{

-					appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);

-					return false;

-				}

-

-				for(int i = 0; i < rows; i++)

-				{

-					usedLocations |= 1 << (location + i);

-				}

-			}

-		}

-

-		// Link attributes that don't have a binding location

-		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)

-		{

-			int location = getAttributeBinding(attribute->name);

-

-			if(location == -1)   // Not set by glBindAttribLocation

-			{

-				int rows = VariableRowCount(attribute->type);

-				int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);

-

-				if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)

-				{

-					appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());

-					return false;   // Fail to link

-				}

-

-				linkedAttribute[availableIndex] = *attribute;

-			}

-		}

-

-		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )

-		{

-			int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);

-			int rows = std::max(VariableRowCount(linkedAttribute[attributeIndex].type), 1);

-

-			for(int r = 0; r < rows; r++)

-			{

-				attributeStream[attributeIndex++] = index++;

-			}

-		}

-

-		return true;

-	}

-

-	int Program::getAttributeBinding(const std::string &name)

-	{

-		for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)

-		{

-			if(attributeBinding[location].find(name) != attributeBinding[location].end())

-			{

-				return location;

-			}

-		}

-

-		return -1;

-	}

-

-	bool Program::linkUniforms(Shader *shader)

-	{

-		const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;

-

-		for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)

-		{

-			const glsl::Uniform &uniform = activeUniforms[uniformIndex];

-

-			if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex))

-			{

-				return false;

-			}

-		}

-

-		return true;

-	}

-

-	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex)

-	{

-		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE)

-	    {

-			int index = registerIndex;

-			

-			do

-			{

-				if(shader == GL_VERTEX_SHADER)

-				{

-					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)

-					{

-						samplersVS[index].active = true;

-						samplersVS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;

-						samplersVS[index].logicalTextureUnit = 0;

-					}

-					else

-					{

-					   appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);

-					   return false;

-					}

-				}

-				else if(shader == GL_FRAGMENT_SHADER)

-				{

-					if(index < MAX_TEXTURE_IMAGE_UNITS)

-					{

-						samplersPS[index].active = true;

-						samplersPS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;

-						samplersPS[index].logicalTextureUnit = 0;

-					}

-					else

-					{

-						appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);

-						return false;

-					}

-				}

-				else UNREACHABLE(shader);

-

-				index++;

-			}

-			while(index < registerIndex + static_cast<int>(arraySize));

-	    }

-

-		Uniform *uniform = 0;

-		GLint location = getUniformLocation(name);

-

-		if(location >= 0)   // Previously defined, types must match

-		{

-			uniform = uniforms[uniformIndex[location].index];

-

-			if(uniform->type != type)

-			{

-				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());

-				return false;

-			}

-

-			if(uniform->precision != precision)

-			{

-				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());

-				return false;

-			}

-		}

-		else

-		{

-			uniform = new Uniform(type, precision, name, arraySize);

-		}

-

-		if(!uniform)

-		{

-			return false;

-		}

-

-		if(shader == GL_VERTEX_SHADER)

-		{

-			uniform->vsRegisterIndex = registerIndex;

-		}

-		else if(shader == GL_FRAGMENT_SHADER)

-		{

-			uniform->psRegisterIndex = registerIndex;

-		}

-		else UNREACHABLE(shader);

-

-		if(location == -1)   // Not previously defined

-		{

-			uniforms.push_back(uniform);

-			unsigned int index = uniforms.size() - 1;

-

-			for(int i = 0; i < uniform->size(); i++)

-			{

-				uniformIndex.push_back(UniformLocation(name, i, index));

-			}

-		}

-

-		if(shader == GL_VERTEX_SHADER)

-		{

-			if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)

-			{

-				appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);

-				return false;

-			}

-		}

-		else if(shader == GL_FRAGMENT_SHADER)

-		{

-			if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)

-			{

-				appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);

-				return false;

-			}

-		}

-		else UNREACHABLE(shader);

-

-		return true;

-	}

-

-	bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = 0;

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 1;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 2;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][3] = 0;

-

-			v += 3;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-

-			v += 4;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = 0;

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 1;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 2;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = v[2];

-			vector[i][3] = 0;

-

-			v += 3;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)v, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)v, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;

-

-			value += 4;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2];	matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5];	matrix[i][1][3] = 0;

-			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];	matrix[i][2][2] = value[8];	matrix[i][2][3] = 0;

-

-			value += 9;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{	

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-	

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)value, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)value, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (float)v[i];

-			vector[i][1] = 0;

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-            if(targetUniform->type == GL_SAMPLER_2D ||

-               targetUniform->type == GL_SAMPLER_CUBE)

-			{

-				for(int i = 0; i < count; i++)

-				{

-					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;

-

-					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)

-					{

-						ASSERT(samplersPS[samplerIndex].active);

-						samplersPS[samplerIndex].logicalTextureUnit = v[i];

-					}

-				}

-			}

-			else

-			{

-				device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-			}

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			if(targetUniform->type == GL_SAMPLER_2D ||

-               targetUniform->type == GL_SAMPLER_CUBE)

-			{

-				for(int i = 0; i < count; i++)

-				{

-					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;

-

-					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)

-					{

-						ASSERT(samplersVS[samplerIndex].active);

-						samplersVS[samplerIndex].logicalTextureUnit = v[i];

-					}

-				}

-			}

-			else

-			{

-				device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-			}

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (float)v[0];

-			vector[i][1] = (float)v[1];

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 2;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (float)v[0];

-			vector[i][1] = (float)v[1];

-			vector[i][2] = (float)v[2];

-			vector[i][3] = 0;

-

-			v += 3;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (float)v[0];

-			vector[i][1] = (float)v[1];

-			vector[i][2] = (float)v[2];

-			vector[i][3] = (float)v[3];

-

-			v += 4;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	void Program::appendToInfoLog(const char *format, ...)

-	{

-		if(!format)

-		{

-			return;

-		}

-

-		char info[1024];

-

-		va_list vararg;

-		va_start(vararg, format);

-		vsnprintf(info, sizeof(info), format, vararg);

-		va_end(vararg);

-

-		size_t infoLength = strlen(info);

-

-		if(!infoLog)

-		{

-			infoLog = new char[infoLength + 2];

-			strcpy(infoLog, info);

-			strcpy(infoLog + infoLength, "\n");

-		}

-		else

-		{

-			size_t logLength = strlen(infoLog);

-			char *newLog = new char[logLength + infoLength + 2];

-			strcpy(newLog, infoLog);

-			strcpy(newLog + logLength, info);

-			strcpy(newLog + logLength + infoLength, "\n");

-

-			delete[] infoLog;

-			infoLog = newLog;

-		}

-	}

-

-	void Program::resetInfoLog()

-	{

-		if(infoLog)

-		{

-			delete[] infoLog;

-			infoLog = 0;

-		}

-	}

-

-	// Returns the program object to an unlinked state, before re-linking, or at destruction

-	void Program::unlink()

-	{

-		delete vertexBinary;

-		vertexBinary = 0;

-		delete pixelBinary;

-		pixelBinary = 0;

-

-		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)

-		{

-			linkedAttribute[index].name.clear();

-			attributeStream[index] = -1;

-		}

-

-		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)

-		{

-			samplersPS[index].active = false;

-		}

-

-		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)

-		{

-			samplersVS[index].active = false;

-		}

-

-		while(!uniforms.empty())

-		{

-			delete uniforms.back();

-			uniforms.pop_back();

-		}

-

-		uniformIndex.clear();

-

-		delete[] infoLog;

-		infoLog = 0;

-

-		linked = false;

-	}

-

-	bool Program::isLinked()

-	{

-		return linked;

-	}

-

-	bool Program::isValidated() const 

-	{

-		return validated;

-	}

-

-	void Program::release()

-	{

-		referenceCount--;

-

-		if(referenceCount == 0 && orphaned)

-		{

-			resourceManager->deleteProgram(handle);

-		}

-	}

-

-	void Program::addRef()

-	{

-		referenceCount++;

-	}

-

-	unsigned int Program::getRefCount() const

-	{

-		return referenceCount;

-	}

-

-	unsigned int Program::getSerial() const

-	{

-		return serial;

-	}

-

-	unsigned int Program::issueSerial()

-	{

-		return currentSerial++;

-	}

-

-	int Program::getInfoLogLength() const

-	{

-		if(!infoLog)

-		{

-			return 0;

-		}

-		else

-		{

-		   return strlen(infoLog) + 1;

-		}

-	}

-

-	void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)

-	{

-		int index = 0;

-

-		if(bufSize > 0)

-		{

-			if(infoLog)

-			{

-				index = std::min(bufSize - 1, (int)strlen(infoLog));

-				memcpy(buffer, infoLog, index);

-			}

-

-			buffer[index] = '\0';

-		}

-

-		if(length)

-		{

-			*length = index;

-		}

-	}

-

-	void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)

-	{

-		int total = 0;

-

-		if(vertexShader)

-		{

-			if(total < maxCount)

-			{

-				shaders[total] = vertexShader->getName();

-			}

-

-			total++;

-		}

-

-		if(fragmentShader)

-		{

-			if(total < maxCount)

-			{

-				shaders[total] = fragmentShader->getName();

-			}

-

-			total++;

-		}

-

-		if(count)

-		{

-			*count = total;

-		}

-	}

-

-	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const

-	{

-		// Skip over inactive attributes

-		unsigned int activeAttribute = 0;

-		unsigned int attribute;

-		for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)

-		{

-			if(linkedAttribute[attribute].name.empty())

-			{

-				continue;

-			}

-

-			if(activeAttribute == index)

-			{

-				break;

-			}

-

-			activeAttribute++;

-		}

-

-		if(bufsize > 0)

-		{

-			const char *string = linkedAttribute[attribute].name.c_str();

-

-			strncpy(name, string, bufsize);

-			name[bufsize - 1] = '\0';

-

-			if(length)

-			{

-				*length = strlen(name);

-			}

-		}

-

-		*size = 1;   // Always a single 'type' instance

-

-		*type = linkedAttribute[attribute].type;

-	}

-

-	size_t Program::getActiveAttributeCount() const

-	{

-		size_t count = 0;

-

-		for(size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ++attributeIndex)

-		{

-			if(!linkedAttribute[attributeIndex].name.empty())

-			{

-				count++;

-			}

-		}

-

-		return count;

-	}

-

-	GLint Program::getActiveAttributeMaxLength() const

-	{

-		int maxLength = 0;

-

-		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)

-		{

-			if(!linkedAttribute[attributeIndex].name.empty())

-			{

-				maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);

-			}

-		}

-

-		return maxLength;

-	}

-

-	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const

-	{

-		if(bufsize > 0)

-		{

-			std::string string = uniforms[index]->name;

-

-			if(uniforms[index]->isArray())

-			{

-				string += "[0]";

-			}

-

-			strncpy(name, string.c_str(), bufsize);

-			name[bufsize - 1] = '\0';

-

-			if(length)

-			{

-				*length = strlen(name);

-			}

-		}

-

-		*size = uniforms[index]->size();

-

-		*type = uniforms[index]->type;

-	}

-

-	size_t Program::getActiveUniformCount() const

-	{

-		return uniforms.size();

-	}

-

-	GLint Program::getActiveUniformMaxLength() const

-	{

-		int maxLength = 0;

-

-		unsigned int numUniforms = uniforms.size();

-		for(unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)

-		{

-			if(!uniforms[uniformIndex]->name.empty())

-			{

-				int length = (int)(uniforms[uniformIndex]->name.length() + 1);

-				if(uniforms[uniformIndex]->isArray())

-				{

-					length += 3;  // Counting in "[0]".

-				}

-				maxLength = std::max(length, maxLength);

-			}

-		}

-

-		return maxLength;

-	}

-

-	void Program::flagForDeletion()

-	{

-		orphaned = true;

-	}

-

-	bool Program::isFlaggedForDeletion() const

-	{

-		return orphaned;

-	}

-

-	void Program::validate()

-	{

-		resetInfoLog();

-

-		if(!isLinked()) 

-		{

-			appendToInfoLog("Program has not been successfully linked.");

-			validated = false;

-		}

-		else

-		{

-			applyUniforms();

-			if(!validateSamplers(true))

-			{

-				validated = false;

-			}

-			else

-			{

-				validated = true;

-			}

-		}

-	}

-

-	bool Program::validateSamplers(bool logErrors)

-	{

-		// if any two active samplers in a program are of different types, but refer to the same

-		// texture image unit, and this is the current program, then ValidateProgram will fail, and

-		// DrawArrays and DrawElements will issue the INVALID_OPERATION error.

-

-		TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];

-

-		for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)

-		{

-			textureUnitType[i] = TEXTURE_UNKNOWN;

-		}

-

-		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)

-		{

-			if(samplersPS[i].active)

-			{

-				unsigned int unit = samplersPS[i].logicalTextureUnit;

-            

-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)

-				{

-					if(logErrors)

-					{

-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);

-					}

-

-					return false;

-				}

-

-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)

-				{

-					if(samplersPS[i].textureType != textureUnitType[unit])

-					{

-						if(logErrors)

-						{

-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);

-						}

-

-						return false;

-					}

-				}

-				else

-				{

-					textureUnitType[unit] = samplersPS[i].textureType;

-				}

-			}

-		}

-

-		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)

-		{

-			if(samplersVS[i].active)

-			{

-				unsigned int unit = samplersVS[i].logicalTextureUnit;

-            

-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)

-				{

-					if(logErrors)

-					{

-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);

-					}

-

-					return false;

-				}

-

-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)

-				{

-					if(samplersVS[i].textureType != textureUnitType[unit])

-					{

-						if(logErrors)

-						{

-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);

-						}

-

-						return false;

-					}

-				}

-				else

-				{

-					textureUnitType[unit] = samplersVS[i].textureType;

-				}

-			}

-		}

-

-		return true;

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Program.cpp: Implements the Program class. Implements GL program objects
+// and related functionality.
+
+#include "Program.h"
+
+#include "main.h"
+#include "Shader.h"
+#include "utilities.h"
+#include "common/debug.h"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+
+#include <string>
+#include <stdlib.h>
+
+namespace gl
+{
+	unsigned int Program::currentSerial = 1;
+
+	std::string str(int i)
+	{
+		char buffer[20];
+		sprintf(buffer, "%d", i);
+		return buffer;
+	}
+
+	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) : type(type), precision(precision), name(name), arraySize(arraySize)
+	{
+		int bytes = UniformTypeSize(type) * size();
+		data = new unsigned char[bytes];
+		memset(data, 0, bytes);
+		dirty = true;
+
+		psRegisterIndex = -1;
+		vsRegisterIndex = -1;
+	}
+
+	Uniform::~Uniform()
+	{
+		delete[] data;
+	}
+
+	bool Uniform::isArray() const
+	{
+		return arraySize >= 1;
+	}
+
+	int Uniform::size() const
+	{
+		return arraySize > 0 ? arraySize : 1;
+	}
+
+	int Uniform::registerCount() const
+	{
+		return size() * VariableRowCount(type);
+	}
+
+	UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
+	{
+	}
+
+	Program::Program(ResourceManager *manager, GLuint handle) : resourceManager(manager), handle(handle), serial(issueSerial())
+	{
+		device = getDevice();
+
+		fragmentShader = 0;
+		vertexShader = 0;
+		pixelBinary = 0;
+		vertexBinary = 0;
+
+		infoLog = 0;
+		validated = false;
+
+		unlink();
+
+		orphaned = false;
+		referenceCount = 0;
+	}
+
+	Program::~Program()
+	{
+		unlink();
+
+		if(vertexShader)
+		{
+			vertexShader->release();
+		}
+
+		if(fragmentShader)
+		{
+			fragmentShader->release();
+		}
+	}
+
+	bool Program::attachShader(Shader *shader)
+	{
+		if(shader->getType() == GL_VERTEX_SHADER)
+		{
+			if(vertexShader)
+			{
+				return false;
+			}
+
+			vertexShader = (VertexShader*)shader;
+			vertexShader->addRef();
+		}
+		else if(shader->getType() == GL_FRAGMENT_SHADER)
+		{
+			if(fragmentShader)
+			{
+				return false;
+			}
+
+			fragmentShader = (FragmentShader*)shader;
+			fragmentShader->addRef();
+		}
+		else UNREACHABLE(shader->getType());
+
+		return true;
+	}
+
+	bool Program::detachShader(Shader *shader)
+	{
+		if(shader->getType() == GL_VERTEX_SHADER)
+		{
+			if(vertexShader != shader)
+			{
+				return false;
+			}
+
+			vertexShader->release();
+			vertexShader = 0;
+		}
+		else if(shader->getType() == GL_FRAGMENT_SHADER)
+		{
+			if(fragmentShader != shader)
+			{
+				return false;
+			}
+
+			fragmentShader->release();
+			fragmentShader = 0;
+		}
+		else UNREACHABLE(shader->getType());
+
+		return true;
+	}
+
+	int Program::getAttachedShadersCount() const
+	{
+		return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
+	}
+
+	sw::PixelShader *Program::getPixelShader()
+	{
+		return pixelBinary;
+	}
+
+	sw::VertexShader *Program::getVertexShader()
+	{
+		return vertexBinary;
+	}
+
+	void Program::bindAttributeLocation(GLuint index, const char *name)
+	{
+		if(index < MAX_VERTEX_ATTRIBS)
+		{
+			for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+			{
+				attributeBinding[i].erase(name);
+			}
+
+			attributeBinding[index].insert(name);
+		}
+	}
+
+	GLuint Program::getAttributeLocation(const char *name)
+	{
+		if(name)
+		{
+			for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+			{
+				if(linkedAttribute[index].name == std::string(name))
+				{
+					return index;
+				}
+			}
+		}
+
+		return -1;
+	}
+
+	int Program::getAttributeStream(int attributeIndex)
+	{
+		ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
+
+		return attributeStream[attributeIndex];
+	}
+
+	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)
+	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
+	{
+		GLuint logicalTextureUnit = -1;
+
+		switch(type)
+		{
+		case sw::SAMPLER_PIXEL:
+			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
+
+			if(samplersPS[samplerIndex].active)
+			{
+				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
+			}
+			break;
+		case sw::SAMPLER_VERTEX:
+			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
+
+			if(samplersVS[samplerIndex].active)
+			{
+				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
+			}
+			break;
+		default: UNREACHABLE(type);
+		}
+
+		if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+		{
+			return logicalTextureUnit;
+		}
+
+		return -1;
+	}
+
+	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
+	TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)
+	{
+		switch(type)
+		{
+		case sw::SAMPLER_PIXEL:
+			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
+			ASSERT(samplersPS[samplerIndex].active);
+			return samplersPS[samplerIndex].textureType;
+		case sw::SAMPLER_VERTEX:
+			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
+			ASSERT(samplersVS[samplerIndex].active);
+			return samplersVS[samplerIndex].textureType;
+		default: UNREACHABLE(type);
+		}
+
+		return TEXTURE_2D;
+	}
+
+	GLint Program::getUniformLocation(std::string name)
+	{
+		int subscript = 0;
+
+		// Strip any trailing array operator and retrieve the subscript
+		size_t open = name.find_last_of('[');
+		size_t close = name.find_last_of(']');
+		if(open != std::string::npos && close == name.length() - 1)
+		{
+			subscript = atoi(name.substr(open + 1).c_str());
+			name.erase(open);
+		}
+
+		unsigned int numUniforms = uniformIndex.size();
+		for(unsigned int location = 0; location < numUniforms; location++)
+		{
+			if(uniformIndex[location].name == name &&
+			   uniformIndex[location].element == subscript)
+			{
+				return location;
+			}
+		}
+
+		return -1;
+	}
+
+	bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_FLOAT)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat),
+				   v, sizeof(GLfloat) * count);
+		}
+		else if(targetUniform->type == GL_BOOL)
+		{
+			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element;
+
+			for(int i = 0; i < count; i++)
+			{
+				if(v[i] == 0.0f)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_FLOAT_VEC2)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 2,
+				   v, 2 * sizeof(GLfloat) * count);
+		}
+		else if(targetUniform->type == GL_BOOL_VEC2)
+		{
+			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 2;
+
+			for(int i = 0; i < count * 2; i++)
+			{
+				if(v[i] == 0.0f)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_FLOAT_VEC3)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 3,
+				   v, 3 * sizeof(GLfloat) * count);
+		}
+		else if(targetUniform->type == GL_BOOL_VEC3)
+		{
+			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 3;
+
+			for(int i = 0; i < count * 3; i++)
+			{
+				if(v[i] == 0.0f)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_FLOAT_VEC4)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,
+				   v, 4 * sizeof(GLfloat) * count);
+		}
+		else if(targetUniform->type == GL_BOOL_VEC4)
+		{
+			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 4;
+
+			for(int i = 0; i < count * 4; i++)
+			{
+				if(v[i] == 0.0f)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		if(targetUniform->type != GL_FLOAT_MAT2)
+		{
+			return false;
+		}
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,
+			   value, 4 * sizeof(GLfloat) * count);
+
+		return true;
+	}
+
+	bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		if(targetUniform->type != GL_FLOAT_MAT3)
+		{
+			return false;
+		}
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 9,
+			   value, 9 * sizeof(GLfloat) * count);
+
+		return true;
+	}
+
+	bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		if(targetUniform->type != GL_FLOAT_MAT4)
+		{
+			return false;
+		}
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 16,
+			   value, 16 * sizeof(GLfloat) * count);
+
+		return true;
+	}
+
+	bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_INT ||
+		   targetUniform->type == GL_SAMPLER_2D ||
+		   targetUniform->type == GL_SAMPLER_CUBE)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
+				   v, sizeof(GLint) * count);
+		}
+		else if(targetUniform->type == GL_BOOL)
+		{
+			GLboolean *boolParams = new GLboolean[count];
+
+			for(int i = 0; i < count; i++)
+			{
+				if(v[i] == 0)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
+				   boolParams, sizeof(GLboolean) * count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_INT_VEC2)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 2,
+				   v, 2 * sizeof(GLint) * count);
+		}
+		else if(targetUniform->type == GL_BOOL_VEC2)
+		{
+			GLboolean *boolParams = new GLboolean[count * 2];
+
+			for(int i = 0; i < count * 2; i++)
+			{
+				if(v[i] == 0)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 2,
+				   boolParams, 2 * sizeof(GLboolean) * count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_INT_VEC3)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 3,
+				   v, 3 * sizeof(GLint) * count);
+		}
+		else if(targetUniform->type == GL_BOOL_VEC3)
+		{
+			GLboolean *boolParams = new GLboolean[count * 3];
+
+			for(int i = 0; i < count * 3; i++)
+			{
+				if(v[i] == 0)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 3,
+				   boolParams, 3 * sizeof(GLboolean) * count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_INT_VEC4)
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 4,
+				   v, 4 * sizeof(GLint) * count);
+		}
+		else if(targetUniform->type == GL_BOOL_VEC4)
+		{
+			GLboolean *boolParams = new GLboolean[count * 4];
+
+			for(int i = 0; i < count * 4; i++)
+			{
+				if(v[i] == 0)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 4,
+				   boolParams, 4 * sizeof(GLboolean) * count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		unsigned int count = UniformComponentCount(targetUniform->type);
+
+		// Sized query - ensure the provided buffer is large enough
+		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))
+		{
+			return false;
+		}
+
+		switch(UniformComponentType(targetUniform->type))
+		{
+		case GL_BOOL:
+			{
+				GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
+				}
+			}
+			break;
+		case GL_FLOAT:
+			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
+				   count * sizeof(GLfloat));
+			break;
+		case GL_INT:
+			{
+				GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (float)intParams[i];
+				}
+			}
+			break;
+		default: UNREACHABLE(targetUniform->type);
+		}
+
+		return true;
+	}
+
+	bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		unsigned int count = UniformComponentCount(targetUniform->type);
+
+		// Sized query - ensure the provided buffer is large enough
+		if(bufSize && static_cast<unsigned int>(*bufSize) < count *sizeof(GLint))
+		{
+			return false;
+		}
+
+		switch(UniformComponentType(targetUniform->type))
+		{
+		case GL_BOOL:
+			{
+				GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (GLint)boolParams[i];
+				}
+			}
+			break;
+		case GL_FLOAT:
+			{
+				GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (GLint)floatParams[i];
+				}
+			}
+			break;
+		case GL_INT:
+			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
+				   count * sizeof(GLint));
+			break;
+		default: UNREACHABLE(targetUniform->type);
+		}
+
+		return true;
+	}
+
+	void Program::dirtyAllUniforms()
+	{
+		unsigned int numUniforms = uniforms.size();
+		for(unsigned int index = 0; index < numUniforms; index++)
+		{
+			uniforms[index]->dirty = true;
+		}
+	}
+
+	// Applies all the uniforms set for this program object to the device
+	void Program::applyUniforms()
+	{
+		unsigned int numUniforms = uniformIndex.size();
+		for(unsigned int location = 0; location < numUniforms; location++)
+		{
+			if(uniformIndex[location].element != 0)
+			{
+				continue;
+			}
+
+			Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+			if(targetUniform->dirty)
+			{
+				int size = targetUniform->size();
+				GLfloat *f = (GLfloat*)targetUniform->data;
+				GLint *i = (GLint*)targetUniform->data;
+				GLboolean *b = (GLboolean*)targetUniform->data;
+
+				switch(targetUniform->type)
+				{
+				case GL_BOOL:       applyUniform1bv(location, size, b);       break;
+				case GL_BOOL_VEC2:  applyUniform2bv(location, size, b);       break;
+				case GL_BOOL_VEC3:  applyUniform3bv(location, size, b);       break;
+				case GL_BOOL_VEC4:  applyUniform4bv(location, size, b);       break;
+				case GL_FLOAT:      applyUniform1fv(location, size, f);       break;
+				case GL_FLOAT_VEC2: applyUniform2fv(location, size, f);       break;
+				case GL_FLOAT_VEC3: applyUniform3fv(location, size, f);       break;
+				case GL_FLOAT_VEC4: applyUniform4fv(location, size, f);       break;
+				case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, size, f); break;
+				case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, size, f); break;
+				case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, size, f); break;
+				case GL_SAMPLER_2D:
+				case GL_SAMPLER_CUBE:
+				case GL_INT:        applyUniform1iv(location, size, i);       break;
+				case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;
+				case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;
+				case GL_INT_VEC4:   applyUniform4iv(location, size, i);       break;
+				default:
+					UNREACHABLE(targetUniform->type);
+				}
+
+				targetUniform->dirty = false;
+			}
+		}
+	}
+
+	// Packs varyings into generic varying registers.
+	// Returns the number of used varying registers, or -1 if unsuccesful
+	int Program::packVaryings(const glsl::Varying *packing[][4])
+	{
+		for(glsl::VaryingList::iterator varying = fragmentShader->varyings.begin(); varying != fragmentShader->varyings.end(); varying++)
+		{
+			int n = VariableRowCount(varying->type) * varying->size();
+			int m = VariableColumnCount(varying->type);
+			bool success = false;
+
+			if(m == 2 || m == 3 || m == 4)
+			{
+				for(int r = 0; r <= MAX_VARYING_VECTORS - n && !success; r++)
+				{
+					bool available = true;
+
+					for(int y = 0; y < n && available; y++)
+					{
+						for(int x = 0; x < m && available; x++)
+						{
+							if(packing[r + y][x])
+							{
+								available = false;
+							}
+						}
+					}
+
+					if(available)
+					{
+						varying->reg = r;
+						varying->col = 0;
+
+						for(int y = 0; y < n; y++)
+						{
+							for(int x = 0; x < m; x++)
+							{
+								packing[r + y][x] = &*varying;
+							}
+						}
+
+						success = true;
+					}
+				}
+
+				if(!success && m == 2)
+				{
+					for(int r = MAX_VARYING_VECTORS - n; r >= 0 && !success; r--)
+					{
+						bool available = true;
+
+						for(int y = 0; y < n && available; y++)
+						{
+							for(int x = 2; x < 4 && available; x++)
+							{
+								if(packing[r + y][x])
+								{
+									available = false;
+								}
+							}
+						}
+
+						if(available)
+						{
+							varying->reg = r;
+							varying->col = 2;
+
+							for(int y = 0; y < n; y++)
+							{
+								for(int x = 2; x < 4; x++)
+								{
+									packing[r + y][x] = &*varying;
+								}
+							}
+
+							success = true;
+						}
+					}
+				}
+			}
+			else if(m == 1)
+			{
+				int space[4] = {0};
+
+				for(int y = 0; y < MAX_VARYING_VECTORS; y++)
+				{
+					for(int x = 0; x < 4; x++)
+					{
+						space[x] += packing[y][x] ? 0 : 1;
+					}
+				}
+
+				int column = 0;
+
+				for(int x = 0; x < 4; x++)
+				{
+					if(space[x] >= n && space[x] < space[column])
+					{
+						column = x;
+					}
+				}
+
+				if(space[column] >= n)
+				{
+					for(int r = 0; r < MAX_VARYING_VECTORS; r++)
+					{
+						if(!packing[r][column])
+						{
+							varying->reg = r;
+
+							for(int y = r; y < r + n; y++)
+							{
+								packing[y][column] = &*varying;
+							}
+
+							break;
+						}
+					}
+
+					varying->col = column;
+
+					success = true;
+				}
+			}
+			else UNREACHABLE(m);
+
+			if(!success)
+			{
+				appendToInfoLog("Could not pack varying %s", varying->name.c_str());
+
+				return -1;
+			}
+		}
+
+		// Return the number of used registers
+		int registers = 0;
+
+		for(int r = 0; r < MAX_VARYING_VECTORS; r++)
+		{
+			if(packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
+			{
+				registers++;
+			}
+		}
+
+		return registers;
+	}
+
+	bool Program::linkVaryings()
+	{
+		for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); input++)
+		{
+			bool matched = false;
+
+			for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); output++)
+			{
+				if(output->name == input->name)
+				{
+					if(output->type != input->type || output->size() != input->size())
+					{
+						appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
+
+						return false;
+					}
+
+					matched = true;
+					break;
+				}
+			}
+
+			if(!matched)
+			{
+				appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
+
+				return false;
+			}
+		}
+
+		glsl::VaryingList &psVaryings = fragmentShader->varyings;
+		glsl::VaryingList &vsVaryings = vertexShader->varyings;
+
+		for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); output++)
+		{
+			for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); input++)
+			{
+				if(output->name == input->name)
+				{
+					int in = input->reg;
+					int out = output->reg;
+					int components = VariableColumnCount(output->type);
+					int registers = VariableRowCount(output->type) * output->size();
+
+					ASSERT(in >= 0);
+
+					if(in + registers > MAX_VARYING_VECTORS)
+					{
+						appendToInfoLog("Too many varyings");
+						return false;
+					}
+
+					if(out >= 0)
+					{
+						if(out + registers > MAX_VARYING_VECTORS)
+						{
+							appendToInfoLog("Too many varyings");
+							return false;
+						}
+
+						for(int i = 0; i < registers; i++)
+						{
+							if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+							if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+							if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+							if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+						}
+					}
+					else   // Vertex varying is declared but not written to
+					{
+						for(int i = 0; i < registers; i++)
+						{
+							if(components >= 1) pixelBinary->semantic[in + i][0] = sw::Shader::Semantic();
+							if(components >= 2) pixelBinary->semantic[in + i][1] = sw::Shader::Semantic();
+							if(components >= 3) pixelBinary->semantic[in + i][2] = sw::Shader::Semantic();
+							if(components >= 4) pixelBinary->semantic[in + i][3] = sw::Shader::Semantic();
+						}
+					}
+
+					break;
+				}
+			}
+		}
+
+		return true;
+	}
+
+	// Links the code of the vertex and pixel shader by matching up their varyings,
+	// compiling them into binaries, determining the attribute mappings, and collecting
+	// a list of uniforms
+	void Program::link()
+	{
+		unlink();
+
+		if(!fragmentShader || !fragmentShader->isCompiled())
+		{
+			return;
+		}
+
+		if(!vertexShader || !vertexShader->isCompiled())
+		{
+			return;
+		}
+
+		vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
+		pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
+
+		if(!linkVaryings())
+		{
+			return;
+		}
+
+		if(!linkAttributes())
+		{
+			return;
+		}
+
+		if(!linkUniforms(fragmentShader))
+		{
+			return;
+		}
+
+		if(!linkUniforms(vertexShader))
+		{
+			return;
+		}
+
+		linked = true;   // Success
+	}
+
+	// Determines the mapping between GL attributes and vertex stream usage indices
+	bool Program::linkAttributes()
+	{
+		unsigned int usedLocations = 0;
+
+		// Link attributes that have a binding location
+		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)
+		{
+			int location = getAttributeBinding(attribute->name);
+
+			if(location != -1)   // Set by glBindAttribLocation
+			{
+				if(!linkedAttribute[location].name.empty())
+				{
+					// Multiple active attributes bound to the same location; not an error
+				}
+
+				linkedAttribute[location] = *attribute;
+
+				int rows = VariableRowCount(attribute->type);
+
+				if(rows + location > MAX_VERTEX_ATTRIBS)
+				{
+					appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
+					return false;
+				}
+
+				for(int i = 0; i < rows; i++)
+				{
+					usedLocations |= 1 << (location + i);
+				}
+			}
+		}
+
+		// Link attributes that don't have a binding location
+		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)
+		{
+			int location = getAttributeBinding(attribute->name);
+
+			if(location == -1)   // Not set by glBindAttribLocation
+			{
+				int rows = VariableRowCount(attribute->type);
+				int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
+
+				if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
+				{
+					appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
+					return false;   // Fail to link
+				}
+
+				linkedAttribute[availableIndex] = *attribute;
+			}
+		}
+
+		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
+		{
+			int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
+			int rows = std::max(VariableRowCount(linkedAttribute[attributeIndex].type), 1);
+
+			for(int r = 0; r < rows; r++)
+			{
+				attributeStream[attributeIndex++] = index++;
+			}
+		}
+
+		return true;
+	}
+
+	int Program::getAttributeBinding(const std::string &name)
+	{
+		for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
+		{
+			if(attributeBinding[location].find(name) != attributeBinding[location].end())
+			{
+				return location;
+			}
+		}
+
+		return -1;
+	}
+
+	bool Program::linkUniforms(Shader *shader)
+	{
+		const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
+
+		for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
+		{
+			const glsl::Uniform &uniform = activeUniforms[uniformIndex];
+
+			if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex))
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex)
+	{
+		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE)
+		{
+			int index = registerIndex;
+
+			do
+			{
+				if(shader == GL_VERTEX_SHADER)
+				{
+					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					{
+						samplersVS[index].active = true;
+						samplersVS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+						samplersVS[index].logicalTextureUnit = 0;
+					}
+					else
+					{
+					   appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+					   return false;
+					}
+				}
+				else if(shader == GL_FRAGMENT_SHADER)
+				{
+					if(index < MAX_TEXTURE_IMAGE_UNITS)
+					{
+						samplersPS[index].active = true;
+						samplersPS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+						samplersPS[index].logicalTextureUnit = 0;
+					}
+					else
+					{
+						appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
+						return false;
+					}
+				}
+				else UNREACHABLE(shader);
+
+				index++;
+			}
+			while(index < registerIndex + static_cast<int>(arraySize));
+		}
+
+		Uniform *uniform = 0;
+		GLint location = getUniformLocation(name);
+
+		if(location >= 0)   // Previously defined, types must match
+		{
+			uniform = uniforms[uniformIndex[location].index];
+
+			if(uniform->type != type)
+			{
+				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
+				return false;
+			}
+
+			if(uniform->precision != precision)
+			{
+				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
+				return false;
+			}
+		}
+		else
+		{
+			uniform = new Uniform(type, precision, name, arraySize);
+		}
+
+		if(!uniform)
+		{
+			return false;
+		}
+
+		if(shader == GL_VERTEX_SHADER)
+		{
+			uniform->vsRegisterIndex = registerIndex;
+		}
+		else if(shader == GL_FRAGMENT_SHADER)
+		{
+			uniform->psRegisterIndex = registerIndex;
+		}
+		else UNREACHABLE(shader);
+
+		if(location == -1)   // Not previously defined
+		{
+			uniforms.push_back(uniform);
+			unsigned int index = uniforms.size() - 1;
+
+			for(int i = 0; i < uniform->size(); i++)
+			{
+				uniformIndex.push_back(UniformLocation(name, i, index));
+			}
+		}
+
+		if(shader == GL_VERTEX_SHADER)
+		{
+			if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
+			{
+				appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
+				return false;
+			}
+		}
+		else if(shader == GL_FRAGMENT_SHADER)
+		{
+			if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
+			{
+				appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
+				return false;
+			}
+		}
+		else UNREACHABLE(shader);
+
+		return true;
+	}
+
+	bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = 0;
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 1;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 2;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][3] = 0;
+
+			v += 3;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+
+			v += 4;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = 0;
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 1;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 2;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = v[2];
+			vector[i][3] = 0;
+
+			v += 3;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)v, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)v, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
+
+			value += 4;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2];	matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5];	matrix[i][1][3] = 0;
+			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];	matrix[i][2][2] = value[8];	matrix[i][2][3] = 0;
+
+			value += 9;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)value, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)value, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (float)v[i];
+			vector[i][1] = 0;
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			if(targetUniform->type == GL_SAMPLER_2D ||
+			   targetUniform->type == GL_SAMPLER_CUBE)
+			{
+				for(int i = 0; i < count; i++)
+				{
+					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
+
+					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+					{
+						ASSERT(samplersPS[samplerIndex].active);
+						samplersPS[samplerIndex].logicalTextureUnit = v[i];
+					}
+				}
+			}
+			else
+			{
+				device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+			}
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			if(targetUniform->type == GL_SAMPLER_2D ||
+			   targetUniform->type == GL_SAMPLER_CUBE)
+			{
+				for(int i = 0; i < count; i++)
+				{
+					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
+
+					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					{
+						ASSERT(samplersVS[samplerIndex].active);
+						samplersVS[samplerIndex].logicalTextureUnit = v[i];
+					}
+				}
+			}
+			else
+			{
+				device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+			}
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (float)v[0];
+			vector[i][1] = (float)v[1];
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 2;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (float)v[0];
+			vector[i][1] = (float)v[1];
+			vector[i][2] = (float)v[2];
+			vector[i][3] = 0;
+
+			v += 3;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (float)v[0];
+			vector[i][1] = (float)v[1];
+			vector[i][2] = (float)v[2];
+			vector[i][3] = (float)v[3];
+
+			v += 4;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	void Program::appendToInfoLog(const char *format, ...)
+	{
+		if(!format)
+		{
+			return;
+		}
+
+		char info[1024];
+
+		va_list vararg;
+		va_start(vararg, format);
+		vsnprintf(info, sizeof(info), format, vararg);
+		va_end(vararg);
+
+		size_t infoLength = strlen(info);
+
+		if(!infoLog)
+		{
+			infoLog = new char[infoLength + 2];
+			strcpy(infoLog, info);
+			strcpy(infoLog + infoLength, "\n");
+		}
+		else
+		{
+			size_t logLength = strlen(infoLog);
+			char *newLog = new char[logLength + infoLength + 2];
+			strcpy(newLog, infoLog);
+			strcpy(newLog + logLength, info);
+			strcpy(newLog + logLength + infoLength, "\n");
+
+			delete[] infoLog;
+			infoLog = newLog;
+		}
+	}
+
+	void Program::resetInfoLog()
+	{
+		if(infoLog)
+		{
+			delete[] infoLog;
+			infoLog = 0;
+		}
+	}
+
+	// Returns the program object to an unlinked state, before re-linking, or at destruction
+	void Program::unlink()
+	{
+		delete vertexBinary;
+		vertexBinary = 0;
+		delete pixelBinary;
+		pixelBinary = 0;
+
+		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+		{
+			linkedAttribute[index].name.clear();
+			attributeStream[index] = -1;
+		}
+
+		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
+		{
+			samplersPS[index].active = false;
+		}
+
+		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
+		{
+			samplersVS[index].active = false;
+		}
+
+		while(!uniforms.empty())
+		{
+			delete uniforms.back();
+			uniforms.pop_back();
+		}
+
+		uniformIndex.clear();
+
+		delete[] infoLog;
+		infoLog = 0;
+
+		linked = false;
+	}
+
+	bool Program::isLinked()
+	{
+		return linked;
+	}
+
+	bool Program::isValidated() const
+	{
+		return validated;
+	}
+
+	void Program::release()
+	{
+		referenceCount--;
+
+		if(referenceCount == 0 && orphaned)
+		{
+			resourceManager->deleteProgram(handle);
+		}
+	}
+
+	void Program::addRef()
+	{
+		referenceCount++;
+	}
+
+	unsigned int Program::getRefCount() const
+	{
+		return referenceCount;
+	}
+
+	unsigned int Program::getSerial() const
+	{
+		return serial;
+	}
+
+	unsigned int Program::issueSerial()
+	{
+		return currentSerial++;
+	}
+
+	int Program::getInfoLogLength() const
+	{
+		if(!infoLog)
+		{
+			return 0;
+		}
+		else
+		{
+		   return strlen(infoLog) + 1;
+		}
+	}
+
+	void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
+	{
+		int index = 0;
+
+		if(bufSize > 0)
+		{
+			if(infoLog)
+			{
+				index = std::min(bufSize - 1, (int)strlen(infoLog));
+				memcpy(buffer, infoLog, index);
+			}
+
+			buffer[index] = '\0';
+		}
+
+		if(length)
+		{
+			*length = index;
+		}
+	}
+
+	void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
+	{
+		int total = 0;
+
+		if(vertexShader)
+		{
+			if(total < maxCount)
+			{
+				shaders[total] = vertexShader->getName();
+			}
+
+			total++;
+		}
+
+		if(fragmentShader)
+		{
+			if(total < maxCount)
+			{
+				shaders[total] = fragmentShader->getName();
+			}
+
+			total++;
+		}
+
+		if(count)
+		{
+			*count = total;
+		}
+	}
+
+	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
+	{
+		// Skip over inactive attributes
+		unsigned int activeAttribute = 0;
+		unsigned int attribute;
+		for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+		{
+			if(linkedAttribute[attribute].name.empty())
+			{
+				continue;
+			}
+
+			if(activeAttribute == index)
+			{
+				break;
+			}
+
+			activeAttribute++;
+		}
+
+		if(bufsize > 0)
+		{
+			const char *string = linkedAttribute[attribute].name.c_str();
+
+			strncpy(name, string, bufsize);
+			name[bufsize - 1] = '\0';
+
+			if(length)
+			{
+				*length = strlen(name);
+			}
+		}
+
+		*size = 1;   // Always a single 'type' instance
+
+		*type = linkedAttribute[attribute].type;
+	}
+
+	size_t Program::getActiveAttributeCount() const
+	{
+		size_t count = 0;
+
+		for(size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ++attributeIndex)
+		{
+			if(!linkedAttribute[attributeIndex].name.empty())
+			{
+				count++;
+			}
+		}
+
+		return count;
+	}
+
+	GLint Program::getActiveAttributeMaxLength() const
+	{
+		int maxLength = 0;
+
+		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+		{
+			if(!linkedAttribute[attributeIndex].name.empty())
+			{
+				maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
+			}
+		}
+
+		return maxLength;
+	}
+
+	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
+	{
+		if(bufsize > 0)
+		{
+			std::string string = uniforms[index]->name;
+
+			if(uniforms[index]->isArray())
+			{
+				string += "[0]";
+			}
+
+			strncpy(name, string.c_str(), bufsize);
+			name[bufsize - 1] = '\0';
+
+			if(length)
+			{
+				*length = strlen(name);
+			}
+		}
+
+		*size = uniforms[index]->size();
+
+		*type = uniforms[index]->type;
+	}
+
+	size_t Program::getActiveUniformCount() const
+	{
+		return uniforms.size();
+	}
+
+	GLint Program::getActiveUniformMaxLength() const
+	{
+		int maxLength = 0;
+
+		unsigned int numUniforms = uniforms.size();
+		for(unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
+		{
+			if(!uniforms[uniformIndex]->name.empty())
+			{
+				int length = (int)(uniforms[uniformIndex]->name.length() + 1);
+				if(uniforms[uniformIndex]->isArray())
+				{
+					length += 3;  // Counting in "[0]".
+				}
+				maxLength = std::max(length, maxLength);
+			}
+		}
+
+		return maxLength;
+	}
+
+	void Program::flagForDeletion()
+	{
+		orphaned = true;
+	}
+
+	bool Program::isFlaggedForDeletion() const
+	{
+		return orphaned;
+	}
+
+	void Program::validate()
+	{
+		resetInfoLog();
+
+		if(!isLinked())
+		{
+			appendToInfoLog("Program has not been successfully linked.");
+			validated = false;
+		}
+		else
+		{
+			applyUniforms();
+			if(!validateSamplers(true))
+			{
+				validated = false;
+			}
+			else
+			{
+				validated = true;
+			}
+		}
+	}
+
+	bool Program::validateSamplers(bool logErrors)
+	{
+		// if any two active samplers in a program are of different types, but refer to the same
+		// texture image unit, and this is the current program, then ValidateProgram will fail, and
+		// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
+
+		TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+
+		for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
+		{
+			textureUnitType[i] = TEXTURE_UNKNOWN;
+		}
+
+		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+		{
+			if(samplersPS[i].active)
+			{
+				unsigned int unit = samplersPS[i].logicalTextureUnit;
+
+				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+				{
+					if(logErrors)
+					{
+						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+					}
+
+					return false;
+				}
+
+				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
+				{
+					if(samplersPS[i].textureType != textureUnitType[unit])
+					{
+						if(logErrors)
+						{
+							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+						}
+
+						return false;
+					}
+				}
+				else
+				{
+					textureUnitType[unit] = samplersPS[i].textureType;
+				}
+			}
+		}
+
+		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+		{
+			if(samplersVS[i].active)
+			{
+				unsigned int unit = samplersVS[i].logicalTextureUnit;
+
+				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+				{
+					if(logErrors)
+					{
+						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+					}
+
+					return false;
+				}
+
+				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
+				{
+					if(samplersVS[i].textureType != textureUnitType[unit])
+					{
+						if(logErrors)
+						{
+							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+						}
+
+						return false;
+					}
+				}
+				else
+				{
+					textureUnitType[unit] = samplersVS[i].textureType;
+				}
+			}
+		}
+
+		return true;
+	}
+}
diff --git a/src/OpenGL/libGL/Program.h b/src/OpenGL/libGL/Program.h
index 37eddcb..0e7c0f6 100644
--- a/src/OpenGL/libGL/Program.h
+++ b/src/OpenGL/libGL/Program.h
@@ -1,207 +1,210 @@
-// 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.

-//

-

-// Program.h: Defines the Program class. Implements GL program objects

-// and related functionality.

-

-#ifndef LIBGL_PROGRAM_H_

-#define LIBGL_PROGRAM_H_

-

-#include "Shader.h"

-#include "Context.h"

-#include "Shader/PixelShader.hpp"

-#include "Shader/VertexShader.hpp"

-

-#include <string>

-#include <vector>

-#include <set>

-

-namespace gl

-{

-	class Device;

-	class ResourceManager;

-	class FragmentShader;

-	class VertexShader;

-

-	// Helper struct representing a single shader uniform

-	struct Uniform

-	{

-		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize);

-

-		~Uniform();

-

-		bool isArray() const;

-		int size() const;

-		int registerCount() const;

-

-		const GLenum type;

-		const GLenum precision;

-		const std::string name;

-		const unsigned int arraySize;

-

-		unsigned char *data;

-		bool dirty;

-

-		short psRegisterIndex;

-		short vsRegisterIndex;

-	};

-

-	// Struct used for correlating uniforms/elements of uniform arrays to handles

-	struct UniformLocation

-	{

-		UniformLocation(const std::string &name, unsigned int element, unsigned int index);

-

-		std::string name;

-		unsigned int element;

-		unsigned int index;

-	};

-

-	class Program

-	{

-	public:

-		Program(ResourceManager *manager, GLuint handle);

-

-		~Program();

-

-		bool attachShader(Shader *shader);

-		bool detachShader(Shader *shader);

-		int getAttachedShadersCount() const;

-

-		sw::PixelShader *getPixelShader();

-		sw::VertexShader *getVertexShader();

-

-		void bindAttributeLocation(GLuint index, const char *name);

-		GLuint getAttributeLocation(const char *name);

-		int getAttributeStream(int attributeIndex);

-

-		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);

-		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);

-

-		GLint getUniformLocation(std::string name);

-		bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);

-		bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);

-		bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);

-		bool setUniform1iv(GLint location, GLsizei count, const GLint *v);

-		bool setUniform2iv(GLint location, GLsizei count, const GLint *v);

-		bool setUniform3iv(GLint location, GLsizei count, const GLint *v);

-		bool setUniform4iv(GLint location, GLsizei count, const GLint *v);

-

-		bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);

-		bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);

-

-		void dirtyAllUniforms();

-		void applyUniforms();

-

-		void link();

-		bool isLinked();

-		int getInfoLogLength() const;

-		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);

-		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);

-

-		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;

-		size_t getActiveAttributeCount() const;

-		GLint getActiveAttributeMaxLength() const;

-

-		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;

-		size_t getActiveUniformCount() const;

-		GLint getActiveUniformMaxLength() const;

-

-		void addRef();

-		void release();

-		unsigned int getRefCount() const;

-		void flagForDeletion();

-		bool isFlaggedForDeletion() const;

-

-		void validate();

-		bool validateSamplers(bool logErrors);

-		bool isValidated() const;

-

-		unsigned int getSerial() const;

-

-	private:

-		void unlink();

-

-		int packVaryings(const glsl::Varying *packing[][4]);

-		bool linkVaryings();

-

-		bool linkAttributes();

-		int getAttributeBinding(const std::string &name);

-

-		bool linkUniforms(Shader *shader);

-		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex);

-		bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniform1iv(GLint location, GLsizei count, const GLint *v);

-		bool applyUniform2iv(GLint location, GLsizei count, const GLint *v);

-		bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);

-		bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);    

-

-		void appendToInfoLog(const char *info, ...);

-		void resetInfoLog();

-

-		static unsigned int issueSerial();

-

-	private:

-		gl::Device *device;

-		FragmentShader *fragmentShader;

-		VertexShader *vertexShader;

-

-		sw::PixelShader *pixelBinary;

-		sw::VertexShader *vertexBinary;

-    

-		std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];

-		glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];

-		int attributeStream[MAX_VERTEX_ATTRIBS];

-

-		struct Sampler

-		{

-			bool active;

-			GLint logicalTextureUnit;

-			TextureType textureType;

-		};

-

-		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];

-		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];

-

-		typedef std::vector<Uniform*> UniformArray;

-		UniformArray uniforms;

-		typedef std::vector<UniformLocation> UniformIndex;

-		UniformIndex uniformIndex;

-

-		bool linked;

-		bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use

-		char *infoLog;

-		bool validated;

-

-		unsigned int referenceCount;

-		const unsigned int serial;

-

-		static unsigned int currentSerial;

-

-		ResourceManager *resourceManager;

-		const GLuint handle;

-	};

-}

-

-#endif   // LIBGL_PROGRAM_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Program.h: Defines the Program class. Implements GL program objects
+// and related functionality.
+
+#ifndef LIBGL_PROGRAM_H_
+#define LIBGL_PROGRAM_H_
+
+#include "Shader.h"
+#include "Context.h"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+
+#include <string>
+#include <vector>
+#include <set>
+
+namespace gl
+{
+	class Device;
+	class ResourceManager;
+	class FragmentShader;
+	class VertexShader;
+
+	// Helper struct representing a single shader uniform
+	struct Uniform
+	{
+		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize);
+
+		~Uniform();
+
+		bool isArray() const;
+		int size() const;
+		int registerCount() const;
+
+		const GLenum type;
+		const GLenum precision;
+		const std::string name;
+		const unsigned int arraySize;
+
+		unsigned char *data;
+		bool dirty;
+
+		short psRegisterIndex;
+		short vsRegisterIndex;
+	};
+
+	// Struct used for correlating uniforms/elements of uniform arrays to handles
+	struct UniformLocation
+	{
+		UniformLocation(const std::string &name, unsigned int element, unsigned int index);
+
+		std::string name;
+		unsigned int element;
+		unsigned int index;
+	};
+
+	class Program
+	{
+	public:
+		Program(ResourceManager *manager, GLuint handle);
+
+		~Program();
+
+		bool attachShader(Shader *shader);
+		bool detachShader(Shader *shader);
+		int getAttachedShadersCount() const;
+
+		sw::PixelShader *getPixelShader();
+		sw::VertexShader *getVertexShader();
+
+		void bindAttributeLocation(GLuint index, const char *name);
+		GLuint getAttributeLocation(const char *name);
+		int getAttributeStream(int attributeIndex);
+
+		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);
+		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);
+
+		GLint getUniformLocation(std::string name);
+		bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);
+		bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
+		bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
+		bool setUniform1iv(GLint location, GLsizei count, const GLint *v);
+		bool setUniform2iv(GLint location, GLsizei count, const GLint *v);
+		bool setUniform3iv(GLint location, GLsizei count, const GLint *v);
+		bool setUniform4iv(GLint location, GLsizei count, const GLint *v);
+
+		bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
+		bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
+
+		void dirtyAllUniforms();
+		void applyUniforms();
+
+		void link();
+		bool isLinked();
+		int getInfoLogLength() const;
+		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
+		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
+
+		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
+		size_t getActiveAttributeCount() const;
+		GLint getActiveAttributeMaxLength() const;
+
+		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
+		size_t getActiveUniformCount() const;
+		GLint getActiveUniformMaxLength() const;
+
+		void addRef();
+		void release();
+		unsigned int getRefCount() const;
+		void flagForDeletion();
+		bool isFlaggedForDeletion() const;
+
+		void validate();
+		bool validateSamplers(bool logErrors);
+		bool isValidated() const;
+
+		unsigned int getSerial() const;
+
+	private:
+		void unlink();
+
+		int packVaryings(const glsl::Varying *packing[][4]);
+		bool linkVaryings();
+
+		bool linkAttributes();
+		int getAttributeBinding(const std::string &name);
+
+		bool linkUniforms(Shader *shader);
+		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex);
+		bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniform1iv(GLint location, GLsizei count, const GLint *v);
+		bool applyUniform2iv(GLint location, GLsizei count, const GLint *v);
+		bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
+		bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);    
+
+		void appendToInfoLog(const char *info, ...);
+		void resetInfoLog();
+
+		static unsigned int issueSerial();
+
+	private:
+		gl::Device *device;
+		FragmentShader *fragmentShader;
+		VertexShader *vertexShader;
+
+		sw::PixelShader *pixelBinary;
+		sw::VertexShader *vertexBinary;
+
+		std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];
+		glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];
+		int attributeStream[MAX_VERTEX_ATTRIBS];
+
+		struct Sampler
+		{
+			bool active;
+			GLint logicalTextureUnit;
+			TextureType textureType;
+		};
+
+		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];
+		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+
+		typedef std::vector<Uniform*> UniformArray;
+		UniformArray uniforms;
+		typedef std::vector<UniformLocation> UniformIndex;
+		UniformIndex uniformIndex;
+
+		bool linked;
+		bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use
+		char *infoLog;
+		bool validated;
+
+		unsigned int referenceCount;
+		const unsigned int serial;
+
+		static unsigned int currentSerial;
+
+		ResourceManager *resourceManager;
+		const GLuint handle;
+	};
+}
+
+#endif   // LIBGL_PROGRAM_H_
diff --git a/src/OpenGL/libGL/Query.cpp b/src/OpenGL/libGL/Query.cpp
index a6ce26f..92b9d61 100644
--- a/src/OpenGL/libGL/Query.cpp
+++ b/src/OpenGL/libGL/Query.cpp
@@ -1,138 +1,138 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Query.cpp: Implements the gl::Query class

-

-#include "Query.h"

-

-#include "main.h"

-#include "Common/Thread.hpp"

-

-namespace gl

-{

-

-Query::Query(GLuint name, GLenum type) : NamedObject(name)

-{ 

-    mQuery = NULL;

-    mStatus = GL_FALSE;

-    mResult = GL_FALSE;

-    mType = type;

-}

-

-Query::~Query()

-{

-    if(mQuery != NULL)

-    {

-        delete mQuery;

-    }

-}

-

-void Query::begin()

-{

-    if(mQuery == NULL)

-    {

-		sw::Query::Type type;

-		switch(mType)

-		{

-		case GL_ANY_SAMPLES_PASSED:

-		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-			type = sw::Query::FRAGMENTS_PASSED;

-			break;

-		default:

-			ASSERT(false);

-		}

-

-		mQuery = new sw::Query(type);

-

-		if(!mQuery)

-        {

-            return error(GL_OUT_OF_MEMORY);

-        }

-    }

-

-	Device *device = getDevice();

-

-	mQuery->begin();

-	device->addQuery(mQuery);

-	device->setOcclusionEnabled(true);

-}

-

-void Query::end()

-{

-    if(mQuery == NULL)

-    {

-        return error(GL_INVALID_OPERATION);

-	}

-

-	Device *device = getDevice();

-

-    mQuery->end();

-	device->removeQuery(mQuery);

-	device->setOcclusionEnabled(false);

-    

-    mStatus = GL_FALSE;

-    mResult = GL_FALSE;

-}

-

-GLuint Query::getResult()

-{

-    if(mQuery != NULL)

-    {

-        while(!testQuery())

-        {

-            sw::Thread::yield();

-        }

-    }

-

-    return (GLuint)mResult;

-}

-

-GLboolean Query::isResultAvailable()

-{

-    if(mQuery != NULL)

-    {

-        testQuery();

-    }

-    

-    return mStatus;

-}

-

-GLenum Query::getType() const

-{

-    return mType;

-}

-

-GLboolean Query::testQuery()

-{

-    if(mQuery != NULL && mStatus != GL_TRUE)

-    {

-        if(!mQuery->building && mQuery->reference == 0)

-        {

-			unsigned int numPixels = mQuery->data;

-            mStatus = GL_TRUE;

-

-            switch(mType)

-            {

-            case GL_ANY_SAMPLES_PASSED:

-            case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-                mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;

-                break;

-            default:

-                ASSERT(false);

-            }

-        }

-        

-        return mStatus;

-    }

-

-    return GL_TRUE;   // Prevent blocking when query is null

-}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Query.cpp: Implements the gl::Query class
+
+#include "Query.h"
+
+#include "main.h"
+#include "Common/Thread.hpp"
+
+namespace gl
+{
+
+Query::Query(GLuint name, GLenum type) : NamedObject(name)
+{
+	mQuery = nullptr;
+	mStatus = GL_FALSE;
+	mResult = GL_FALSE;
+	mType = type;
+}
+
+Query::~Query()
+{
+	delete mQuery;
+}
+
+void Query::begin()
+{
+	if(!mQuery)
+	{
+		sw::Query::Type type;
+		switch(mType)
+		{
+		case GL_ANY_SAMPLES_PASSED:
+		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+			type = sw::Query::FRAGMENTS_PASSED;
+			break;
+		default:
+			ASSERT(false);
+		}
+
+		mQuery = new sw::Query(type);
+
+		if(!mQuery)
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+	}
+
+	Device *device = getDevice();
+
+	mQuery->begin();
+	device->addQuery(mQuery);
+	device->setOcclusionEnabled(true);
+}
+
+void Query::end()
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	Device *device = getDevice();
+
+	mQuery->end();
+	device->removeQuery(mQuery);
+	device->setOcclusionEnabled(false);
+
+	mStatus = GL_FALSE;
+	mResult = GL_FALSE;
+}
+
+GLuint Query::getResult()
+{
+	if(mQuery)
+	{
+		while(!testQuery())
+		{
+			sw::Thread::yield();
+		}
+	}
+
+	return (GLuint)mResult;
+}
+
+GLboolean Query::isResultAvailable()
+{
+	if(mQuery)
+	{
+		testQuery();
+	}
+
+	return mStatus;
+}
+
+GLenum Query::getType() const
+{
+	return mType;
+}
+
+GLboolean Query::testQuery()
+{
+	if(mQuery && mStatus != GL_TRUE)
+	{
+		if(!mQuery->building && mQuery->reference == 0)
+		{
+			unsigned int numPixels = mQuery->data;
+			mStatus = GL_TRUE;
+
+			switch(mType)
+			{
+			case GL_ANY_SAMPLES_PASSED:
+			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+				mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
+				break;
+			default:
+				ASSERT(false);
+			}
+		}
+
+		return mStatus;
+	}
+
+	return GL_TRUE;   // Prevent blocking when query is null
+}
+}
diff --git a/src/OpenGL/libGL/Query.h b/src/OpenGL/libGL/Query.h
index d4e4163..e16da8e 100644
--- a/src/OpenGL/libGL/Query.h
+++ b/src/OpenGL/libGL/Query.h
@@ -1,52 +1,55 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Query.h: Defines the gl::Query class

-

-#ifndef LIBGL_QUERY_H_

-#define LIBGL_QUERY_H_

-

-#include "common/Object.hpp"

-#include "Renderer/Renderer.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-

-class Query : public NamedObject

-{

-  public:

-    Query(GLuint name, GLenum type);

-    virtual ~Query();

-

-    void begin();

-    void end();

-    GLuint getResult();

-    GLboolean isResultAvailable();

-

-    GLenum getType() const;

-

-  private:

-    GLboolean testQuery();

-

-    sw::Query* mQuery;

-    GLenum mType;

-    GLboolean mStatus;

-    GLint mResult;

-};

-

-}

-

-#endif   // LIBGL_QUERY_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Query.h: Defines the gl::Query class
+
+#ifndef LIBGL_QUERY_H_
+#define LIBGL_QUERY_H_
+
+#include "common/Object.hpp"
+#include "Renderer/Renderer.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+
+class Query : public NamedObject
+{
+public:
+	Query(GLuint name, GLenum type);
+	virtual ~Query();
+
+	void begin();
+	void end();
+	GLuint getResult();
+	GLboolean isResultAvailable();
+
+	GLenum getType() const;
+
+private:
+	GLboolean testQuery();
+
+	sw::Query* mQuery;
+	GLenum mType;
+	GLboolean mStatus;
+	GLint mResult;
+};
+
+}
+
+#endif   // LIBGL_QUERY_H_
diff --git a/src/OpenGL/libGL/Renderbuffer.cpp b/src/OpenGL/libGL/Renderbuffer.cpp
index ea65da0..a2b8e97 100644
--- a/src/OpenGL/libGL/Renderbuffer.cpp
+++ b/src/OpenGL/libGL/Renderbuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
@@ -27,7 +30,7 @@
 
 // The default case for classes inherited from RenderbufferInterface is not to
 // need to do anything upon the reference count to the parent Renderbuffer incrementing
-// or decrementing. 
+// or decrementing.
 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
 {
 }
@@ -75,19 +78,19 @@
 
 RenderbufferTexture2D::~RenderbufferTexture2D()
 {
-	mTexture2D = NULL;
+	mTexture2D = nullptr;
 }
 
 // Textures need to maintain their own reference count for references via
 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
 {
-    mTexture2D->addProxyRef(proxy);
+	mTexture2D->addProxyRef(proxy);
 }
 
 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
 {
-    mTexture2D->releaseProxy(proxy);
+	mTexture2D->releaseProxy(proxy);
 }
 
 // Increments refcount on surface.
@@ -131,19 +134,19 @@
 
 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
 {
-	mTextureCubeMap = NULL;
+	mTextureCubeMap = nullptr;
 }
 
 // Textures need to maintain their own reference count for references via
 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
 {
-    mTextureCubeMap->addProxyRef(proxy);
+	mTextureCubeMap->addProxyRef(proxy);
 }
 
 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
 {
-    mTextureCubeMap->releaseProxy(proxy);
+	mTextureCubeMap->releaseProxy(proxy);
 }
 
 // Increments refcount on surface.
@@ -182,7 +185,7 @@
 
 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
 {
-	ASSERT(instance != NULL);
+	ASSERT(instance);
 	mInstance = instance;
 }
 
@@ -195,16 +198,16 @@
 // its own reference count, so we pass it on here.
 void Renderbuffer::addRef()
 {
-    mInstance->addProxyRef(this);
+	mInstance->addProxyRef(this);
 
-    Object::addRef();
+	Object::addRef();
 }
 
 void Renderbuffer::release()
 {
-    mInstance->releaseProxy(this);
+	mInstance->releaseProxy(this);
 
-    Object::release();
+	Object::release();
 }
 
 // Increments refcount on surface.
@@ -271,7 +274,7 @@
 
 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
 {
-	ASSERT(newStorage != NULL);
+	ASSERT(newStorage);
 
 	delete mInstance;
 	mInstance = newStorage;
@@ -294,7 +297,7 @@
 // caller must Release() the returned surface
 Image *RenderbufferStorage::getRenderTarget()
 {
-	return NULL;
+	return nullptr;
 }
 
 GLsizei RenderbufferStorage::getWidth() const
@@ -327,7 +330,7 @@
 	if(renderTarget)
 	{
 		renderTarget->addRef();
-		
+
 		mWidth = renderTarget->getWidth();
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
@@ -444,7 +447,7 @@
 	if(depthStencil)
 	{
 		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
-		                                 // will expect one of the valid renderbuffer formats for use in 
+		                                 // will expect one of the valid renderbuffer formats for use in
 		                                 // glRenderbufferStorage
 	}
 }
@@ -454,7 +457,7 @@
 	if(mDepthStencil)
 	{
 		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
-		                                 // will expect one of the valid renderbuffer formats for use in 
+		                                 // will expect one of the valid renderbuffer formats for use in
 		                                 // glRenderbufferStorage
 	}
 }
@@ -468,7 +471,7 @@
 	if(depthStencil)
 	{
 		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
-		                              // will expect one of the valid renderbuffer formats for use in 
+		                              // will expect one of the valid renderbuffer formats for use in
 		                              // glRenderbufferStorage
 	}
 }
@@ -478,7 +481,7 @@
 	if(mDepthStencil)
 	{
 		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
-		                              // will expect one of the valid renderbuffer formats for use in 
+		                              // will expect one of the valid renderbuffer formats for use in
 		                              // glRenderbufferStorage
 	}
 }
diff --git a/src/OpenGL/libGL/Renderbuffer.h b/src/OpenGL/libGL/Renderbuffer.h
index 2085420..55c639a 100644
--- a/src/OpenGL/libGL/Renderbuffer.h
+++ b/src/OpenGL/libGL/Renderbuffer.h
@@ -1,217 +1,220 @@
-// 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.

-//

-

-// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the

-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,

-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer

-// objects and related functionality.

-

-#ifndef LIBGL_RENDERBUFFER_H_

-#define LIBGL_RENDERBUFFER_H_

-

-#include "common/Object.hpp"

-#include "Image.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-class Texture2D;

-class TextureCubeMap;

-class Renderbuffer;

-class Colorbuffer;

-class DepthStencilbuffer;

-

-class RenderbufferInterface

-{

-public:

-	RenderbufferInterface();

-

-	virtual ~RenderbufferInterface() {};

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual Image *getRenderTarget() = 0;

-

-	virtual GLsizei getWidth() const = 0;

-	virtual GLsizei getHeight() const = 0;

-	virtual GLenum getFormat() const = 0;

-	virtual sw::Format getInternalFormat() const = 0;

-	virtual GLsizei getSamples() const = 0;

-

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-};

-

-class RenderbufferTexture2D : public RenderbufferInterface

-{

-public:

-	RenderbufferTexture2D(Texture2D *texture);

-

-	virtual ~RenderbufferTexture2D();

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	Image *getRenderTarget();

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-private:

-	BindingPointer<Texture2D> mTexture2D;

-};

-

-class RenderbufferTextureCubeMap : public RenderbufferInterface

-{

-public:

-	RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target);

-

-	virtual ~RenderbufferTextureCubeMap();

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	Image *getRenderTarget();

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-private:

-	BindingPointer<TextureCubeMap> mTextureCubeMap;

-	GLenum mTarget;

-};

-

-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage

-// is called. The specific concrete type depends on whether the internal format is

-// colour depth, stencil or packed depth/stencil.

-class RenderbufferStorage : public RenderbufferInterface

-{

-public:

-	RenderbufferStorage();

-

-	virtual ~RenderbufferStorage() = 0;

-

-	virtual Image *getRenderTarget();

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-protected:

-	GLsizei mWidth;

-	GLsizei mHeight;

-	GLenum format;

-	sw::Format internalFormat;

-	GLsizei mSamples;

-};

-

-// Renderbuffer implements the GL renderbuffer object.

-// It's only a proxy for a RenderbufferInterface instance; the internal object

-// can change whenever glRenderbufferStorage is called.

-class Renderbuffer : public NamedObject

-{

-public:

-	Renderbuffer(GLuint name, RenderbufferInterface *storage);

-

-	virtual ~Renderbuffer();

-

-	// These functions from Object are overloaded here because

-    // Textures need to maintain their own count of references to them via

-    // Renderbuffers/RenderbufferTextures. These functions invoke those

-    // reference counting functions on the RenderbufferInterface.

-    virtual void addRef();

-    virtual void release();

-

-	Image *getRenderTarget();

-

-	GLsizei getWidth() const;

-	GLsizei getHeight() const;

-	GLenum getFormat() const;

-	sw::Format getInternalFormat() const;

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-	GLsizei getSamples() const;

-

-	void setStorage(RenderbufferStorage *newStorage);

-

-private:

-	RenderbufferInterface *mInstance;

-};

-

-class Colorbuffer : public RenderbufferStorage

-{

-public:

-	explicit Colorbuffer(Image *renderTarget);

-	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);

-

-	virtual ~Colorbuffer();

-

-	virtual Image *getRenderTarget();

-

-private:

-	Image *mRenderTarget;

-};

-

-class DepthStencilbuffer : public RenderbufferStorage

-{

-public:

-	explicit DepthStencilbuffer(Image *depthStencil);

-	DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	~DepthStencilbuffer();

-

-	virtual Image *getRenderTarget();

-

-protected:

-	Image *mDepthStencil;

-};

-

-class Depthbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Depthbuffer(Image *depthStencil);

-	Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	virtual ~Depthbuffer();

-};

-

-class Stencilbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Stencilbuffer(Image *depthStencil);

-	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	virtual ~Stencilbuffer();

-};

-}

-

-#endif   // LIBGL_RENDERBUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the
+// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
+// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
+// objects and related functionality.
+
+#ifndef LIBGL_RENDERBUFFER_H_
+#define LIBGL_RENDERBUFFER_H_
+
+#include "common/Object.hpp"
+#include "Image.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+class Texture2D;
+class TextureCubeMap;
+class Renderbuffer;
+class Colorbuffer;
+class DepthStencilbuffer;
+
+class RenderbufferInterface
+{
+public:
+	RenderbufferInterface();
+
+	virtual ~RenderbufferInterface() {};
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+	virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual Image *getRenderTarget() = 0;
+
+	virtual GLsizei getWidth() const = 0;
+	virtual GLsizei getHeight() const = 0;
+	virtual GLenum getFormat() const = 0;
+	virtual sw::Format getInternalFormat() const = 0;
+	virtual GLsizei getSamples() const = 0;
+
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+};
+
+class RenderbufferTexture2D : public RenderbufferInterface
+{
+public:
+	RenderbufferTexture2D(Texture2D *texture);
+
+	virtual ~RenderbufferTexture2D();
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+	virtual void releaseProxy(const Renderbuffer *proxy);
+
+	Image *getRenderTarget();
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+private:
+	BindingPointer<Texture2D> mTexture2D;
+};
+
+class RenderbufferTextureCubeMap : public RenderbufferInterface
+{
+public:
+	RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target);
+
+	virtual ~RenderbufferTextureCubeMap();
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+	virtual void releaseProxy(const Renderbuffer *proxy);
+
+	Image *getRenderTarget();
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+private:
+	BindingPointer<TextureCubeMap> mTextureCubeMap;
+	GLenum mTarget;
+};
+
+// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
+// is called. The specific concrete type depends on whether the internal format is
+// colour depth, stencil or packed depth/stencil.
+class RenderbufferStorage : public RenderbufferInterface
+{
+public:
+	RenderbufferStorage();
+
+	virtual ~RenderbufferStorage() = 0;
+
+	virtual Image *getRenderTarget();
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+protected:
+	GLsizei mWidth;
+	GLsizei mHeight;
+	GLenum format;
+	sw::Format internalFormat;
+	GLsizei mSamples;
+};
+
+// Renderbuffer implements the GL renderbuffer object.
+// It's only a proxy for a RenderbufferInterface instance; the internal object
+// can change whenever glRenderbufferStorage is called.
+class Renderbuffer : public NamedObject
+{
+public:
+	Renderbuffer(GLuint name, RenderbufferInterface *storage);
+
+	virtual ~Renderbuffer();
+
+	// These functions from Object are overloaded here because
+	// Textures need to maintain their own count of references to them via
+	// Renderbuffers/RenderbufferTextures. These functions invoke those
+	// reference counting functions on the RenderbufferInterface.
+	virtual void addRef();
+	virtual void release();
+
+	Image *getRenderTarget();
+
+	GLsizei getWidth() const;
+	GLsizei getHeight() const;
+	GLenum getFormat() const;
+	sw::Format getInternalFormat() const;
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+	GLsizei getSamples() const;
+
+	void setStorage(RenderbufferStorage *newStorage);
+
+private:
+	RenderbufferInterface *mInstance;
+};
+
+class Colorbuffer : public RenderbufferStorage
+{
+public:
+	explicit Colorbuffer(Image *renderTarget);
+	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+
+	virtual ~Colorbuffer();
+
+	virtual Image *getRenderTarget();
+
+private:
+	Image *mRenderTarget;
+};
+
+class DepthStencilbuffer : public RenderbufferStorage
+{
+public:
+	explicit DepthStencilbuffer(Image *depthStencil);
+	DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	~DepthStencilbuffer();
+
+	virtual Image *getRenderTarget();
+
+protected:
+	Image *mDepthStencil;
+};
+
+class Depthbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Depthbuffer(Image *depthStencil);
+	Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	virtual ~Depthbuffer();
+};
+
+class Stencilbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Stencilbuffer(Image *depthStencil);
+	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	virtual ~Stencilbuffer();
+};
+}
+
+#endif   // LIBGL_RENDERBUFFER_H_
diff --git a/src/OpenGL/libGL/ResourceManager.cpp b/src/OpenGL/libGL/ResourceManager.cpp
index 49352ae..48b912b 100644
--- a/src/OpenGL/libGL/ResourceManager.cpp
+++ b/src/OpenGL/libGL/ResourceManager.cpp
@@ -1,15 +1,18 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
-// ResourceManager.cpp: Implements the ResourceManager class, which tracks and 
+// ResourceManager.cpp: Implements the ResourceManager class, which tracks and
 // retrieves objects which may be shared by multiple Contexts.
 
 #include "ResourceManager.h"
@@ -24,332 +27,332 @@
 {
 ResourceManager::ResourceManager()
 {
-    mRefCount = 1;
+	mRefCount = 1;
 }
 
 ResourceManager::~ResourceManager()
 {
-    while(!mBufferMap.empty())
-    {
-        deleteBuffer(mBufferMap.begin()->first);
-    }
+	while(!mBufferMap.empty())
+	{
+		deleteBuffer(mBufferMap.begin()->first);
+	}
 
-    while(!mProgramMap.empty())
-    {
-        deleteProgram(mProgramMap.begin()->first);
-    }
+	while(!mProgramMap.empty())
+	{
+		deleteProgram(mProgramMap.begin()->first);
+	}
 
-    while(!mShaderMap.empty())
-    {
-        deleteShader(mShaderMap.begin()->first);
-    }
+	while(!mShaderMap.empty())
+	{
+		deleteShader(mShaderMap.begin()->first);
+	}
 
-    while(!mRenderbufferMap.empty())
-    {
-        deleteRenderbuffer(mRenderbufferMap.begin()->first);
-    }
+	while(!mRenderbufferMap.empty())
+	{
+		deleteRenderbuffer(mRenderbufferMap.begin()->first);
+	}
 
-    while(!mTextureMap.empty())
-    {
-        deleteTexture(mTextureMap.begin()->first);
-    }
+	while(!mTextureMap.empty())
+	{
+		deleteTexture(mTextureMap.begin()->first);
+	}
 }
 
 void ResourceManager::addRef()
 {
-    mRefCount++;
+	mRefCount++;
 }
 
 void ResourceManager::release()
 {
-    if(--mRefCount == 0)
-    {
-        delete this;
-    }
+	if(--mRefCount == 0)
+	{
+		delete this;
+	}
 }
 
 // Returns an unused buffer name
 GLuint ResourceManager::createBuffer()
 {
-    //GLuint handle = mBufferNameSpace.allocate();
-    unsigned int handle = 1;
+	//GLuint handle = mBufferNameSpace.allocate();
+	unsigned int handle = 1;
 
-    while (mBufferMap.find(handle) != mBufferMap.end())
-    {
-        handle++;
-    }
+	while (mBufferMap.find(handle) != mBufferMap.end())
+	{
+		handle++;
+	}
 
-    mBufferMap[handle] = NULL;
+	mBufferMap[handle] = nullptr;
 
-    return handle;
+	return handle;
 }
 
 // Returns an unused shader/program name
 GLuint ResourceManager::createShader(GLenum type)
 {
-    //GLuint handle = mProgramShaderNameSpace.allocate();
-    unsigned int handle = 1;
+	//GLuint handle = mProgramShaderNameSpace.allocate();
+	unsigned int handle = 1;
 
-    while (mShaderMap.find(handle) != mShaderMap.end())
-    {
-        handle++;
-    }
+	while (mShaderMap.find(handle) != mShaderMap.end())
+	{
+		handle++;
+	}
 
-    if(type == GL_VERTEX_SHADER)
-    {
-        mShaderMap[handle] = new VertexShader(this, handle);
-    }
-    else if(type == GL_FRAGMENT_SHADER)
-    {
-        mShaderMap[handle] = new FragmentShader(this, handle);
-    }
-    else UNREACHABLE(type);
+	if(type == GL_VERTEX_SHADER)
+	{
+		mShaderMap[handle] = new VertexShader(this, handle);
+	}
+	else if(type == GL_FRAGMENT_SHADER)
+	{
+		mShaderMap[handle] = new FragmentShader(this, handle);
+	}
+	else UNREACHABLE(type);
 
-    return handle;
+	return handle;
 }
 
 // Returns an unused program/shader name
 GLuint ResourceManager::createProgram()
 {
-    //GLuint handle = mProgramShaderNameSpace.allocate();
-    unsigned int handle = 1;
+	//GLuint handle = mProgramShaderNameSpace.allocate();
+	unsigned int handle = 1;
 
-    while (mProgramMap.find(handle) != mProgramMap.end())
-    {
-        handle++;
-    }
+	while (mProgramMap.find(handle) != mProgramMap.end())
+	{
+		handle++;
+	}
 
-    mProgramMap[handle] = new Program(this, handle);
+	mProgramMap[handle] = new Program(this, handle);
 
-    return handle;
+	return handle;
 }
 
 // Returns an unused texture name
 GLuint ResourceManager::createTexture()
 {
-    //GLuint handle = mTextureNameSpace.allocate();
-    unsigned int handle = 1;
+	//GLuint handle = mTextureNameSpace.allocate();
+	unsigned int handle = 1;
 
-    while (mTextureMap.find(handle) != mTextureMap.end())
-    {
-        handle++;
-    }
+	while (mTextureMap.find(handle) != mTextureMap.end())
+	{
+		handle++;
+	}
 
-    mTextureMap[handle] = NULL;
+	mTextureMap[handle] = nullptr;
 
-    return handle;
+	return handle;
 }
 
 // Returns an unused renderbuffer name
 GLuint ResourceManager::createRenderbuffer()
 {
-    //GLuint handle = mRenderbufferNameSpace.allocate();
-    unsigned int handle = 1;
+	//GLuint handle = mRenderbufferNameSpace.allocate();
+	unsigned int handle = 1;
 
-    while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
-    {
-        handle++;
-    }
+	while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
+	{
+		handle++;
+	}
 
-    mRenderbufferMap[handle] = NULL;
+	mRenderbufferMap[handle] = nullptr;
 
-    return handle;
+	return handle;
 }
 
 void ResourceManager::deleteBuffer(GLuint buffer)
 {
-    BufferMap::iterator bufferObject = mBufferMap.find(buffer);
+	BufferMap::iterator bufferObject = mBufferMap.find(buffer);
 
-    if(bufferObject != mBufferMap.end())
-    {
-        //mBufferNameSpace.release(bufferObject->first);
-        if(bufferObject->second) bufferObject->second->release();
-        mBufferMap.erase(bufferObject);
-    }
+	if(bufferObject != mBufferMap.end())
+	{
+		//mBufferNameSpace.release(bufferObject->first);
+		if(bufferObject->second) bufferObject->second->release();
+		mBufferMap.erase(bufferObject);
+	}
 }
 
 void ResourceManager::deleteShader(GLuint shader)
 {
-    ShaderMap::iterator shaderObject = mShaderMap.find(shader);
+	ShaderMap::iterator shaderObject = mShaderMap.find(shader);
 
-    if(shaderObject != mShaderMap.end())
-    {
-        if(shaderObject->second->getRefCount() == 0)
-        {
-            //mProgramShaderNameSpace.release(shaderObject->first);
-            delete shaderObject->second;
-            mShaderMap.erase(shaderObject);
-        }
-        else
-        {
-            shaderObject->second->flagForDeletion();
-        }
-    }
+	if(shaderObject != mShaderMap.end())
+	{
+		if(shaderObject->second->getRefCount() == 0)
+		{
+			//mProgramShaderNameSpace.release(shaderObject->first);
+			delete shaderObject->second;
+			mShaderMap.erase(shaderObject);
+		}
+		else
+		{
+			shaderObject->second->flagForDeletion();
+		}
+	}
 }
 
 void ResourceManager::deleteProgram(GLuint program)
 {
-    ProgramMap::iterator programObject = mProgramMap.find(program);
+	ProgramMap::iterator programObject = mProgramMap.find(program);
 
-    if(programObject != mProgramMap.end())
-    {
-        if(programObject->second->getRefCount() == 0)
-        {
-            //mProgramShaderNameSpace.release(programObject->first);
-            delete programObject->second;
-            mProgramMap.erase(programObject);
-        }
-        else
-        { 
-            programObject->second->flagForDeletion();
-        }
-    }
+	if(programObject != mProgramMap.end())
+	{
+		if(programObject->second->getRefCount() == 0)
+		{
+			//mProgramShaderNameSpace.release(programObject->first);
+			delete programObject->second;
+			mProgramMap.erase(programObject);
+		}
+		else
+		{
+			programObject->second->flagForDeletion();
+		}
+	}
 }
 
 void ResourceManager::deleteTexture(GLuint texture)
 {
-    TextureMap::iterator textureObject = mTextureMap.find(texture);
+	TextureMap::iterator textureObject = mTextureMap.find(texture);
 
-    if(textureObject != mTextureMap.end())
-    {
-        //mTextureNameSpace.release(textureObject->first);
-        if(textureObject->second) textureObject->second->release();
-        mTextureMap.erase(textureObject);
-    }
+	if(textureObject != mTextureMap.end())
+	{
+		//mTextureNameSpace.release(textureObject->first);
+		if(textureObject->second) textureObject->second->release();
+		mTextureMap.erase(textureObject);
+	}
 }
 
 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
 {
-    RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
+	RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
 
-    if(renderbufferObject != mRenderbufferMap.end())
-    {
-        //mRenderbufferNameSpace.release(renderbufferObject->first);
-        if(renderbufferObject->second) renderbufferObject->second->release();
-        mRenderbufferMap.erase(renderbufferObject);
-    }
+	if(renderbufferObject != mRenderbufferMap.end())
+	{
+		//mRenderbufferNameSpace.release(renderbufferObject->first);
+		if(renderbufferObject->second) renderbufferObject->second->release();
+		mRenderbufferMap.erase(renderbufferObject);
+	}
 }
 
 Buffer *ResourceManager::getBuffer(unsigned int handle)
 {
-    BufferMap::iterator buffer = mBufferMap.find(handle);
+	BufferMap::iterator buffer = mBufferMap.find(handle);
 
-    if(buffer == mBufferMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return buffer->second;
-    }
+	if(buffer == mBufferMap.end())
+	{
+		return nullptr;
+	}
+	else
+	{
+		return buffer->second;
+	}
 }
 
 Shader *ResourceManager::getShader(unsigned int handle)
 {
-    ShaderMap::iterator shader = mShaderMap.find(handle);
+	ShaderMap::iterator shader = mShaderMap.find(handle);
 
-    if(shader == mShaderMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return shader->second;
-    }
+	if(shader == mShaderMap.end())
+	{
+		return nullptr;
+	}
+	else
+	{
+		return shader->second;
+	}
 }
 
 Texture *ResourceManager::getTexture(unsigned int handle)
 {
-    if(handle == 0) return NULL;
+	if(handle == 0) return nullptr;
 
-    TextureMap::iterator texture = mTextureMap.find(handle);
+	TextureMap::iterator texture = mTextureMap.find(handle);
 
-    if(texture == mTextureMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return texture->second;
-    }
+	if(texture == mTextureMap.end())
+	{
+		return nullptr;
+	}
+	else
+	{
+		return texture->second;
+	}
 }
 
 Program *ResourceManager::getProgram(unsigned int handle)
 {
-    ProgramMap::iterator program = mProgramMap.find(handle);
+	ProgramMap::iterator program = mProgramMap.find(handle);
 
-    if(program == mProgramMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return program->second;
-    }
+	if(program == mProgramMap.end())
+	{
+		return nullptr;
+	}
+	else
+	{
+		return program->second;
+	}
 }
 
 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
 {
-    RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
+	RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
 
-    if(renderbuffer == mRenderbufferMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return renderbuffer->second;
-    }
+	if(renderbuffer == mRenderbufferMap.end())
+	{
+		return nullptr;
+	}
+	else
+	{
+		return renderbuffer->second;
+	}
 }
 
 void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
 {
-    mRenderbufferMap[handle] = buffer;
+	mRenderbufferMap[handle] = buffer;
 }
 
 void ResourceManager::checkBufferAllocation(unsigned int buffer)
 {
-    if(buffer != 0 && !getBuffer(buffer))
-    {
-        Buffer *bufferObject = new Buffer(buffer);
-        mBufferMap[buffer] = bufferObject;
-        bufferObject->addRef();
-    }
+	if(buffer != 0 && !getBuffer(buffer))
+	{
+		Buffer *bufferObject = new Buffer(buffer);
+		mBufferMap[buffer] = bufferObject;
+		bufferObject->addRef();
+	}
 }
 
 void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
 {
-    if(!getTexture(texture) && texture != 0)
-    {
-        Texture *textureObject;
+	if(!getTexture(texture) && texture != 0)
+	{
+		Texture *textureObject;
 
-        if(type == TEXTURE_2D)
-        {
-            textureObject = new Texture2D(texture);
-        }
-        else if(type == TEXTURE_CUBE)
-        {
-            textureObject = new TextureCubeMap(texture);
-        }
-        else
-        {
-            UNREACHABLE(type);
-            return;
-        }
+		if(type == TEXTURE_2D)
+		{
+			textureObject = new Texture2D(texture);
+		}
+		else if(type == TEXTURE_CUBE)
+		{
+			textureObject = new TextureCubeMap(texture);
+		}
+		else
+		{
+			UNREACHABLE(type);
+			return;
+		}
 
-        mTextureMap[texture] = textureObject;
-        textureObject->addRef();
-    }
+		mTextureMap[texture] = textureObject;
+		textureObject->addRef();
+	}
 }
 
 void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
 {
-    if(renderbuffer != 0 && !getRenderbuffer(renderbuffer))
-    {
-        Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
-        mRenderbufferMap[renderbuffer] = renderbufferObject;
-        renderbufferObject->addRef();
-    }
+	if(renderbuffer != 0 && !getRenderbuffer(renderbuffer))
+	{
+		Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
+		mRenderbufferMap[renderbuffer] = renderbufferObject;
+		renderbufferObject->addRef();
+	}
 }
 
 }
diff --git a/src/OpenGL/libGL/ResourceManager.h b/src/OpenGL/libGL/ResourceManager.h
index 11c85eb..e857b03 100644
--- a/src/OpenGL/libGL/ResourceManager.h
+++ b/src/OpenGL/libGL/ResourceManager.h
@@ -1,103 +1,106 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// ResourceManager.h : Defines the ResourceManager class, which tracks objects

-// shared by multiple GL contexts.

-

-#ifndef LIBGL_RESOURCEMANAGER_H_

-#define LIBGL_RESOURCEMANAGER_H_

-

-#include "common/NameSpace.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#include <map>

-

-namespace gl

-{

-class Buffer;

-class Shader;

-class Program;

-class Texture;

-class Renderbuffer;

-

-enum TextureType

-{

-    TEXTURE_2D,

-    PROXY_TEXTURE_2D,

-    TEXTURE_CUBE,

-

-    TEXTURE_TYPE_COUNT,

-    TEXTURE_UNKNOWN

-};

-

-class ResourceManager

-{

-  public:

-    ResourceManager();

-    ~ResourceManager();

-

-    void addRef();

-    void release();

-

-    GLuint createBuffer();

-    GLuint createShader(GLenum type);

-    GLuint createProgram();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-

-    void deleteBuffer(GLuint buffer);

-    void deleteShader(GLuint shader);

-    void deleteProgram(GLuint program);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-

-    Buffer *getBuffer(GLuint handle);

-    Shader *getShader(GLuint handle);

-    Program *getProgram(GLuint handle);

-    Texture *getTexture(GLuint handle);

-    Renderbuffer *getRenderbuffer(GLuint handle);

-    

-    void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);

-

-    void checkBufferAllocation(unsigned int buffer);

-    void checkTextureAllocation(GLuint texture, TextureType type);

-    void checkRenderbufferAllocation(GLuint renderbuffer);

-

-  private:

-    std::size_t mRefCount;

-

-    typedef std::map<GLint, Buffer*> BufferMap;

-    BufferMap mBufferMap;

-    //NameSpace mBufferNameSpace;

-

-    typedef std::map<GLint, Shader*> ShaderMap;

-    ShaderMap mShaderMap;

-

-    typedef std::map<GLint, Program*> ProgramMap;

-    ProgramMap mProgramMap;

-    //NameSpace mProgramShaderNameSpace;

-

-    typedef std::map<GLint, Texture*> TextureMap;

-    TextureMap mTextureMap;

-    //NameSpace mTextureNameSpace;

-

-    typedef std::map<GLint, Renderbuffer*> RenderbufferMap;

-    RenderbufferMap mRenderbufferMap;

-    //NameSpace mRenderbufferNameSpace;

-};

-

-}

-

-#endif // LIBGL_RESOURCEMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// ResourceManager.h : Defines the ResourceManager class, which tracks objects
+// shared by multiple GL contexts.
+
+#ifndef LIBGL_RESOURCEMANAGER_H_
+#define LIBGL_RESOURCEMANAGER_H_
+
+#include "common/NameSpace.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#include <map>
+
+namespace gl
+{
+class Buffer;
+class Shader;
+class Program;
+class Texture;
+class Renderbuffer;
+
+enum TextureType
+{
+	TEXTURE_2D,
+	PROXY_TEXTURE_2D,
+	TEXTURE_CUBE,
+
+	TEXTURE_TYPE_COUNT,
+	TEXTURE_UNKNOWN
+};
+
+class ResourceManager
+{
+public:
+	ResourceManager();
+	~ResourceManager();
+
+	void addRef();
+	void release();
+
+	GLuint createBuffer();
+	GLuint createShader(GLenum type);
+	GLuint createProgram();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+
+	void deleteBuffer(GLuint buffer);
+	void deleteShader(GLuint shader);
+	void deleteProgram(GLuint program);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+
+	Buffer *getBuffer(GLuint handle);
+	Shader *getShader(GLuint handle);
+	Program *getProgram(GLuint handle);
+	Texture *getTexture(GLuint handle);
+	Renderbuffer *getRenderbuffer(GLuint handle);
+
+	void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
+
+	void checkBufferAllocation(unsigned int buffer);
+	void checkTextureAllocation(GLuint texture, TextureType type);
+	void checkRenderbufferAllocation(GLuint renderbuffer);
+
+private:
+	std::size_t mRefCount;
+
+	typedef std::map<GLint, Buffer*> BufferMap;
+	BufferMap mBufferMap;
+	//NameSpace mBufferNameSpace;
+
+	typedef std::map<GLint, Shader*> ShaderMap;
+	ShaderMap mShaderMap;
+
+	typedef std::map<GLint, Program*> ProgramMap;
+	ProgramMap mProgramMap;
+	//NameSpace mProgramShaderNameSpace;
+
+	typedef std::map<GLint, Texture*> TextureMap;
+	TextureMap mTextureMap;
+	//NameSpace mTextureNameSpace;
+
+	typedef std::map<GLint, Renderbuffer*> RenderbufferMap;
+	RenderbufferMap mRenderbufferMap;
+	//NameSpace mRenderbufferNameSpace;
+};
+
+}
+
+#endif // LIBGL_RESOURCEMANAGER_H_
diff --git a/src/OpenGL/libGL/Shader.cpp b/src/OpenGL/libGL/Shader.cpp
index 0b10049..14983bd 100644
--- a/src/OpenGL/libGL/Shader.cpp
+++ b/src/OpenGL/libGL/Shader.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Shader.cpp: Implements the Shader class and its  derived classes
 // VertexShader and FragmentShader. Implements GL shader objects and related
@@ -26,79 +29,79 @@
 
 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
 {
-    mSource = NULL;
+	mSource = nullptr;
 
 	clear();
 
-    mRefCount = 0;
-    mDeleteStatus = false;
+	mRefCount = 0;
+	mDeleteStatus = false;
 }
 
 Shader::~Shader()
 {
-    delete[] mSource;
+	delete[] mSource;
 }
 
 GLuint Shader::getName() const
 {
-    return mHandle;
+	return mHandle;
 }
 
 void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
 {
-    delete[] mSource;
-    int totalLength = 0;
+	delete[] mSource;
+	int totalLength = 0;
 
-    for(int i = 0; i < count; i++)
-    {
-        if(length && length[i] >= 0)
-        {
-            totalLength += length[i];
-        }
-        else
-        {
-            totalLength += (int)strlen(string[i]);
-        }
-    }
+	for(int i = 0; i < count; i++)
+	{
+		if(length && length[i] >= 0)
+		{
+			totalLength += length[i];
+		}
+		else
+		{
+			totalLength += (int)strlen(string[i]);
+		}
+	}
 
-    mSource = new char[totalLength + 1];
-    char *code = mSource;
+	mSource = new char[totalLength + 1];
+	char *code = mSource;
 
-    for(int i = 0; i < count; i++)
-    {
-        int stringLength;
+	for(int i = 0; i < count; i++)
+	{
+		int stringLength;
 
-        if(length && length[i] >= 0)
-        {
-            stringLength = length[i];
-        }
-        else
-        {
-            stringLength = (int)strlen(string[i]);
-        }
+		if(length && length[i] >= 0)
+		{
+			stringLength = length[i];
+		}
+		else
+		{
+			stringLength = (int)strlen(string[i]);
+		}
 
-        strncpy(code, string[i], stringLength);
-        code += stringLength;
-    }
+		strncpy(code, string[i], stringLength);
+		code += stringLength;
+	}
 
-    mSource[totalLength] = '\0';
+	mSource[totalLength] = '\0';
 }
 
 int Shader::getInfoLogLength() const
 {
-    if(infoLog.empty())
-    {
-        return 0;
-    }
-    else
-    {
-       return infoLog.size() + 1;
-    }
+	if(infoLog.empty())
+	{
+		return 0;
+	}
+	else
+	{
+	   return infoLog.size() + 1;
+	}
 }
 
 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
 {
-    int index = 0;
+	int index = 0;
 
 	if(bufSize > 0)
 	{
@@ -108,30 +111,30 @@
 			memcpy(infoLogOut, infoLog.c_str(), index);
 		}
 
-        infoLogOut[index] = '\0';
-    }
+		infoLogOut[index] = '\0';
+	}
 
-    if(length)
-    {
-        *length = index;
-    }
+	if(length)
+	{
+		*length = index;
+	}
 }
 
 int Shader::getSourceLength() const
 {
-    if(!mSource)
-    {
-        return 0;
-    }
-    else
-    {
-       return strlen(mSource) + 1;
-    }
+	if(!mSource)
+	{
+		return 0;
+	}
+	else
+	{
+	   return strlen(mSource) + 1;
+	}
 }
 
 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
 {
-    int index = 0;
+	int index = 0;
 
 	if(bufSize > 0)
 	{
@@ -141,13 +144,13 @@
 			memcpy(source, mSource, index);
 		}
 
-        source[index] = '\0';
-    }
+		source[index] = '\0';
+	}
 
-    if(length)
-    {
-        *length = index;
-    }
+	if(length)
+	{
+		*length = index;
+	}
 }
 
 TranslatorASM *Shader::createCompiler(GLenum shaderType)
@@ -193,12 +196,12 @@
 	createShader();
 	TranslatorASM *compiler = createCompiler(getType());
 
-	// Ensure we don't pass a NULL source to the compiler
-    char *source = "\0";
+	// Ensure we don't pass a nullptr source to the compiler
+	char *source = "\0";
 	if(mSource)
-    {
-        source = mSource;
-    }
+	{
+		source = mSource;
+	}
 
 	bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);
 
@@ -219,7 +222,7 @@
 		deleteShader();
 
 		infoLog = compiler->getInfoSink().info.c_str();
-        TRACE("\n%s", infoLog.c_str());
+		TRACE("\n%s", infoLog.c_str());
 	}
 
 	delete compiler;
@@ -227,126 +230,126 @@
 
 bool Shader::isCompiled()
 {
-    return getShader() != 0;
+	return getShader() != 0;
 }
 
 void Shader::addRef()
 {
-    mRefCount++;
+	mRefCount++;
 }
 
 void Shader::release()
 {
-    mRefCount--;
+	mRefCount--;
 
-    if(mRefCount == 0 && mDeleteStatus)
-    {
-        mResourceManager->deleteShader(mHandle);
-    }
+	if(mRefCount == 0 && mDeleteStatus)
+	{
+		mResourceManager->deleteShader(mHandle);
+	}
 }
 
 unsigned int Shader::getRefCount() const
 {
-    return mRefCount;
+	return mRefCount;
 }
 
 bool Shader::isFlaggedForDeletion() const
 {
-    return mDeleteStatus;
+	return mDeleteStatus;
 }
 
 void Shader::flagForDeletion()
 {
-    mDeleteStatus = true;
+	mDeleteStatus = true;
 }
 
 void Shader::releaseCompiler()
 {
-    FreeCompilerGlobals();
+	FreeCompilerGlobals();
 	compilerInitialized = false;
 }
 
 // true if varying x has a higher priority in packing than y
 bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
 {
-    if(x.type == y.type)
-    {
-        return x.size() > y.size();
-    }
+	if(x.type == y.type)
+	{
+		return x.size() > y.size();
+	}
 
-    switch (x.type)
-    {
-      case GL_FLOAT_MAT4: return true;
-      case GL_FLOAT_MAT2:
-        switch(y.type)
-        {
-          case GL_FLOAT_MAT4: return false;
-          case GL_FLOAT_MAT2: return true;
-          case GL_FLOAT_VEC4: return true;
-          case GL_FLOAT_MAT3: return true;
-          case GL_FLOAT_VEC3: return true;
-          case GL_FLOAT_VEC2: return true;
-          case GL_FLOAT:      return true;
-          default: UNREACHABLE(y.type);
-        }
-        break;
-      case GL_FLOAT_VEC4:
-        switch(y.type)
-        {
-          case GL_FLOAT_MAT4: return false;
-          case GL_FLOAT_MAT2: return false;
-          case GL_FLOAT_VEC4: return true;
-          case GL_FLOAT_MAT3: return true;
-          case GL_FLOAT_VEC3: return true;
-          case GL_FLOAT_VEC2: return true;
-          case GL_FLOAT:      return true;
-          default: UNREACHABLE(y.type);
-        }
-        break;
-      case GL_FLOAT_MAT3:
-        switch(y.type)
-        {
-          case GL_FLOAT_MAT4: return false;
-          case GL_FLOAT_MAT2: return false;
-          case GL_FLOAT_VEC4: return false;
-          case GL_FLOAT_MAT3: return true;
-          case GL_FLOAT_VEC3: return true;
-          case GL_FLOAT_VEC2: return true;
-          case GL_FLOAT:      return true;
-          default: UNREACHABLE(y.type);
-        }
-        break;
-      case GL_FLOAT_VEC3:
-        switch(y.type)
-        {
-          case GL_FLOAT_MAT4: return false;
-          case GL_FLOAT_MAT2: return false;
-          case GL_FLOAT_VEC4: return false;
-          case GL_FLOAT_MAT3: return false;
-          case GL_FLOAT_VEC3: return true;
-          case GL_FLOAT_VEC2: return true;
-          case GL_FLOAT:      return true;
-          default: UNREACHABLE(y.type);
-        }
-        break;
-      case GL_FLOAT_VEC2:
-        switch(y.type)
-        {
-          case GL_FLOAT_MAT4: return false;
-          case GL_FLOAT_MAT2: return false;
-          case GL_FLOAT_VEC4: return false;
-          case GL_FLOAT_MAT3: return false;
-          case GL_FLOAT_VEC3: return false;
-          case GL_FLOAT_VEC2: return true;
-          case GL_FLOAT:      return true;
-          default: UNREACHABLE(y.type);
-        }
-        break;
-      case GL_FLOAT: return false;
-      default: UNREACHABLE(x.type);
-    }
+	switch(x.type)
+	{
+	case GL_FLOAT_MAT4: return true;
+	case GL_FLOAT_MAT2:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return true;
+		case GL_FLOAT_VEC4: return true;
+		case GL_FLOAT_MAT3: return true;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_VEC4:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return true;
+		case GL_FLOAT_MAT3: return true;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_MAT3:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return false;
+		case GL_FLOAT_MAT3: return true;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_VEC3:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return false;
+		case GL_FLOAT_MAT3: return false;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_VEC2:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return false;
+		case GL_FLOAT_MAT3: return false;
+		case GL_FLOAT_VEC3: return false;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT: return false;
+	default: UNREACHABLE(x.type);
+	}
 
-    return false;
+	return false;
 }
 
 VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
@@ -361,23 +364,23 @@
 
 GLenum VertexShader::getType()
 {
-    return GL_VERTEX_SHADER;
+	return GL_VERTEX_SHADER;
 }
 
 int VertexShader::getSemanticIndex(const std::string &attributeName)
 {
-    if(!attributeName.empty())
-    {
+	if(!attributeName.empty())
+	{
 		for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
-        {
-            if(attribute->name == attributeName)
-            {
+		{
+			if(attribute->name == attributeName)
+			{
 				return attribute->registerIndex;
-            }
-        }
-    }
+			}
+		}
+	}
 
-    return -1;
+	return -1;
 }
 
 sw::Shader *VertexShader::getShader() const
@@ -414,7 +417,7 @@
 
 GLenum FragmentShader::getType()
 {
-    return GL_FRAGMENT_SHADER;
+	return GL_FRAGMENT_SHADER;
 }
 
 sw::Shader *FragmentShader::getShader() const
diff --git a/src/OpenGL/libGL/Shader.h b/src/OpenGL/libGL/Shader.h
index 3e95845..2267ac6 100644
--- a/src/OpenGL/libGL/Shader.h
+++ b/src/OpenGL/libGL/Shader.h
@@ -1,134 +1,137 @@
-// 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.

-//

-

-// Shader.h: Defines the abstract Shader class and its concrete derived

-// classes VertexShader and FragmentShader. Implements GL shader objects and

-// related functionality.

-

-

-#ifndef LIBGL_SHADER_H_

-#define LIBGL_SHADER_H_

-

-#include "ResourceManager.h"

-

-#include "compiler/TranslatorASM.h"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#include <string>

-#include <list>

-#include <vector>

-

-namespace glsl

-{

-	class OutputASM;

-}

-

-namespace gl

-{

-

-class Shader : public glsl::Shader

-{

-    friend class Program;

-

-public:

-    Shader(ResourceManager *manager, GLuint handle);

-

-    virtual ~Shader();

-

-    virtual GLenum getType() = 0;

-    GLuint getName() const;

-

-    void deleteSource();

-    void setSource(GLsizei count, const char *const *string, const GLint *length);

-    int getInfoLogLength() const;

-    void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);

-    int getSourceLength() const;

-    void getSource(GLsizei bufSize, GLsizei *length, char *source);

-

-    void compile();

-    bool isCompiled();

-    

-    void addRef();

-    void release();

-    unsigned int getRefCount() const;

-    bool isFlaggedForDeletion() const;

-    void flagForDeletion();

-

-    static void releaseCompiler();

-

-protected:

-	static bool compilerInitialized;

-	TranslatorASM *createCompiler(GLenum shaderType);

-	void clear();

-

-    static bool compareVarying(const glsl::Varying &x, const glsl::Varying &y);

-

-	char *mSource;

-	std::string infoLog;

-

-private:

-	virtual void createShader() = 0;

-	virtual void deleteShader() = 0;

-

-	const GLuint mHandle;

-    unsigned int mRefCount;     // Number of program objects this shader is attached to

-    bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use

-

-	ResourceManager *mResourceManager;

-};

-

-class VertexShader : public Shader

-{

-    friend class Program;

-

-public:

-    VertexShader(ResourceManager *manager, GLuint handle);

-

-    ~VertexShader();

-

-    virtual GLenum getType();

-    int getSemanticIndex(const std::string &attributeName);

-

-	virtual sw::Shader *getShader() const;

-	virtual sw::VertexShader *getVertexShader() const;

-

-private:

-	virtual void createShader();

-	virtual void deleteShader();

-

-	sw::VertexShader *vertexShader;

-};

-

-class FragmentShader : public Shader

-{

-public:

-    FragmentShader(ResourceManager *manager, GLuint handle);

-

-    ~FragmentShader();

-

-    virtual GLenum getType();

-

-	virtual sw::Shader *getShader() const;

-	virtual sw::PixelShader *getPixelShader() const;

-

-private:

-	virtual void createShader();

-	virtual void deleteShader();

-

-	sw::PixelShader *pixelShader;

-};

-}

-

-#endif   // LIBGL_SHADER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Shader.h: Defines the abstract Shader class and its concrete derived
+// classes VertexShader and FragmentShader. Implements GL shader objects and
+// related functionality.
+
+
+#ifndef LIBGL_SHADER_H_
+#define LIBGL_SHADER_H_
+
+#include "ResourceManager.h"
+
+#include "compiler/TranslatorASM.h"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#include <string>
+#include <list>
+#include <vector>
+
+namespace glsl
+{
+	class OutputASM;
+}
+
+namespace gl
+{
+
+class Shader : public glsl::Shader
+{
+	friend class Program;
+
+public:
+	Shader(ResourceManager *manager, GLuint handle);
+
+	virtual ~Shader();
+
+	virtual GLenum getType() = 0;
+	GLuint getName() const;
+
+	void deleteSource();
+	void setSource(GLsizei count, const char *const *string, const GLint *length);
+	int getInfoLogLength() const;
+	void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
+	int getSourceLength() const;
+	void getSource(GLsizei bufSize, GLsizei *length, char *source);
+
+	void compile();
+	bool isCompiled();
+
+	void addRef();
+	void release();
+	unsigned int getRefCount() const;
+	bool isFlaggedForDeletion() const;
+	void flagForDeletion();
+
+	static void releaseCompiler();
+
+protected:
+	static bool compilerInitialized;
+	TranslatorASM *createCompiler(GLenum shaderType);
+	void clear();
+
+	static bool compareVarying(const glsl::Varying &x, const glsl::Varying &y);
+
+	char *mSource;
+	std::string infoLog;
+
+private:
+	virtual void createShader() = 0;
+	virtual void deleteShader() = 0;
+
+	const GLuint mHandle;
+	unsigned int mRefCount;     // Number of program objects this shader is attached to
+	bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use
+
+	ResourceManager *mResourceManager;
+};
+
+class VertexShader : public Shader
+{
+	friend class Program;
+
+public:
+	VertexShader(ResourceManager *manager, GLuint handle);
+
+	~VertexShader();
+
+	virtual GLenum getType();
+	int getSemanticIndex(const std::string &attributeName);
+
+	virtual sw::Shader *getShader() const;
+	virtual sw::VertexShader *getVertexShader() const;
+
+private:
+	virtual void createShader();
+	virtual void deleteShader();
+
+	sw::VertexShader *vertexShader;
+};
+
+class FragmentShader : public Shader
+{
+public:
+	FragmentShader(ResourceManager *manager, GLuint handle);
+
+	~FragmentShader();
+
+	virtual GLenum getType();
+
+	virtual sw::Shader *getShader() const;
+	virtual sw::PixelShader *getPixelShader() const;
+
+private:
+	virtual void createShader();
+	virtual void deleteShader();
+
+	sw::PixelShader *pixelShader;
+};
+}
+
+#endif   // LIBGL_SHADER_H_
diff --git a/src/OpenGL/libGL/Surface.cpp b/src/OpenGL/libGL/Surface.cpp
index f5ccae6..a6ec333 100644
--- a/src/OpenGL/libGL/Surface.cpp
+++ b/src/OpenGL/libGL/Surface.cpp
@@ -1,256 +1,259 @@
-// 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.

-//

-

-// Surface.cpp: Implements the Surface class, representing a drawing surface

-// such as the client area of a window, including any back buffers.

-

-#include "Surface.h"

-

-#include "main.h"

-#include "Display.h"

-#include "Image.hpp"

-#include "Context.h"

-#include "common/debug.h"

-#include "Main/FrameBuffer.hpp"

-

-#if defined(_WIN32)

-#include <tchar.h>

-#endif

-

-#include <algorithm>

-

-namespace gl

-{

-

-Surface::Surface(Display *display, NativeWindowType window)

-    : mDisplay(display), mWindow(window)

-{

-    frameBuffer = 0;

-	backBuffer = 0;

-

-    mDepthStencil = NULL;

-    mTextureFormat = GL_NONE;

-    mTextureTarget = GL_NONE;

-

-    mSwapInterval = -1;

-    setSwapInterval(1);

-}

-

-Surface::Surface(Display *display, GLint width, GLint height, GLenum textureFormat, GLenum textureType)

-    : mDisplay(display), mWindow(NULL), mWidth(width), mHeight(height)

-{

-	frameBuffer = 0;

-	backBuffer = 0;

-

-    mDepthStencil = NULL;

-    mWindowSubclassed = false;

-    mTextureFormat = textureFormat;

-    mTextureTarget = textureType;

-

-    mSwapInterval = -1;

-    setSwapInterval(1);

-}

-

-Surface::~Surface()

-{

-    release();

-}

-

-bool Surface::initialize()

-{

-    ASSERT(!frameBuffer && !backBuffer && !mDepthStencil);

-

-    return reset();

-}

-

-void Surface::release()

-{	

-    if(mDepthStencil)

-    {

-        mDepthStencil->release();

-        mDepthStencil = NULL;

-    }

-

-	if(backBuffer)

-	{

-		backBuffer->release();

-		backBuffer = 0;

-	}

-

-	delete frameBuffer;

-	frameBuffer = 0;

-}

-

-bool Surface::reset()

-{

-    if(!mWindow)

-    {

-        return reset(mWidth, mHeight);

-    }

-

-	// FIXME: Wrap into an abstract Window class

-	#if defined(_WIN32)

-		RECT windowRect;

-		GetClientRect(mWindow, &windowRect);

-

-		return reset(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);

-	#else

-		XWindowAttributes windowAttributes;

-		XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);

-		

-		return reset(windowAttributes.width, windowAttributes.height);

-	#endif

-}

-

-bool Surface::reset(int backBufferWidth, int backBufferHeight)

-{

-    release();

-

-    if(mWindow)

-    {

-		frameBuffer = ::createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);

-

-		if(!frameBuffer)

-		{

-			ERR("Could not create frame buffer");

-			release();

-			return error(GL_OUT_OF_MEMORY, false);

-		}

-    }

-

-	backBuffer = new Image(0, backBufferWidth, backBufferHeight, GL_RGB, GL_UNSIGNED_BYTE);

-

-    if(!backBuffer)

-    {

-        ERR("Could not create back buffer");

-        release();

-        return error(GL_OUT_OF_MEMORY, false);

-    }

-

-    if(true)   // Always provide a depth/stencil buffer

-    {

-        mDepthStencil = new Image(0, backBufferWidth, backBufferHeight, sw::FORMAT_D24S8, 1, false, true);

-

-		if(!mDepthStencil)

-		{

-			ERR("Could not create depth/stencil buffer for surface");

-			release();

-			return error(GL_OUT_OF_MEMORY, false);

-		}

-    }

-

-    mWidth = backBufferWidth;

-    mHeight = backBufferHeight;

-

-    return true;

-}

-

-void Surface::swap()

-{

-	if(backBuffer)

-    {

-		void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-		frameBuffer->flip(source, backBuffer->Surface::getInternalFormat(), backBuffer->getInternalPitchB());

-		backBuffer->unlockInternal();

-

-        checkForResize();

-	}

-}

-

-Image *Surface::getRenderTarget()

-{

-    if(backBuffer)

-    {

-        backBuffer->addRef();

-    }

-

-    return backBuffer;

-}

-

-Image *Surface::getDepthStencil()

-{

-    if(mDepthStencil)

-    {

-        mDepthStencil->addRef();

-    }

-

-    return mDepthStencil;

-}

-

-void Surface::setSwapInterval(GLint interval)

-{

-    if(mSwapInterval == interval)

-    {

-        return;

-    }

-    

-    mSwapInterval = interval;

-    mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());

-    mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());

-}

-

-GLint Surface::getWidth() const

-{

-    return mWidth;

-}

-

-GLint Surface::getHeight() const

-{

-    return mHeight;

-}

-

-GLenum Surface::getTextureFormat() const

-{

-    return mTextureFormat;

-}

-

-GLenum Surface::getTextureTarget() const

-{

-    return mTextureTarget;

-}

-

-bool Surface::checkForResize()

-{

-    #if defined(_WIN32)

-		RECT client;

-		if(!GetClientRect(mWindow, &client))

-		{

-			ASSERT(false);

-			return false;

-		}

-

-		int clientWidth = client.right - client.left;

-		int clientHeight = client.bottom - client.top;

-	#else

-		XWindowAttributes windowAttributes;

-		XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);

-

-		int clientWidth = windowAttributes.width;

-		int clientHeight = windowAttributes.height;

-	#endif

-

-	bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();

-

-    if(sizeDirty)

-    {

-        reset(clientWidth, clientHeight);

-

-        if(getCurrentDrawSurface() == this)

-        {

-			getContext()->makeCurrent(this);

-        }

-

-        return true;

-    }

-

-    return false;

-}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Surface.cpp: Implements the Surface class, representing a drawing surface
+// such as the client area of a window, including any back buffers.
+
+#include "Surface.h"
+
+#include "main.h"
+#include "Display.h"
+#include "Image.hpp"
+#include "Context.h"
+#include "common/debug.h"
+#include "Main/FrameBuffer.hpp"
+
+#if defined(_WIN32)
+#include <tchar.h>
+#endif
+
+#include <algorithm>
+
+namespace gl
+{
+
+Surface::Surface(Display *display, NativeWindowType window)
+	: mDisplay(display), mWindow(window)
+{
+	frameBuffer = 0;
+	backBuffer = 0;
+
+	mDepthStencil = nullptr;
+	mTextureFormat = GL_NONE;
+	mTextureTarget = GL_NONE;
+
+	mSwapInterval = -1;
+	setSwapInterval(1);
+}
+
+Surface::Surface(Display *display, GLint width, GLint height, GLenum textureFormat, GLenum textureType)
+	: mDisplay(display), mWindow(nullptr), mWidth(width), mHeight(height)
+{
+	frameBuffer = 0;
+	backBuffer = 0;
+
+	mDepthStencil = nullptr;
+	mWindowSubclassed = false;
+	mTextureFormat = textureFormat;
+	mTextureTarget = textureType;
+
+	mSwapInterval = -1;
+	setSwapInterval(1);
+}
+
+Surface::~Surface()
+{
+	release();
+}
+
+bool Surface::initialize()
+{
+	ASSERT(!frameBuffer && !backBuffer && !mDepthStencil);
+
+	return reset();
+}
+
+void Surface::release()
+{
+	if(mDepthStencil)
+	{
+		mDepthStencil->release();
+		mDepthStencil = nullptr;
+	}
+
+	if(backBuffer)
+	{
+		backBuffer->release();
+		backBuffer = 0;
+	}
+
+	delete frameBuffer;
+	frameBuffer = 0;
+}
+
+bool Surface::reset()
+{
+	if(!mWindow)
+	{
+		return reset(mWidth, mHeight);
+	}
+
+	// FIXME: Wrap into an abstract Window class
+	#if defined(_WIN32)
+		RECT windowRect;
+		GetClientRect(mWindow, &windowRect);
+
+		return reset(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
+	#else
+		XWindowAttributes windowAttributes;
+		XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
+
+		return reset(windowAttributes.width, windowAttributes.height);
+	#endif
+}
+
+bool Surface::reset(int backBufferWidth, int backBufferHeight)
+{
+	release();
+
+	if(mWindow)
+	{
+		frameBuffer = ::createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);
+
+		if(!frameBuffer)
+		{
+			ERR("Could not create frame buffer");
+			release();
+			return error(GL_OUT_OF_MEMORY, false);
+		}
+	}
+
+	backBuffer = new Image(0, backBufferWidth, backBufferHeight, GL_RGB, GL_UNSIGNED_BYTE);
+
+	if(!backBuffer)
+	{
+		ERR("Could not create back buffer");
+		release();
+		return error(GL_OUT_OF_MEMORY, false);
+	}
+
+	if(true)   // Always provide a depth/stencil buffer
+	{
+		mDepthStencil = new Image(0, backBufferWidth, backBufferHeight, sw::FORMAT_D24S8, 1, false, true);
+
+		if(!mDepthStencil)
+		{
+			ERR("Could not create depth/stencil buffer for surface");
+			release();
+			return error(GL_OUT_OF_MEMORY, false);
+		}
+	}
+
+	mWidth = backBufferWidth;
+	mHeight = backBufferHeight;
+
+	return true;
+}
+
+void Surface::swap()
+{
+	if(backBuffer)
+	{
+		void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+		frameBuffer->flip(source, backBuffer->Surface::getInternalFormat(), backBuffer->getInternalPitchB());
+		backBuffer->unlockInternal();
+
+		checkForResize();
+	}
+}
+
+Image *Surface::getRenderTarget()
+{
+	if(backBuffer)
+	{
+		backBuffer->addRef();
+	}
+
+	return backBuffer;
+}
+
+Image *Surface::getDepthStencil()
+{
+	if(mDepthStencil)
+	{
+		mDepthStencil->addRef();
+	}
+
+	return mDepthStencil;
+}
+
+void Surface::setSwapInterval(GLint interval)
+{
+	if(mSwapInterval == interval)
+	{
+		return;
+	}
+
+	mSwapInterval = interval;
+	mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
+	mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
+}
+
+GLint Surface::getWidth() const
+{
+	return mWidth;
+}
+
+GLint Surface::getHeight() const
+{
+	return mHeight;
+}
+
+GLenum Surface::getTextureFormat() const
+{
+	return mTextureFormat;
+}
+
+GLenum Surface::getTextureTarget() const
+{
+	return mTextureTarget;
+}
+
+bool Surface::checkForResize()
+{
+	#if defined(_WIN32)
+		RECT client;
+		if(!GetClientRect(mWindow, &client))
+		{
+			ASSERT(false);
+			return false;
+		}
+
+		int clientWidth = client.right - client.left;
+		int clientHeight = client.bottom - client.top;
+	#else
+		XWindowAttributes windowAttributes;
+		XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
+
+		int clientWidth = windowAttributes.width;
+		int clientHeight = windowAttributes.height;
+	#endif
+
+	bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
+
+	if(sizeDirty)
+	{
+		reset(clientWidth, clientHeight);
+
+		if(getCurrentDrawSurface() == this)
+		{
+			getContext()->makeCurrent(this);
+		}
+
+		return true;
+	}
+
+	return false;
+}
+}
diff --git a/src/OpenGL/libGL/Surface.h b/src/OpenGL/libGL/Surface.h
index 06b33d5..20ab599 100644
--- a/src/OpenGL/libGL/Surface.h
+++ b/src/OpenGL/libGL/Surface.h
@@ -1,82 +1,85 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Surface.h: Defines the Surface class, representing a drawing surface

-// such as the client area of a window, including any back buffers.

-

-#ifndef INCLUDE_SURFACE_H_

-#define INCLUDE_SURFACE_H_

-

-#include "Main/FrameBuffer.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#if defined(_WIN32)

-typedef HDC     NativeDisplayType;

-typedef HBITMAP NativePixmapType;

-typedef HWND    NativeWindowType;

-#else

-#error

-#endif

-

-namespace gl

-{

-class Image;

-class Display;

-

-class Surface

-{

-public:

-    Surface(Display *display, NativeWindowType window);

-    Surface(Display *display, GLint width, GLint height, GLenum textureFormat, GLenum textureTarget);

-

-    virtual ~Surface();

-

-	bool initialize();

-    void swap();

-    

-    virtual Image *getRenderTarget();

-    virtual Image *getDepthStencil();

-

-    void setSwapInterval(GLint interval);

-

-    virtual GLint getWidth() const;

-    virtual GLint getHeight() const;

-    virtual GLenum getTextureFormat() const;

-    virtual GLenum getTextureTarget() const;

-

-	bool checkForResize();   // Returns true if surface changed due to resize

-

-private:

-    void release();

-    bool reset();

-

-    Display *const mDisplay;

-    Image *mDepthStencil;

-	sw::FrameBuffer *frameBuffer;

-	Image *backBuffer;

-

-	bool reset(int backbufferWidth, int backbufferHeight);

-    

-    const NativeWindowType mWindow;   // Window that the surface is created for.

-    bool mWindowSubclassed;           // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking

-    GLint mHeight;                    // Height of surface

-    GLint mWidth;                     // Width of surface

-    GLenum mTextureFormat;            // Format of texture: RGB, RGBA, or no texture

-    GLenum mTextureTarget;            // Type of texture: 2D or no texture

-    GLint mSwapInterval;

-};

-}

-

-#endif   // INCLUDE_SURFACE_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Surface.h: Defines the Surface class, representing a drawing surface
+// such as the client area of a window, including any back buffers.
+
+#ifndef INCLUDE_SURFACE_H_
+#define INCLUDE_SURFACE_H_
+
+#include "Main/FrameBuffer.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#if defined(_WIN32)
+typedef HDC     NativeDisplayType;
+typedef HBITMAP NativePixmapType;
+typedef HWND    NativeWindowType;
+#else
+#error
+#endif
+
+namespace gl
+{
+class Image;
+class Display;
+
+class Surface
+{
+public:
+	Surface(Display *display, NativeWindowType window);
+	Surface(Display *display, GLint width, GLint height, GLenum textureFormat, GLenum textureTarget);
+
+	virtual ~Surface();
+
+	bool initialize();
+	void swap();
+
+	virtual Image *getRenderTarget();
+	virtual Image *getDepthStencil();
+
+	void setSwapInterval(GLint interval);
+
+	virtual GLint getWidth() const;
+	virtual GLint getHeight() const;
+	virtual GLenum getTextureFormat() const;
+	virtual GLenum getTextureTarget() const;
+
+	bool checkForResize();   // Returns true if surface changed due to resize
+
+private:
+	void release();
+	bool reset();
+
+	Display *const mDisplay;
+	Image *mDepthStencil;
+	sw::FrameBuffer *frameBuffer;
+	Image *backBuffer;
+
+	bool reset(int backbufferWidth, int backbufferHeight);
+
+	const NativeWindowType mWindow;   // Window that the surface is created for.
+	bool mWindowSubclassed;           // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
+	GLint mHeight;                    // Height of surface
+	GLint mWidth;                     // Width of surface
+	GLenum mTextureFormat;            // Format of texture: RGB, RGBA, or no texture
+	GLenum mTextureTarget;            // Type of texture: 2D or no texture
+	GLint mSwapInterval;
+};
+}
+
+#endif   // INCLUDE_SURFACE_H_
diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
index 0f1a0e9..0265a1c 100644
--- a/src/OpenGL/libGL/Texture.cpp
+++ b/src/OpenGL/libGL/Texture.cpp
@@ -1,1041 +1,1044 @@
-// 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.

-//

-

-// Texture.cpp: Implements the Texture class and its derived classes

-// Texture2D and TextureCubeMap. Implements GL texture objects and related

-// functionality.

-

-#include "Texture.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "Framebuffer.h"

-#include "Device.hpp"

-#include "Display.h"

-#include "common/debug.h"

-

-#include <algorithm>

-

-namespace gl

-{

-

-Texture::Texture(GLuint name) : NamedObject(name)

-{

-    mMinFilter = GL_NEAREST_MIPMAP_LINEAR;

-    mMagFilter = GL_LINEAR;

-    mWrapS = GL_REPEAT;

-    mWrapT = GL_REPEAT;

-	mMaxAnisotropy = 1.0f;

-	mMaxLevel = 1000;

-

-	resource = new sw::Resource(0);

-}

-

-Texture::~Texture()

-{

-	resource->destruct();

-}

-

-sw::Resource *Texture::getResource() const

-{

-	return resource;

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMinFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        mMinFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMagFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        mMagFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapS(GLenum wrap)

-{

-    switch(wrap)

-    {

-    case GL_CLAMP:

-    case GL_REPEAT:

-    case GL_CLAMP_TO_EDGE:

-    case GL_MIRRORED_REPEAT:

-        mWrapS = wrap;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapT(GLenum wrap)

-{

-    switch(wrap)

-    {

-    case GL_CLAMP:

-    case GL_REPEAT:

-    case GL_CLAMP_TO_EDGE:

-    case GL_MIRRORED_REPEAT:

-         mWrapT = wrap;

-         return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful max anisotropy update (valid anisotropy value)

-bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)

-{

-    textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);

-

-    if(textureMaxAnisotropy < 1.0f)

-    {

-        return false;

-    }

-    

-	if(mMaxAnisotropy != textureMaxAnisotropy)

-    {

-        mMaxAnisotropy = textureMaxAnisotropy;

-    }

-

-    return true;

-}

-

-bool Texture::setMaxLevel(int level)

-{

-    if(level < 0)

-    {

-        return false;

-    }

-    

-	mMaxLevel = level;

-

-    return true;

-}

-

-GLenum Texture::getMinFilter() const

-{

-    return mMinFilter;

-}

-

-GLenum Texture::getMagFilter() const

-{

-    return mMagFilter;

-}

-

-GLenum Texture::getWrapS() const

-{

-    return mWrapS;

-}

-

-GLenum Texture::getWrapT() const

-{

-    return mWrapT;

-}

-

-GLfloat Texture::getMaxAnisotropy() const

-{

-    return mMaxAnisotropy;

-}

-

-void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)

-{

-    if(pixels && image)

-    {

-		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackAlignment, pixels);

-    }

-}

-

-void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)

-{

-    if(pixels && image)

-    {

-		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);

-    }

-}

-

-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(IsCompressed(image->getFormat()))

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-        image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackAlignment, pixels);

-    }

-}

-

-void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);

-    }

-}

-

-bool Texture::copy(Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, Image *dest)

-{

-    Device *device = getDevice();

-	

-    sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), 0);

-    sw::SliceRect sourceSliceRect(sourceRect);

-    bool success = device->stretchRect(source, &sourceSliceRect, dest, &destRect, false);

-

-    if(!success)

-    {

-        return error(GL_OUT_OF_MEMORY, false);

-    }

-

-    return true;

-}

-

-bool Texture::isMipmapFiltered() const

-{

-	switch(mMinFilter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        return false;

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        return true;

-    default: UNREACHABLE(mMinFilter);

-    }

-

-	return false;

-}

-

-Texture2D::Texture2D(GLuint name) : Texture(name)

-{

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		image[i] = 0;

-	}

-

-	mColorbufferProxy = NULL;

-	mProxyRefs = 0;

-}

-

-Texture2D::~Texture2D()

-{

-	resource->lock(sw::DESTRUCT);

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i])

-		{

-			image[i]->unbind();

-			image[i] = 0;

-		}

-	}

-

-	resource->unlock();

-

-	mColorbufferProxy = NULL;

-}

-

-// We need to maintain a count of references to renderbuffers acting as 

-// proxies for this texture, so that we do not attempt to use a pointer 

-// to a renderbuffer proxy which has been deleted.

-void Texture2D::addProxyRef(const Renderbuffer *proxy)

-{

-    mProxyRefs++;

-}

-

-void Texture2D::releaseProxy(const Renderbuffer *proxy)

-{

-    if(mProxyRefs > 0)

-	{

-        mProxyRefs--;

-	}

-

-    if(mProxyRefs == 0)

-	{

-		mColorbufferProxy = NULL;

-	}

-}

-

-GLenum Texture2D::getTarget() const

-{

-    return GL_TEXTURE_2D;

-}

-

-GLsizei Texture2D::getWidth(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);

-    return image[level] ? image[level]->getWidth() : 0;

-}

-

-GLsizei Texture2D::getHeight(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);

-    return image[level] ? image[level]->getHeight() : 0;

-}

-

-GLenum Texture2D::getFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);

-	return image[level] ? image[level]->getFormat() : GL_NONE;

-}

-

-GLenum Texture2D::getType(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);

-	return image[level] ? image[level]->getType() : GL_NONE;

-}

-

-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);

-	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;

-}

-

-int Texture2D::getLevelCount() const

-{

-	ASSERT(isSamplerComplete());

-	int levels = 0;

-

-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])

-	{

-		levels++;

-	}

-

-	return levels;

-}

-

-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->unbind();

-	}

-

-	image[level] = new Image(this, width, height, format, type);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setImage(format, type, unpackAlignment, pixels, image[level]);

-}

-

-void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->unbind();

-	}

-

-	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setCompressedImage(imageSize, pixels, image[level]);

-}

-

-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);

-}

-

-void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

-{

-    Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);

-}

-

-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-    Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	if(image[level])

-	{

-		image[level]->unbind();

-	}

-

-	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    if(width != 0 && height != 0)

-    {

-		sw::Rect sourceRect = {x, y, x + width, y + height};

-		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-

-        copy(renderTarget, sourceRect, format, 0, 0, image[level]);

-    }

-

-	renderTarget->release();

-}

-

-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	if(!image[level])

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-	Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	sw::Rect sourceRect = {x, y, x + width, y + height};

-	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-

-	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);

-

-	renderTarget->release();

-}

-

-void Texture2D::setImage(Image *sharedImage)

-{

-	sharedImage->addRef();

-

-    if(image[0])

-    {

-        image[0]->unbind();

-    }

-

-    image[0] = sharedImage;

-}

-

-// Tests for 2D texture sampling completeness.

-bool Texture2D::isSamplerComplete() const

-{

-	if(!image[0])

-	{

-		return false;

-	}

-

-    GLsizei width = image[0]->getWidth();

-    GLsizei height = image[0]->getHeight();

-

-    if(width <= 0 || height <= 0)

-    {

-        return false;

-    }

-

-    if(isMipmapFiltered())

-    {

-        if(!isMipmapComplete())

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-// Tests for 2D texture (mipmap) completeness.

-bool Texture2D::isMipmapComplete() const

-{

-    GLsizei width = image[0]->getWidth();

-    GLsizei height = image[0]->getHeight();

-

-    int q = log2(std::max(width, height));

-

-    for(int level = 1; level <= q && level <= mMaxLevel; level++)

-    {

-		if(!image[level])

-		{

-			return false;

-		}

-

-        if(image[level]->getFormat() != image[0]->getFormat())

-        {

-            return false;

-        }

-

-        if(image[level]->getType() != image[0]->getType())

-        {

-            return false;

-        }

-

-        if(image[level]->getWidth() != std::max(1, width >> level))

-        {

-            return false;

-        }

-

-        if(image[level]->getHeight() != std::max(1, height >> level))

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-bool Texture2D::isCompressed(GLenum target, GLint level) const

-{

-    return IsCompressed(getFormat(target, level));

-}

-

-bool Texture2D::isDepth(GLenum target, GLint level) const

-{

-    return IsDepthTexture(getFormat(target, level));

-}

-

-void Texture2D::generateMipmaps()

-{

-	if(!image[0])

-	{

-		return;   // FIXME: error?

-	}

-

-    unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));

-    

-	for(unsigned int i = 1; i <= q; i++)

-    {

-		if(image[i])

-		{

-			image[i]->unbind();

-		}

-

-		image[i] = new Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());

-

-		if(!image[i])

-		{

-			return error(GL_OUT_OF_MEMORY);

-		}

-

-		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);

-    }

-}

-

-Image *Texture2D::getImage(unsigned int level)

-{

-	return image[level];

-}

-

-Renderbuffer *Texture2D::getRenderbuffer(GLenum target)

-{

-    if(target != GL_TEXTURE_2D)

-    {

-        return error(GL_INVALID_OPERATION, (Renderbuffer*)NULL);

-    }

-

-    if(mColorbufferProxy == NULL)

-    {

-        mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));

-    }

-

-    return mColorbufferProxy;

-}

-

-Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)

-{

-    ASSERT(target == GL_TEXTURE_2D);

-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-	if(image[level])

-	{

-		image[level]->addRef();

-	}

-

-	return image[level];

-}

-

-TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)

-{

-	for(int f = 0; f < 6; f++)

-	{

-		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-		{

-			image[f][i] = 0;

-		}

-	}

-

-	for(int f = 0; f < 6; f++)

-    {

-        mFaceProxies[f] = NULL;

-        mFaceProxyRefs[f] = 0;

-	}

-}

-

-TextureCubeMap::~TextureCubeMap()

-{

-	resource->lock(sw::DESTRUCT);

-

-	for(int f = 0; f < 6; f++)

-	{

-		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-		{

-			if(image[f][i])

-			{

-				image[f][i]->unbind();

-				image[f][i] = 0;

-			}

-		}

-	}

-

-	resource->unlock();

-

-    for(int i = 0; i < 6; i++)

-    {

-        mFaceProxies[i] = NULL;

-    }

-}

-

-// We need to maintain a count of references to renderbuffers acting as 

-// proxies for this texture, so that the texture is not deleted while 

-// proxy references still exist. If the reference count drops to zero,

-// we set our proxy pointer NULL, so that a new attempt at referencing

-// will cause recreation.

-void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)

-{

-    for(int f = 0; f < 6; f++)

-    {

-        if(mFaceProxies[f] == proxy)

-        {

-			mFaceProxyRefs[f]++;

-		}

-	}

-}

-

-void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)

-{

-    for(int f = 0; f < 6; f++)

-    {

-        if(mFaceProxies[f] == proxy)

-        {

-            if(mFaceProxyRefs[f] > 0)

-			{

-				mFaceProxyRefs[f]--;

-			}

-

-            if(mFaceProxyRefs[f] == 0)

-			{

-				mFaceProxies[f] = NULL;

-			}

-		}

-    }

-}

-

-GLenum TextureCubeMap::getTarget() const

-{

-    return GL_TEXTURE_CUBE_MAP;

-}

-

-GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getWidth() : 0;

-}

-

-GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getHeight() : 0;

-}

-

-GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-	return image[face][level] ? image[face][level]->getFormat() : GL_NONE;

-}

-

-GLenum TextureCubeMap::getType(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-	return image[face][level] ? image[face][level]->getType() : GL_NONE;

-}

-

-sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;

-}

-

-int TextureCubeMap::getLevelCount() const

-{

-	ASSERT(isSamplerComplete());

-	int levels = 0;

-

-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][levels])

-	{

-		levels++;

-	}

-

-	return levels;

-}

-

-void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)

-{

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->unbind();

-	}

-

-	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[face][level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setCompressedImage(imageSize, pixels, image[face][level]);

-}

-

-void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-    Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[CubeFaceIndex(target)][level]);

-}

-

-void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

-{

-    Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);

-}

-

-// Tests for cube map sampling completeness.

-bool TextureCubeMap::isSamplerComplete() const

-{

-	for(int face = 0; face < 6; face++)

-    {

-		if(!image[face][0])

-		{

-			return false;

-		}

-	}

-

-    int size = image[0][0]->getWidth();

-

-    if(size <= 0)

-    {

-        return false;

-    }

-

-    if(!isMipmapFiltered())

-    {

-        if(!isCubeComplete())

-        {

-            return false;

-        }

-    }

-    else

-    {

-        if(!isMipmapCubeComplete())   // Also tests for isCubeComplete()

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-// Tests for cube texture completeness.

-bool TextureCubeMap::isCubeComplete() const

-{

-    if(image[0][0]->getWidth() <= 0 || image[0][0]->getHeight() != image[0][0]->getWidth())

-    {

-        return false;

-    }

-

-    for(unsigned int face = 1; face < 6; face++)

-    {

-        if(image[face][0]->getWidth()  != image[0][0]->getWidth() ||

-           image[face][0]->getWidth()  != image[0][0]->getHeight() ||

-           image[face][0]->getFormat() != image[0][0]->getFormat() ||

-           image[face][0]->getType()   != image[0][0]->getType())

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-bool TextureCubeMap::isMipmapCubeComplete() const

-{

-    if(!isCubeComplete())

-    {

-        return false;

-    }

-

-    GLsizei size = image[0][0]->getWidth();

-    int q = log2(size);

-

-    for(int face = 0; face < 6; face++)

-    {

-        for(int level = 1; level <= q; level++)

-        {

-			if(!image[face][level])

-			{

-				return false;

-			}

-

-            if(image[face][level]->getFormat() != image[0][0]->getFormat())

-            {

-                return false;

-            }

-

-            if(image[face][level]->getType() != image[0][0]->getType())

-            {

-                return false;

-            }

-

-            if(image[face][level]->getWidth() != std::max(1, size >> level))

-            {

-                return false;

-            }

-        }

-    }

-

-    return true;

-}

-

-bool TextureCubeMap::isCompressed(GLenum target, GLint level) const

-{

-    return IsCompressed(getFormat(target, level));

-}

-

-bool TextureCubeMap::isDepth(GLenum target, GLint level) const

-{

-    return IsDepthTexture(getFormat(target, level));

-}

-

-void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->unbind();

-	}

-

-	image[face][level] = new Image(this, width, height, format, type);

-

-	if(!image[face][level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setImage(format, type, unpackAlignment, pixels, image[face][level]);

-}

-

-void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->unbind();

-	}

-

-	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[face][level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    if(width != 0 && height != 0)

-    {

-		sw::Rect sourceRect = {x, y, x + width, y + height};

-		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-        

-        copy(renderTarget, sourceRect, format, 0, 0, image[face][level]);

-    }

-

-	renderTarget->release();

-}

-

-Image *TextureCubeMap::getImage(int face, unsigned int level)

-{

-	return image[face][level];

-}

-

-Image *TextureCubeMap::getImage(GLenum face, unsigned int level)

-{

-    return image[CubeFaceIndex(face)][level];

-}

-

-void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	int face = CubeFaceIndex(target);

-

-	if(!image[face][level])

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    GLsizei size = image[face][level]->getWidth();

-

-    if(xoffset + width > size || yoffset + height > size)

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	sw::Rect sourceRect = {x, y, x + width, y + height};

-	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-

-	copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, image[face][level]);

-

-	renderTarget->release();

-}

-

-void TextureCubeMap::generateMipmaps()

-{

-    if(!isCubeComplete())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    unsigned int q = log2(image[0][0]->getWidth());

-

-	for(unsigned int f = 0; f < 6; f++)

-    {

-		for(unsigned int i = 1; i <= q; i++)

-		{

-			if(image[f][i])

-			{

-				image[f][i]->unbind();

-			}

-

-			image[f][i] = new Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());

-

-			if(!image[f][i])

-			{

-				return error(GL_OUT_OF_MEMORY);

-			}

-

-			getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, true);

-		}

-	}

-}

-

-Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)

-{

-    if(!IsCubemapTextureTarget(target))

-    {

-        return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);

-    }

-

-    int face = CubeFaceIndex(target);

-

-    if(mFaceProxies[face] == NULL)

-    {

-        mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target));

-    }

-

-    return mFaceProxies[face];

-}

-

-Image *TextureCubeMap::getRenderTarget(GLenum target, unsigned int level)

-{

-    ASSERT(IsCubemapTextureTarget(target));

-    ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-    

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->addRef();

-	}

-

-	return image[face][level];

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Texture.cpp: Implements the Texture class and its derived classes
+// Texture2D and TextureCubeMap. Implements GL texture objects and related
+// functionality.
+
+#include "Texture.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "Framebuffer.h"
+#include "Device.hpp"
+#include "Display.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+namespace gl
+{
+
+Texture::Texture(GLuint name) : NamedObject(name)
+{
+	mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
+	mMagFilter = GL_LINEAR;
+	mWrapS = GL_REPEAT;
+	mWrapT = GL_REPEAT;
+	mMaxAnisotropy = 1.0f;
+	mMaxLevel = 1000;
+
+	resource = new sw::Resource(0);
+}
+
+Texture::~Texture()
+{
+	resource->destruct();
+}
+
+sw::Resource *Texture::getResource() const
+{
+	return resource;
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMinFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		mMinFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMagFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		mMagFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapS(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_CLAMP:
+	case GL_REPEAT:
+	case GL_CLAMP_TO_EDGE:
+	case GL_MIRRORED_REPEAT:
+		mWrapS = wrap;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapT(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_CLAMP:
+	case GL_REPEAT:
+	case GL_CLAMP_TO_EDGE:
+	case GL_MIRRORED_REPEAT:
+		 mWrapT = wrap;
+		 return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful max anisotropy update (valid anisotropy value)
+bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)
+{
+	textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);
+
+	if(textureMaxAnisotropy < 1.0f)
+	{
+		return false;
+	}
+
+	if(mMaxAnisotropy != textureMaxAnisotropy)
+	{
+		mMaxAnisotropy = textureMaxAnisotropy;
+	}
+
+	return true;
+}
+
+bool Texture::setMaxLevel(int level)
+{
+	if(level < 0)
+	{
+		return false;
+	}
+
+	mMaxLevel = level;
+
+	return true;
+}
+
+GLenum Texture::getMinFilter() const
+{
+	return mMinFilter;
+}
+
+GLenum Texture::getMagFilter() const
+{
+	return mMagFilter;
+}
+
+GLenum Texture::getWrapS() const
+{
+	return mWrapS;
+}
+
+GLenum Texture::getWrapT() const
+{
+	return mWrapT;
+}
+
+GLfloat Texture::getMaxAnisotropy() const
+{
+	return mMaxAnisotropy;
+}
+
+void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)
+{
+	if(pixels && image)
+	{
+		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackAlignment, pixels);
+	}
+}
+
+void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
+{
+	if(pixels && image)
+	{
+		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);
+	}
+}
+
+void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(IsCompressed(image->getFormat()))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackAlignment, pixels);
+	}
+}
+
+void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);
+	}
+}
+
+bool Texture::copy(Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, Image *dest)
+{
+	Device *device = getDevice();
+
+	sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), 0);
+	sw::SliceRect sourceSliceRect(sourceRect);
+	bool success = device->stretchRect(source, &sourceSliceRect, dest, &destRect, false);
+
+	if(!success)
+	{
+		return error(GL_OUT_OF_MEMORY, false);
+	}
+
+	return true;
+}
+
+bool Texture::isMipmapFiltered() const
+{
+	switch(mMinFilter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		return false;
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		return true;
+	default: UNREACHABLE(mMinFilter);
+	}
+
+	return false;
+}
+
+Texture2D::Texture2D(GLuint name) : Texture(name)
+{
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		image[i] = 0;
+	}
+
+	mColorbufferProxy = nullptr;
+	mProxyRefs = 0;
+}
+
+Texture2D::~Texture2D()
+{
+	resource->lock(sw::DESTRUCT);
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i])
+		{
+			image[i]->unbind();
+			image[i] = 0;
+		}
+	}
+
+	resource->unlock();
+
+	mColorbufferProxy = nullptr;
+}
+
+// We need to maintain a count of references to renderbuffers acting as
+// proxies for this texture, so that we do not attempt to use a pointer
+// to a renderbuffer proxy which has been deleted.
+void Texture2D::addProxyRef(const Renderbuffer *proxy)
+{
+	mProxyRefs++;
+}
+
+void Texture2D::releaseProxy(const Renderbuffer *proxy)
+{
+	if(mProxyRefs > 0)
+	{
+		mProxyRefs--;
+	}
+
+	if(mProxyRefs == 0)
+	{
+		mColorbufferProxy = nullptr;
+	}
+}
+
+GLenum Texture2D::getTarget() const
+{
+	return GL_TEXTURE_2D;
+}
+
+GLsizei Texture2D::getWidth(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
+	return image[level] ? image[level]->getWidth() : 0;
+}
+
+GLsizei Texture2D::getHeight(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
+	return image[level] ? image[level]->getHeight() : 0;
+}
+
+GLenum Texture2D::getFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
+	return image[level] ? image[level]->getFormat() : GL_NONE;
+}
+
+GLenum Texture2D::getType(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
+	return image[level] ? image[level]->getType() : GL_NONE;
+}
+
+sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
+	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
+}
+
+int Texture2D::getLevelCount() const
+{
+	ASSERT(isSamplerComplete());
+	int levels = 0;
+
+	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	{
+		levels++;
+	}
+
+	return levels;
+}
+
+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->unbind();
+	}
+
+	image[level] = new Image(this, width, height, format, type);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setImage(format, type, unpackAlignment, pixels, image[level]);
+}
+
+void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->unbind();
+	}
+
+	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setCompressedImage(imageSize, pixels, image[level]);
+}
+
+void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);
+}
+
+void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+	Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);
+}
+
+void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(image[level])
+	{
+		image[level]->unbind();
+	}
+
+	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(width != 0 && height != 0)
+	{
+		sw::Rect sourceRect = {x, y, x + width, y + height};
+		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+		copy(renderTarget, sourceRect, format, 0, 0, image[level]);
+	}
+
+	renderTarget->release();
+}
+
+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	if(!image[level])
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	sw::Rect sourceRect = {x, y, x + width, y + height};
+	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);
+
+	renderTarget->release();
+}
+
+void Texture2D::setImage(Image *sharedImage)
+{
+	sharedImage->addRef();
+
+	if(image[0])
+	{
+		image[0]->unbind();
+	}
+
+	image[0] = sharedImage;
+}
+
+// Tests for 2D texture sampling completeness.
+bool Texture2D::isSamplerComplete() const
+{
+	if(!image[0])
+	{
+		return false;
+	}
+
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+
+	if(width <= 0 || height <= 0)
+	{
+		return false;
+	}
+
+	if(isMipmapFiltered())
+	{
+		if(!isMipmapComplete())
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// Tests for 2D texture (mipmap) completeness.
+bool Texture2D::isMipmapComplete() const
+{
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+
+	int q = log2(std::max(width, height));
+
+	for(int level = 1; level <= q && level <= mMaxLevel; level++)
+	{
+		if(!image[level])
+		{
+			return false;
+		}
+
+		if(image[level]->getFormat() != image[0]->getFormat())
+		{
+			return false;
+		}
+
+		if(image[level]->getType() != image[0]->getType())
+		{
+			return false;
+		}
+
+		if(image[level]->getWidth() != std::max(1, width >> level))
+		{
+			return false;
+		}
+
+		if(image[level]->getHeight() != std::max(1, height >> level))
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool Texture2D::isCompressed(GLenum target, GLint level) const
+{
+	return IsCompressed(getFormat(target, level));
+}
+
+bool Texture2D::isDepth(GLenum target, GLint level) const
+{
+	return IsDepthTexture(getFormat(target, level));
+}
+
+void Texture2D::generateMipmaps()
+{
+	if(!image[0])
+	{
+		return;   // FIXME: error?
+	}
+
+	unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+
+	for(unsigned int i = 1; i <= q; i++)
+	{
+		if(image[i])
+		{
+			image[i]->unbind();
+		}
+
+		image[i] = new Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
+
+		if(!image[i])
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+
+		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);
+	}
+}
+
+Image *Texture2D::getImage(unsigned int level)
+{
+	return image[level];
+}
+
+Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
+{
+	if(target != GL_TEXTURE_2D)
+	{
+		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
+	}
+
+	if(!mColorbufferProxy)
+	{
+		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));
+	}
+
+	return mColorbufferProxy;
+}
+
+Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(image[level])
+	{
+		image[level]->addRef();
+	}
+
+	return image[level];
+}
+
+TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
+{
+	for(int f = 0; f < 6; f++)
+	{
+		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+		{
+			image[f][i] = 0;
+		}
+	}
+
+	for(int f = 0; f < 6; f++)
+	{
+		mFaceProxies[f] = nullptr;
+		mFaceProxyRefs[f] = 0;
+	}
+}
+
+TextureCubeMap::~TextureCubeMap()
+{
+	resource->lock(sw::DESTRUCT);
+
+	for(int f = 0; f < 6; f++)
+	{
+		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+		{
+			if(image[f][i])
+			{
+				image[f][i]->unbind();
+				image[f][i] = 0;
+			}
+		}
+	}
+
+	resource->unlock();
+
+	for(int i = 0; i < 6; i++)
+	{
+		mFaceProxies[i] = nullptr;
+	}
+}
+
+// We need to maintain a count of references to renderbuffers acting as
+// proxies for this texture, so that the texture is not deleted while
+// proxy references still exist. If the reference count drops to zero,
+// we set our proxy pointer null, so that a new attempt at referencing
+// will cause recreation.
+void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)
+{
+	for(int f = 0; f < 6; f++)
+	{
+		if(mFaceProxies[f] == proxy)
+		{
+			mFaceProxyRefs[f]++;
+		}
+	}
+}
+
+void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)
+{
+	for(int f = 0; f < 6; f++)
+	{
+		if(mFaceProxies[f] == proxy)
+		{
+			if(mFaceProxyRefs[f] > 0)
+			{
+				mFaceProxyRefs[f]--;
+			}
+
+			if(mFaceProxyRefs[f] == 0)
+			{
+				mFaceProxies[f] = nullptr;
+			}
+		}
+	}
+}
+
+GLenum TextureCubeMap::getTarget() const
+{
+	return GL_TEXTURE_CUBE_MAP;
+}
+
+GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getWidth() : 0;
+}
+
+GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getHeight() : 0;
+}
+
+GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getFormat() : GL_NONE;
+}
+
+GLenum TextureCubeMap::getType(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getType() : GL_NONE;
+}
+
+sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;
+}
+
+int TextureCubeMap::getLevelCount() const
+{
+	ASSERT(isSamplerComplete());
+	int levels = 0;
+
+	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][levels])
+	{
+		levels++;
+	}
+
+	return levels;
+}
+
+void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->unbind();
+	}
+
+	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[face][level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setCompressedImage(imageSize, pixels, image[face][level]);
+}
+
+void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[CubeFaceIndex(target)][level]);
+}
+
+void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+	Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);
+}
+
+// Tests for cube map sampling completeness.
+bool TextureCubeMap::isSamplerComplete() const
+{
+	for(int face = 0; face < 6; face++)
+	{
+		if(!image[face][0])
+		{
+			return false;
+		}
+	}
+
+	int size = image[0][0]->getWidth();
+
+	if(size <= 0)
+	{
+		return false;
+	}
+
+	if(!isMipmapFiltered())
+	{
+		if(!isCubeComplete())
+		{
+			return false;
+		}
+	}
+	else
+	{
+		if(!isMipmapCubeComplete())   // Also tests for isCubeComplete()
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// Tests for cube texture completeness.
+bool TextureCubeMap::isCubeComplete() const
+{
+	if(image[0][0]->getWidth() <= 0 || image[0][0]->getHeight() != image[0][0]->getWidth())
+	{
+		return false;
+	}
+
+	for(unsigned int face = 1; face < 6; face++)
+	{
+		if(image[face][0]->getWidth()  != image[0][0]->getWidth() ||
+		   image[face][0]->getWidth()  != image[0][0]->getHeight() ||
+		   image[face][0]->getFormat() != image[0][0]->getFormat() ||
+		   image[face][0]->getType()   != image[0][0]->getType())
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool TextureCubeMap::isMipmapCubeComplete() const
+{
+	if(!isCubeComplete())
+	{
+		return false;
+	}
+
+	GLsizei size = image[0][0]->getWidth();
+	int q = log2(size);
+
+	for(int face = 0; face < 6; face++)
+	{
+		for(int level = 1; level <= q; level++)
+		{
+			if(!image[face][level])
+			{
+				return false;
+			}
+
+			if(image[face][level]->getFormat() != image[0][0]->getFormat())
+			{
+				return false;
+			}
+
+			if(image[face][level]->getType() != image[0][0]->getType())
+			{
+				return false;
+			}
+
+			if(image[face][level]->getWidth() != std::max(1, size >> level))
+			{
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
+{
+	return IsCompressed(getFormat(target, level));
+}
+
+bool TextureCubeMap::isDepth(GLenum target, GLint level) const
+{
+	return IsDepthTexture(getFormat(target, level));
+}
+
+void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->unbind();
+	}
+
+	image[face][level] = new Image(this, width, height, format, type);
+
+	if(!image[face][level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setImage(format, type, unpackAlignment, pixels, image[face][level]);
+}
+
+void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->unbind();
+	}
+
+	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[face][level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(width != 0 && height != 0)
+	{
+		sw::Rect sourceRect = {x, y, x + width, y + height};
+		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+		copy(renderTarget, sourceRect, format, 0, 0, image[face][level]);
+	}
+
+	renderTarget->release();
+}
+
+Image *TextureCubeMap::getImage(int face, unsigned int level)
+{
+	return image[face][level];
+}
+
+Image *TextureCubeMap::getImage(GLenum face, unsigned int level)
+{
+	return image[CubeFaceIndex(face)][level];
+}
+
+void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	int face = CubeFaceIndex(target);
+
+	if(!image[face][level])
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	GLsizei size = image[face][level]->getWidth();
+
+	if(xoffset + width > size || yoffset + height > size)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	sw::Rect sourceRect = {x, y, x + width, y + height};
+	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+	copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, image[face][level]);
+
+	renderTarget->release();
+}
+
+void TextureCubeMap::generateMipmaps()
+{
+	if(!isCubeComplete())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	unsigned int q = log2(image[0][0]->getWidth());
+
+	for(unsigned int f = 0; f < 6; f++)
+	{
+		for(unsigned int i = 1; i <= q; i++)
+		{
+			if(image[f][i])
+			{
+				image[f][i]->unbind();
+			}
+
+			image[f][i] = new Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());
+
+			if(!image[f][i])
+			{
+				return error(GL_OUT_OF_MEMORY);
+			}
+
+			getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, true);
+		}
+	}
+}
+
+Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
+{
+	if(!IsCubemapTextureTarget(target))
+	{
+		return error(GL_INVALID_OPERATION, (Renderbuffer *)nullptr);
+	}
+
+	int face = CubeFaceIndex(target);
+
+	if(!mFaceProxies[face])
+	{
+		mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target));
+	}
+
+	return mFaceProxies[face];
+}
+
+Image *TextureCubeMap::getRenderTarget(GLenum target, unsigned int level)
+{
+	ASSERT(IsCubemapTextureTarget(target));
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->addRef();
+	}
+
+	return image[face][level];
+}
+
+}
diff --git a/src/OpenGL/libGL/Texture.h b/src/OpenGL/libGL/Texture.h
index 327aca3..ed124c8 100644
--- a/src/OpenGL/libGL/Texture.h
+++ b/src/OpenGL/libGL/Texture.h
@@ -1,220 +1,223 @@
-// 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.

-//

-

-// Texture.h: Defines the abstract Texture class and its concrete derived

-// classes Texture2D and TextureCubeMap. Implements GL texture objects and

-// related functionality.

-

-#ifndef LIBGL_TEXTURE_H_

-#define LIBGL_TEXTURE_H_

-

-#include "Renderbuffer.h"

-#include "common/Object.hpp"

-#include "utilities.h"

-#include "common/debug.h"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#include <vector>

-

-namespace gl

-{

-class Surface;

-class Config;

-class Framebuffer;

-

-enum

-{

-	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,

-    IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,

-};

-

-class Texture : public NamedObject

-{

-public:

-    explicit Texture(GLuint name);

-

-    virtual ~Texture();

-

-	sw::Resource *getResource() const;

-

-	virtual void addProxyRef(const Renderbuffer *proxy) = 0;

-    virtual void releaseProxy(const Renderbuffer *proxy) = 0;

-

-    virtual GLenum getTarget() const = 0;

-

-    bool setMinFilter(GLenum filter);

-    bool setMagFilter(GLenum filter);

-    bool setWrapS(GLenum wrap);

-    bool setWrapT(GLenum wrap);

-	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);

-	bool setMaxLevel(int level);

-

-    GLenum getMinFilter() const;

-    GLenum getMagFilter() const;

-    GLenum getWrapS() const;

-    GLenum getWrapT() const;

-	GLfloat getMaxAnisotropy() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const = 0;

-    virtual GLsizei getHeight(GLenum target, GLint level) const = 0;

-    virtual GLenum getFormat(GLenum target, GLint level) const = 0;

-    virtual GLenum getType(GLenum target, GLint level) const = 0;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;

-	virtual int getLevelCount() const = 0;

-

-    virtual bool isSamplerComplete() const = 0;

-    virtual bool isCompressed(GLenum target, GLint level) const = 0;

-	virtual bool isDepth(GLenum target, GLint level) const = 0;

-

-    virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;

-    virtual Image *getRenderTarget(GLenum target, unsigned int level) = 0;

-

-    virtual void generateMipmaps() = 0;

-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

-

-protected:

-    void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);

-    void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);

-    void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);

-    void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);

-

-	bool copy(Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, Image *dest);

-

-	bool isMipmapFiltered() const;

-

-    GLenum mMinFilter;

-    GLenum mMagFilter;

-    GLenum mWrapS;

-    GLenum mWrapT;

-	GLfloat mMaxAnisotropy;

-	GLint mMaxLevel;

-

-	sw::Resource *resource;

-};

-

-class Texture2D : public Texture

-{

-public:

-    explicit Texture2D(GLuint name);

-

-    virtual ~Texture2D();

-

-	void addProxyRef(const Renderbuffer *proxy);

-    void releaseProxy(const Renderbuffer *proxy);

-

-    virtual GLenum getTarget() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const;

-    virtual GLsizei getHeight(GLenum target, GLint level) const;

-    virtual GLenum getFormat(GLenum target, GLint level) const;

-    virtual GLenum getType(GLenum target, GLint level) const;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

-	virtual int getLevelCount() const;

-

-    void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);

-    void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

-    void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-

-	void setImage(Image *image);

-

-    virtual bool isSamplerComplete() const;

-    virtual bool isCompressed(GLenum target, GLint level) const;

-	virtual bool isDepth(GLenum target, GLint level) const;

-

-    virtual void generateMipmaps();

-

-	virtual Renderbuffer *getRenderbuffer(GLenum target);

-    virtual Image *getRenderTarget(GLenum target, unsigned int level);

-

-    Image *getImage(unsigned int level);

-

-protected:

-	bool isMipmapComplete() const;

-

-	Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-

-	// A specific internal reference count is kept for colorbuffer proxy references,

-    // because, as the renderbuffer acting as proxy will maintain a binding pointer

-    // back to this texture, there would be a circular reference if we used a binding

-    // pointer here. This reference count will cause the pointer to be set to NULL if

-    // the count drops to zero, but will not cause deletion of the Renderbuffer.

-    Renderbuffer *mColorbufferProxy;

-    unsigned int mProxyRefs;

-};

-

-class TextureCubeMap : public Texture

-{

-public:

-    explicit TextureCubeMap(GLuint name);

-

-    virtual ~TextureCubeMap();

-

-	void addProxyRef(const Renderbuffer *proxy);

-    void releaseProxy(const Renderbuffer *proxy);

-

-    virtual GLenum getTarget() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const;

-    virtual GLsizei getHeight(GLenum target, GLint level) const;

-    virtual GLenum getFormat(GLenum target, GLint level) const;

-    virtual GLenum getType(GLenum target, GLint level) const;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

-	virtual int getLevelCount() const;

-

-	void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);

-

-    void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

-    void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-

-    virtual bool isSamplerComplete() const;

-    virtual bool isCompressed(GLenum target, GLint level) const;

-	virtual bool isDepth(GLenum target, GLint level) const;

-

-    virtual void generateMipmaps();

-

-    virtual Renderbuffer *getRenderbuffer(GLenum target);

-	virtual Image *getRenderTarget(GLenum target, unsigned int level);

-

-	Image *getImage(int face, unsigned int level);

-

-private:

-	bool isCubeComplete() const;

-	bool isMipmapCubeComplete() const;

-

-    // face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns NULL on failure.

-    Image *getImage(GLenum face, unsigned int level);

-

-    Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-

-	// A specific internal reference count is kept for colorbuffer proxy references,

-    // because, as the renderbuffer acting as proxy will maintain a binding pointer

-    // back to this texture, there would be a circular reference if we used a binding

-    // pointer here. This reference count will cause the pointer to be set to NULL if

-    // the count drops to zero, but will not cause deletion of the Renderbuffer.

-    Renderbuffer *mFaceProxies[6];

-	unsigned int mFaceProxyRefs[6];

-};

-

-}

-

-#endif   // LIBGL_TEXTURE_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Texture.h: Defines the abstract Texture class and its concrete derived
+// classes Texture2D and TextureCubeMap. Implements GL texture objects and
+// related functionality.
+
+#ifndef LIBGL_TEXTURE_H_
+#define LIBGL_TEXTURE_H_
+
+#include "Renderbuffer.h"
+#include "common/Object.hpp"
+#include "utilities.h"
+#include "common/debug.h"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#include <vector>
+
+namespace gl
+{
+class Surface;
+class Config;
+class Framebuffer;
+
+enum
+{
+	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
+	IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,
+};
+
+class Texture : public NamedObject
+{
+public:
+	explicit Texture(GLuint name);
+
+	virtual ~Texture();
+
+	sw::Resource *getResource() const;
+
+	virtual void addProxyRef(const Renderbuffer *proxy) = 0;
+	virtual void releaseProxy(const Renderbuffer *proxy) = 0;
+
+	virtual GLenum getTarget() const = 0;
+
+	bool setMinFilter(GLenum filter);
+	bool setMagFilter(GLenum filter);
+	bool setWrapS(GLenum wrap);
+	bool setWrapT(GLenum wrap);
+	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);
+	bool setMaxLevel(int level);
+
+	GLenum getMinFilter() const;
+	GLenum getMagFilter() const;
+	GLenum getWrapS() const;
+	GLenum getWrapT() const;
+	GLfloat getMaxAnisotropy() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
+	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
+	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
+	virtual GLenum getType(GLenum target, GLint level) const = 0;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
+	virtual int getLevelCount() const = 0;
+
+	virtual bool isSamplerComplete() const = 0;
+	virtual bool isCompressed(GLenum target, GLint level) const = 0;
+	virtual bool isDepth(GLenum target, GLint level) const = 0;
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
+	virtual Image *getRenderTarget(GLenum target, unsigned int level) = 0;
+
+	virtual void generateMipmaps() = 0;
+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
+
+protected:
+	void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
+	void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
+	void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
+	void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
+
+	bool copy(Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, Image *dest);
+
+	bool isMipmapFiltered() const;
+
+	GLenum mMinFilter;
+	GLenum mMagFilter;
+	GLenum mWrapS;
+	GLenum mWrapT;
+	GLfloat mMaxAnisotropy;
+	GLint mMaxLevel;
+
+	sw::Resource *resource;
+};
+
+class Texture2D : public Texture
+{
+public:
+	explicit Texture2D(GLuint name);
+
+	virtual ~Texture2D();
+
+	void addProxyRef(const Renderbuffer *proxy);
+	void releaseProxy(const Renderbuffer *proxy);
+
+	virtual GLenum getTarget() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const;
+	virtual GLsizei getHeight(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const;
+	virtual GLenum getType(GLenum target, GLint level) const;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
+	virtual int getLevelCount() const;
+
+	void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+	void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+
+	void setImage(Image *image);
+
+	virtual bool isSamplerComplete() const;
+	virtual bool isCompressed(GLenum target, GLint level) const;
+	virtual bool isDepth(GLenum target, GLint level) const;
+
+	virtual void generateMipmaps();
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target);
+	virtual Image *getRenderTarget(GLenum target, unsigned int level);
+
+	Image *getImage(unsigned int level);
+
+protected:
+	bool isMipmapComplete() const;
+
+	Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+	// A specific internal reference count is kept for colorbuffer proxy references,
+	// because, as the renderbuffer acting as proxy will maintain a binding pointer
+	// back to this texture, there would be a circular reference if we used a binding
+	// pointer here. This reference count will cause the pointer to be set to null if
+	// the count drops to zero, but will not cause deletion of the Renderbuffer.
+	Renderbuffer *mColorbufferProxy;
+	unsigned int mProxyRefs;
+};
+
+class TextureCubeMap : public Texture
+{
+public:
+	explicit TextureCubeMap(GLuint name);
+
+	virtual ~TextureCubeMap();
+
+	void addProxyRef(const Renderbuffer *proxy);
+	void releaseProxy(const Renderbuffer *proxy);
+
+	virtual GLenum getTarget() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const;
+	virtual GLsizei getHeight(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const;
+	virtual GLenum getType(GLenum target, GLint level) const;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
+	virtual int getLevelCount() const;
+
+	void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+
+	void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+	void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+
+	virtual bool isSamplerComplete() const;
+	virtual bool isCompressed(GLenum target, GLint level) const;
+	virtual bool isDepth(GLenum target, GLint level) const;
+
+	virtual void generateMipmaps();
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target);
+	virtual Image *getRenderTarget(GLenum target, unsigned int level);
+
+	Image *getImage(int face, unsigned int level);
+
+private:
+	bool isCubeComplete() const;
+	bool isMipmapCubeComplete() const;
+
+	// face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure.
+	Image *getImage(GLenum face, unsigned int level);
+
+	Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+	// A specific internal reference count is kept for colorbuffer proxy references,
+	// because, as the renderbuffer acting as proxy will maintain a binding pointer
+	// back to this texture, there would be a circular reference if we used a binding
+	// pointer here. This reference count will cause the pointer to be set to null if
+	// the count drops to zero, but will not cause deletion of the Renderbuffer.
+	Renderbuffer *mFaceProxies[6];
+	unsigned int mFaceProxyRefs[6];
+};
+
+}
+
+#endif   // LIBGL_TEXTURE_H_
diff --git a/src/OpenGL/libGL/VertexDataManager.cpp b/src/OpenGL/libGL/VertexDataManager.cpp
index 7481359..1520ed0 100644
--- a/src/OpenGL/libGL/VertexDataManager.cpp
+++ b/src/OpenGL/libGL/VertexDataManager.cpp
@@ -1,334 +1,337 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#include "VertexDataManager.h"

-

-#include "Buffer.h"

-#include "Program.h"

-#include "IndexDataManager.h"

-#include "common/debug.h"

-

-namespace

-{

-    enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};

-}

-

-namespace gl

-{

-

-VertexDataManager::VertexDataManager(Context *context) : mContext(context)

-{

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        mDirtyCurrentValue[i] = true;

-        mCurrentValueBuffer[i] = NULL;

-    }

-

-    mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming vertex buffer.");

-    }

-}

-

-VertexDataManager::~VertexDataManager()

-{

-    delete mStreamingBuffer;

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        delete mCurrentValueBuffer[i];

-    }

-}

-

-unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)

-{

-    Buffer *buffer = attribute.mBoundBuffer;

-

-    int inputStride = attribute.stride();

-    int elementSize = attribute.typeSize();

-    unsigned int streamOffset = 0;

-

-    char *output = nullptr;

-

-    if(vertexBuffer)

-    {

-        output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);

-    }

-

-    if(!output)

-    {

-        ERR("Failed to map vertex buffer.");

-        return ~0u;

-    }

-

-    const char *input = nullptr;

-

-    if(buffer)

-    {

-        int offset = attribute.mOffset;

-

-        input = static_cast<const char*>(buffer->data()) + offset;

-    }

-    else

-    {

-        input = static_cast<const char*>(attribute.mPointer);

-    }

-

-    input += inputStride * start;

-

-    if(inputStride == elementSize)

-    {

-        memcpy(output, input, count * inputStride);

-    }

-    else

-    {

-		for(int i = 0; i < count; i++)

-		{

-			memcpy(output, input, elementSize);

-			output += elementSize;

-			input += inputStride;

-		}

-    }

-

-    vertexBuffer->unmap();

-

-    return streamOffset;

-}

-

-GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-    const VertexAttributeArray &attribs = mContext->getVertexAttributes();

-    Program *program = mContext->getCurrentProgram();

-

-    // Determine the required storage size per used buffer

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        if(!program || program->getAttributeStream(i) != -1)

-        {

-            if(attribs[i].mArrayEnabled)

-            {

-                if(!attribs[i].mBoundBuffer)

-                {

-                    mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);

-                }

-            }

-        }

-    }

-

-    mStreamingBuffer->reserveRequiredSpace();

-

-    // Perform the vertex data translations

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        if(!program || program->getAttributeStream(i) != -1)

-        {

-            if(attribs[i].mArrayEnabled)

-            {

-                Buffer *buffer = attribs[i].mBoundBuffer;

-

-                if(!buffer && attribs[i].mPointer == NULL)

-                {

-                    // This is an application error that would normally result in a crash, but we catch it and return an error

-                    ERR("An enabled vertex array has no buffer and no pointer.");

-                    return GL_INVALID_OPERATION;

-                }

-

-                sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-                if(staticBuffer)

-                {

-					translated[i].vertexBuffer = staticBuffer;

-					translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;

-					translated[i].stride = attribs[i].stride();

-                }

-                else

-                {

-                    unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);

-

-					if(streamOffset == ~0u)

-					{

-						return GL_OUT_OF_MEMORY;

-					}

-

-					translated[i].vertexBuffer = mStreamingBuffer->getResource();

-					translated[i].offset = streamOffset;

-					translated[i].stride = attribs[i].typeSize();

-                }

-

-				switch(attribs[i].mType)

-				{

-				case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;

-				case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;

-				case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;

-				case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;

-				case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;

-				case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;

-				case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;

-				case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-				default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-				}

-

-				translated[i].count = attribs[i].mSize;

-				translated[i].normalized = attribs[i].mNormalized;

-            }

-            else

-            {

-                if(mDirtyCurrentValue[i])

-                {

-                    delete mCurrentValueBuffer[i];

-                    mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);

-                    mDirtyCurrentValue[i] = false;

-                }

-

-                translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();

-

-                translated[i].type = sw::STREAMTYPE_FLOAT;

-				translated[i].count = 4;

-                translated[i].stride = 0;

-                translated[i].offset = 0;

-            }

-        }

-    }

-

-    return GL_NO_ERROR;

-}

-

-VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(NULL)

-{

-    if(size > 0)

-    {

-        mVertexBuffer = new sw::Resource(size + 1024);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", size);

-        }

-    }

-}

-

-VertexBuffer::~VertexBuffer()

-{

-    if(mVertexBuffer)

-    {

-        mVertexBuffer->destruct();

-    }

-}

-

-void VertexBuffer::unmap()

-{

-    if(mVertexBuffer)

-    {

-		mVertexBuffer->unlock();

-    }

-}

-

-sw::Resource *VertexBuffer::getResource() const

-{

-    return mVertexBuffer;

-}

-

-ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))

-{

-    if(mVertexBuffer)

-    {

-		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);

-

-        vector[0] = x;

-        vector[1] = y;

-        vector[2] = z;

-        vector[3] = w;

-

-        mVertexBuffer->unlock();

-    }

-}

-

-ConstantVertexBuffer::~ConstantVertexBuffer()

-{

-}

-

-StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)

-{

-    mBufferSize = size;

-    mWritePosition = 0;

-    mRequiredSpace = 0;

-}

-

-StreamingVertexBuffer::~StreamingVertexBuffer()

-{

-}

-

-void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)

-{

-    mRequiredSpace += requiredSpace;

-}

-

-void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mVertexBuffer)

-    {

-		// We can use a private lock because we never overwrite the content

-		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingVertexBuffer::reserveRequiredSpace()

-{

-    if(mRequiredSpace > mBufferSize)

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-            mVertexBuffer = 0;

-        }

-

-        mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.

-

-		mVertexBuffer = new sw::Resource(mBufferSize);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-			mVertexBuffer = new sw::Resource(mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-

-    mRequiredSpace = 0;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#include "VertexDataManager.h"
+
+#include "Buffer.h"
+#include "Program.h"
+#include "IndexDataManager.h"
+#include "common/debug.h"
+
+namespace
+{
+	enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};
+}
+
+namespace gl
+{
+
+VertexDataManager::VertexDataManager(Context *context) : mContext(context)
+{
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mDirtyCurrentValue[i] = true;
+		mCurrentValueBuffer[i] = nullptr;
+	}
+
+	mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming vertex buffer.");
+	}
+}
+
+VertexDataManager::~VertexDataManager()
+{
+	delete mStreamingBuffer;
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		delete mCurrentValueBuffer[i];
+	}
+}
+
+unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
+{
+	Buffer *buffer = attribute.mBoundBuffer;
+
+	int inputStride = attribute.stride();
+	int elementSize = attribute.typeSize();
+	unsigned int streamOffset = 0;
+
+	char *output = nullptr;
+
+	if(vertexBuffer)
+	{
+		output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);
+	}
+
+	if(!output)
+	{
+		ERR("Failed to map vertex buffer.");
+		return ~0u;
+	}
+
+	const char *input = nullptr;
+
+	if(buffer)
+	{
+		int offset = attribute.mOffset;
+
+		input = static_cast<const char*>(buffer->data()) + offset;
+	}
+	else
+	{
+		input = static_cast<const char*>(attribute.mPointer);
+	}
+
+	input += inputStride * start;
+
+	if(inputStride == elementSize)
+	{
+		memcpy(output, input, count * inputStride);
+	}
+	else
+	{
+		for(int i = 0; i < count; i++)
+		{
+			memcpy(output, input, elementSize);
+			output += elementSize;
+			input += inputStride;
+		}
+	}
+
+	vertexBuffer->unmap();
+
+	return streamOffset;
+}
+
+GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	const VertexAttributeArray &attribs = mContext->getVertexAttributes();
+	Program *program = mContext->getCurrentProgram();
+
+	// Determine the required storage size per used buffer
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(!program || program->getAttributeStream(i) != -1)
+		{
+			if(attribs[i].mArrayEnabled)
+			{
+				if(!attribs[i].mBoundBuffer)
+				{
+					mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);
+				}
+			}
+		}
+	}
+
+	mStreamingBuffer->reserveRequiredSpace();
+
+	// Perform the vertex data translations
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(!program || program->getAttributeStream(i) != -1)
+		{
+			if(attribs[i].mArrayEnabled)
+			{
+				Buffer *buffer = attribs[i].mBoundBuffer;
+
+				if(!buffer && attribs[i].mPointer == nullptr)
+				{
+					// This is an application error that would normally result in a crash, but we catch it and return an error
+					ERR("An enabled vertex array has no buffer and no pointer.");
+					return GL_INVALID_OPERATION;
+				}
+
+				sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr;
+
+				if(staticBuffer)
+				{
+					translated[i].vertexBuffer = staticBuffer;
+					translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;
+					translated[i].stride = attribs[i].stride();
+				}
+				else
+				{
+					unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
+
+					if(streamOffset == ~0u)
+					{
+						return GL_OUT_OF_MEMORY;
+					}
+
+					translated[i].vertexBuffer = mStreamingBuffer->getResource();
+					translated[i].offset = streamOffset;
+					translated[i].stride = attribs[i].typeSize();
+				}
+
+				switch(attribs[i].mType)
+				{
+				case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;
+				case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;
+				case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;
+				case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;
+				case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;
+				case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;
+				case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;
+				case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+				default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+				}
+
+				translated[i].count = attribs[i].mSize;
+				translated[i].normalized = attribs[i].mNormalized;
+			}
+			else
+			{
+				if(mDirtyCurrentValue[i])
+				{
+					delete mCurrentValueBuffer[i];
+					mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
+					mDirtyCurrentValue[i] = false;
+				}
+
+				translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();
+
+				translated[i].type = sw::STREAMTYPE_FLOAT;
+				translated[i].count = 4;
+				translated[i].stride = 0;
+				translated[i].offset = 0;
+			}
+		}
+	}
+
+	return GL_NO_ERROR;
+}
+
+VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(nullptr)
+{
+	if(size > 0)
+	{
+		mVertexBuffer = new sw::Resource(size + 1024);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", size);
+		}
+	}
+}
+
+VertexBuffer::~VertexBuffer()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->destruct();
+	}
+}
+
+void VertexBuffer::unmap()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->unlock();
+	}
+}
+
+sw::Resource *VertexBuffer::getResource() const
+{
+	return mVertexBuffer;
+}
+
+ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))
+{
+	if(mVertexBuffer)
+	{
+		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);
+
+		vector[0] = x;
+		vector[1] = y;
+		vector[2] = z;
+		vector[3] = w;
+
+		mVertexBuffer->unlock();
+	}
+}
+
+ConstantVertexBuffer::~ConstantVertexBuffer()
+{
+}
+
+StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)
+{
+	mBufferSize = size;
+	mWritePosition = 0;
+	mRequiredSpace = 0;
+}
+
+StreamingVertexBuffer::~StreamingVertexBuffer()
+{
+}
+
+void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)
+{
+	mRequiredSpace += requiredSpace;
+}
+
+void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = nullptr;
+
+	if(mVertexBuffer)
+	{
+		// We can use a private lock because we never overwrite the content
+		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingVertexBuffer::reserveRequiredSpace()
+{
+	if(mRequiredSpace > mBufferSize)
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = 0;
+		}
+
+		mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
+
+		mVertexBuffer = new sw::Resource(mBufferSize);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = new sw::Resource(mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+
+	mRequiredSpace = 0;
+}
+
+}
diff --git a/src/OpenGL/libGL/VertexDataManager.h b/src/OpenGL/libGL/VertexDataManager.h
index b55b064..7f0a432 100644
--- a/src/OpenGL/libGL/VertexDataManager.h
+++ b/src/OpenGL/libGL/VertexDataManager.h
@@ -1,101 +1,104 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#ifndef LIBGL_VERTEXDATAMANAGER_H_

-#define LIBGL_VERTEXDATAMANAGER_H_

-

-#include "Context.h"

-#include "Device.hpp"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-

-struct TranslatedAttribute

-{

-    sw::StreamType type;

-	int count;

-	bool normalized;

-

-    unsigned int offset;

-    unsigned int stride;   // 0 means not to advance the read pointer at all

-

-    sw::Resource *vertexBuffer;

-};

-

-class VertexBuffer

-{

-  public:

-    VertexBuffer(unsigned int size);

-    virtual ~VertexBuffer();

-

-    void unmap();

-

-    sw::Resource *getResource() const;

-

-  protected:

-    sw::Resource *mVertexBuffer;

-};

-

-class ConstantVertexBuffer : public VertexBuffer

-{

-  public:

-    ConstantVertexBuffer(float x, float y, float z, float w);

-    ~ConstantVertexBuffer();

-};

-

-class StreamingVertexBuffer : public VertexBuffer

-{

-  public:

-    StreamingVertexBuffer(unsigned int size);

-    ~StreamingVertexBuffer();

-

-    void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);

-    void reserveRequiredSpace();

-    void addRequiredSpace(unsigned int requiredSpace);

-

-  protected:

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-    unsigned int mRequiredSpace;

-};

-

-class VertexDataManager

-{

-  public:

-    VertexDataManager(Context *context);

-    virtual ~VertexDataManager();

-

-    void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }

-

-    GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);

-

-  private:

-    unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);

-

-    Context *const mContext;

-

-    StreamingVertexBuffer *mStreamingBuffer;

-

-    bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];

-    ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];

-};

-

-}

-

-#endif   // LIBGL_VERTEXDATAMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#ifndef LIBGL_VERTEXDATAMANAGER_H_
+#define LIBGL_VERTEXDATAMANAGER_H_
+
+#include "Context.h"
+#include "Device.hpp"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+
+struct TranslatedAttribute
+{
+	sw::StreamType type;
+	int count;
+	bool normalized;
+
+	unsigned int offset;
+	unsigned int stride;   // 0 means not to advance the read pointer at all
+
+	sw::Resource *vertexBuffer;
+};
+
+class VertexBuffer
+{
+public:
+	VertexBuffer(unsigned int size);
+	virtual ~VertexBuffer();
+
+	void unmap();
+
+	sw::Resource *getResource() const;
+
+protected:
+	sw::Resource *mVertexBuffer;
+};
+
+class ConstantVertexBuffer : public VertexBuffer
+{
+public:
+	ConstantVertexBuffer(float x, float y, float z, float w);
+	~ConstantVertexBuffer();
+};
+
+class StreamingVertexBuffer : public VertexBuffer
+{
+public:
+	StreamingVertexBuffer(unsigned int size);
+	~StreamingVertexBuffer();
+
+	void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);
+	void reserveRequiredSpace();
+	void addRequiredSpace(unsigned int requiredSpace);
+
+protected:
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+	unsigned int mRequiredSpace;
+};
+
+class VertexDataManager
+{
+public:
+	VertexDataManager(Context *context);
+	virtual ~VertexDataManager();
+
+	void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
+
+	GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
+
+private:
+	unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
+
+	Context *const mContext;
+
+	StreamingVertexBuffer *mStreamingBuffer;
+
+	bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
+	ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
+};
+
+}
+
+#endif   // LIBGL_VERTEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGL/libGL.cpp b/src/OpenGL/libGL/libGL.cpp
index d72fb48..8c0d760 100644
--- a/src/OpenGL/libGL/libGL.cpp
+++ b/src/OpenGL/libGL/libGL.cpp
@@ -1,8286 +1,8289 @@
-// 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.

-//

-// libGL.cpp: Implements the exported OpenGL functions.

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "Buffer.h"

-#include "Context.h"

-#include "Fence.h"

-#include "Framebuffer.h"

-#include "Program.h"

-#include "Renderbuffer.h"

-#include "Shader.h"

-#include "Texture.h"

-#include "Query.h"

-#include "common/debug.h"

-#include "Common/Version.h"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#include <limits>

-

-using std::abs;

-

-static bool validImageSize(GLint level, GLsizei width, GLsizei height)

-{

-	if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)

-	{

-		return false;

-	}

-

-	return true;

-}

-

-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, gl::Texture *texture)

-{

-	if(!texture)

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed != texture->isCompressed(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(format != GL_NONE && format != texture->getFormat(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed)

-	{

-		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-		   (height % 4 != 0 && height != texture->getHeight(target, 0)))

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-	}

-

-	if(xoffset + width > texture->getWidth(target, level) ||

-	   yoffset + height > texture->getHeight(target, level))

-	{

-		return error(GL_INVALID_VALUE, false);

-	}

-

-	return true;

-}

-

-// Check for combinations of format and type that are valid for ReadPixels

-static bool validReadFormatType(GLenum format, GLenum type)

-{

-	switch(format)

-	{

-	case GL_RGBA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-			break;

-		default:

-			return false;

-		}

-		break;

-	case GL_BGRA_EXT:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_4_4_4_4_REV:

-		case GL_UNSIGNED_SHORT_1_5_5_5_REV:

-			break;

-		default:

-			return false;

-		}

-		break;

-	case gl::IMPLEMENTATION_COLOR_READ_FORMAT:

-		switch(type)

-		{

-		case gl::IMPLEMENTATION_COLOR_READ_TYPE:

-			break;

-		default:

-			return false;

-		}

-		break;

-	default:

-		return false;

-	}

-

-	return true;

-}

-

-extern "C"

-{

-

-void APIENTRY glActiveTexture(GLenum texture)

-{

-	TRACE("(GLenum texture = 0x%X)", texture);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		context->setActiveSampler(texture - GL_TEXTURE0);

-	}

-}

-

-void APIENTRY glAttachShader(GLuint program, GLuint shader)

-{

-	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(!programObject->attachShader(shaderObject))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)

-{

-	TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);

-

-	switch(target)

-	{

-	case GL_ANY_SAMPLES_PASSED:

-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(name == 0)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->beginQuery(target, name);

-	}

-}

-

-void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(strncmp(name, "gl_", 3) == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		programObject->bindAttributeLocation(index, name);

-	}

-}

-

-void APIENTRY glBindBuffer(GLenum target, GLuint buffer)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			context->bindArrayBuffer(buffer);

-			return;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			context->bindElementArrayBuffer(buffer);

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)

-{

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

-

-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)

-		{

-			context->bindReadFramebuffer(framebuffer);

-		}

-

-		if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)

-		{

-			context->bindDrawFramebuffer(framebuffer);

-		}

-	}

-}

-

-void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)

-{

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

-

-	if(target != GL_RENDERBUFFER)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->bindRenderbuffer(renderbuffer);

-	}

-}

-

-void APIENTRY glBindTexture(GLenum target, GLuint texture)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Texture *textureObject = context->getTexture(texture);

-

-		if(textureObject && textureObject->getTarget() != target && texture != 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			context->bindTexture2D(texture);

-			return;

-		case GL_TEXTURE_CUBE_MAP:

-			context->bindTextureCubeMap(texture);

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",

-		  red, green, blue, alpha);

-

-	gl::Context* context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));

-	}

-}

-

-void APIENTRY glBlendEquation(GLenum mode)

-{

-	glBlendEquationSeparate(mode, mode);

-}

-

-void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)

-{

-	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);

-

-	switch(modeRGB)

-	{

-	case GL_FUNC_ADD:

-	case GL_FUNC_SUBTRACT:

-	case GL_FUNC_REVERSE_SUBTRACT:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(modeAlpha)

-	{

-	case GL_FUNC_ADD:

-	case GL_FUNC_SUBTRACT:

-	case GL_FUNC_REVERSE_SUBTRACT:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setBlendEquation(modeRGB, modeAlpha);

-	}

-}

-

-void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)

-{

-	glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);

-}

-

-void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)

-{

-	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",

-	      srcRGB, dstRGB, srcAlpha, dstAlpha);

-

-	switch(srcRGB)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-	case GL_SRC_ALPHA_SATURATE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(dstRGB)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(srcAlpha)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-	case GL_SRC_ALPHA_SATURATE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(dstAlpha)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

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

-	}

-}

-

-void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)

-{

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

-	      target, size, data, usage);

-

-	if(size < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(usage)

-	{

-	case GL_STREAM_DRAW:

-	case GL_STATIC_DRAW:

-	case GL_DYNAMIC_DRAW:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-	}

-}

-

-void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)

-{

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

-	      target, offset, size, data);

-

-	if(size < 0 || offset < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(data == NULL)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if((size_t)size + offset > buffer->size())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

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

-	}

-}

-

-GLenum APIENTRY glCheckFramebufferStatus(GLenum target)

-{

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

-

-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)

-	{

-		return error(GL_INVALID_ENUM, 0);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Framebuffer *framebuffer = NULL;

-		if(target == GL_READ_FRAMEBUFFER_EXT)

-		{

-			framebuffer = context->getReadFramebuffer();

-		}

-		else

-		{

-			framebuffer = context->getDrawFramebuffer();

-		}

-

-		return framebuffer->completeness();

-	}

-

-	return 0;

-}

-

-void APIENTRY glClear(GLbitfield mask)

-{

-	TRACE("(GLbitfield mask = %X)", mask);

-

-	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			return context->listCommand(gl::newCommand(glClear, mask));

-		}

-

-		context->clear(mask);

-	}

-}

-

-void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",

-	      red, green, blue, alpha);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

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

-	}

-}

-

-void APIENTRY glClearDepthf(GLclampf depth)

-{

-	TRACE("(GLclampf depth = %f)", depth);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setClearDepth(depth);

-	}

-}

-

-void APIENTRY glClearStencil(GLint s)

-{

-	TRACE("(GLint s = %d)", s);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setClearStencil(s);

-	}

-}

-

-void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)

-{

-	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",

-	      red, green, blue, alpha);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);

-	}

-}

-

-void APIENTRY glCompileShader(GLuint shader)

-{

-	TRACE("(GLuint shader = %d)", shader);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		shaderObject->compile();

-	}

-}

-

-void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                                        GLint border, GLsizei imageSize, const GLvoid* data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "

-	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",

-	      target, level, internalformat, width, height, border, imageSize, data);

-

-	if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(internalformat)

-	{

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:

-		if(!S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_DEPTH_COMPONENT:

-	case GL_DEPTH_COMPONENT16:

-	case GL_DEPTH_COMPONENT32:

-	case GL_DEPTH_STENCIL_EXT:

-	case GL_DEPTH24_STENCIL8_EXT:

-		return error(GL_INVALID_OPERATION);

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-			if(width != height)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||

-			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			gl::Texture2D *texture = context->getTexture2D(target);

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);

-		}

-		else

-		{

-			gl::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			switch(target)

-			{

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

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

-				break;

-			default: UNREACHABLE(target);

-			}

-		}

-	}

-}

-

-void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                                           GLenum format, GLsizei imageSize, const GLvoid* data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "

-	      "GLsizei imageSize = %d, const GLvoid* data = %p)",

-	      target, level, xoffset, yoffset, width, height, format, imageSize, data);

-

-	if(!gl::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(format)

-	{

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:

-		if(!S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width == 0 || height == 0 || data == NULL)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(imageSize != gl::ComputeCompressedSize(width, height, format))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(xoffset % 4 != 0 || yoffset % 4 != 0)

-		{

-			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			gl::Texture2D *texture = context->getTexture2D(target);

-

-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))

-			{

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

-			}

-		}

-		else if(gl::IsCubemapTextureTarget(target))

-		{

-			gl::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))

-			{

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

-			}

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "

-	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",

-	      target, level, internalformat, x, y, width, height, border);

-

-	if(!validImageSize(level, width, height))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-			if(width != height)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||

-			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		gl::Framebuffer *framebuffer = context->getReadFramebuffer();

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-		}

-

-		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-		GLenum colorbufferFormat = source->getFormat();

-

-		switch(internalformat)

-		{

-		case GL_ALPHA:

-			if(colorbufferFormat != GL_ALPHA &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_EXT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE:

-		case GL_RGB:

-			if(colorbufferFormat != GL_RGB &&

-			   colorbufferFormat != GL_RGB565 &&

-			   colorbufferFormat != GL_RGB8_EXT &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_EXT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE_ALPHA:

-		case GL_RGBA:

-			if(colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4 &&

-			   colorbufferFormat != GL_RGB5_A1 &&

-			   colorbufferFormat != GL_RGBA8_EXT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:

-			if(S3TC_SUPPORT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			gl::Texture2D *texture = context->getTexture2D(target);

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);

-		}

-		else if(gl::IsCubemapTextureTarget(target))

-		{

-			gl::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

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

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",

-	      target, level, xoffset, yoffset, x, y, width, height);

-

-	if(!gl::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(width == 0 || height == 0)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		gl::Framebuffer *framebuffer = context->getReadFramebuffer();

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-		}

-

-		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		gl::Texture *texture = NULL;

-

-		if(target == GL_TEXTURE_2D)

-		{

-			texture = context->getTexture2D(target);

-		}

-		else if(gl::IsCubemapTextureTarget(target))

-		{

-			texture = context->getTextureCubeMap();

-		}

-		else UNREACHABLE(target);

-

-		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))

-		{

-			return;

-		}

-

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

-	}

-}

-

-GLuint APIENTRY glCreateProgram(void)

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		return context->createProgram();

-	}

-

-	return 0;

-}

-

-GLuint APIENTRY glCreateShader(GLenum type)

-{

-	TRACE("(GLenum type = 0x%X)", type);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		switch(type)

-		{

-		case GL_FRAGMENT_SHADER:

-		case GL_VERTEX_SHADER:

-			return context->createShader(type);

-		default:

-			return error(GL_INVALID_ENUM, 0);

-		}

-	}

-

-	return 0;

-}

-

-void APIENTRY glCullFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		{

-			gl::Context *context = gl::getContext();

-

-			if(context)

-			{

-				context->setCullMode(mode);

-			}

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteBuffer(buffers[i]);

-		}

-	}

-}

-

-void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)

-{

-	TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteFence(fences[i]);

-		}

-	}

-}

-

-void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		for(int i = 0; i < n; i++)

-		{

-			if(framebuffers[i] != 0)

-			{

-				context->deleteFramebuffer(framebuffers[i]);

-			}

-		}

-	}

-}

-

-void APIENTRY glDeleteProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	if(program == 0)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(!context->getProgram(program))

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		context->deleteProgram(program);

-	}

-}

-

-void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)

-{

-	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteQuery(ids[i]);

-		}

-	}

-}

-

-void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteRenderbuffer(renderbuffers[i]);

-		}

-	}

-}

-

-void APIENTRY glDeleteShader(GLuint shader)

-{

-	TRACE("(GLuint shader = %d)", shader);

-

-	if(shader == 0)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(!context->getShader(shader))

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		context->deleteShader(shader);

-	}

-}

-

-void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			if(textures[i] != 0)

-			{

-				context->deleteTexture(textures[i]);

-			}

-		}

-	}

-}

-

-void APIENTRY glDepthFunc(GLenum func)

-{

-	TRACE("(GLenum func = 0x%X)", func);

-

-	switch(func)

-	{

-	case GL_NEVER:

-	case GL_ALWAYS:

-	case GL_LESS:

-	case GL_LEQUAL:

-	case GL_EQUAL:

-	case GL_GREATER:

-	case GL_GEQUAL:

-	case GL_NOTEQUAL:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setDepthFunc(func);

-	}

-}

-

-void APIENTRY glDepthMask(GLboolean flag)

-{

-	TRACE("(GLboolean flag = %d)", flag);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setDepthMask(flag != GL_FALSE);

-	}

-}

-

-void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)

-{

-	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setDepthRange(zNear, zFar);

-	}

-}

-

-void APIENTRY glDetachShader(GLuint program, GLuint shader)

-{

-	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(!programObject)

-		{

-			gl::Shader *shaderByProgramHandle;

-			shaderByProgramHandle = context->getShader(program);

-			if(!shaderByProgramHandle)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		}

-

-		if(!shaderObject)

-		{

-			gl::Program *programByShaderHandle = context->getProgram(shader);

-			if(!programByShaderHandle)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		}

-

-		if(!programObject->detachShader(shaderObject))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glDisable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		switch(cap)

-		{

-		case GL_CULL_FACE:                context->setCullFaceEnabled(false);              break;

-		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(false);     break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;

-		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(false);        break;

-		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(false);           break;

-		case GL_STENCIL_TEST:             context->setStencilTestEnabled(false);           break;

-		case GL_DEPTH_TEST:               context->setDepthTestEnabled(false);             break;

-		case GL_BLEND:                    context->setBlendEnabled(false);                 break;

-		case GL_DITHER:                   context->setDitherEnabled(false);                break;

-		case GL_LIGHTING:                 context->setLightingEnabled(false);              break;

-		case GL_FOG:                      context->setFogEnabled(false);                   break;

-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;

-		case GL_TEXTURE_2D:               context->setTexture2DEnabled(false);             break;

-		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;

-		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;

-		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;

-		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;

-		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;

-		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;

-		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;

-		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;

-		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;

-		case GL_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(false);      break;

-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;

-		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glDisableVertexAttribArray(GLuint index)

-{

-	TRACE("(GLuint index = %d)", index);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribArrayEnabled(index, false);

-	}

-}

-

-void APIENTRY glCaptureAttribs()

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->captureAttribs();

-	}

-}

-

-void APIENTRY glRestoreAttribs()

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->restoreAttribs();

-	}

-}

-

-void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)

-{

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

-

-	if(count < 0 || first < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE);   // UNIMPLEMENTED!

-

-			context->listCommand(gl::newCommand(glCaptureAttribs));

-			context->captureDrawArrays(mode, first, count);

-			context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));

-			context->listCommand(gl::newCommand(glRestoreAttribs));

-

-			return;

-		}

-

-		context->drawArrays(mode, first, count);

-	}

-}

-

-void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)

-{

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

-	      mode, count, type, indices);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT:

-		case GL_UNSIGNED_INT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

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

-	}

-}

-

-void APIENTRY glEnable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		switch(cap)

-		{

-		case GL_CULL_FACE:                context->setCullFaceEnabled(true);              break;

-		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(true);     break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;

-		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(true);        break;

-		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(true);           break;

-		case GL_STENCIL_TEST:             context->setStencilTestEnabled(true);           break;

-		case GL_DEPTH_TEST:               context->setDepthTestEnabled(true);             break;

-		case GL_BLEND:                    context->setBlendEnabled(true);                 break;

-		case GL_DITHER:                   context->setDitherEnabled(true);                break;

-		case GL_TEXTURE_2D:               context->setTexture2DEnabled(true);             break;

-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;

-		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;

-		case GL_FOG:                      context->setFogEnabled(true);                   break;

-		case GL_LIGHTING:                 context->setLightingEnabled(true);              break;

-		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;

-		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;

-		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;

-		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;

-		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;

-		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;

-		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;

-		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;

-		case GL_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(true);      break;

-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;

-		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glEnableVertexAttribArray(GLuint index)

-{

-	TRACE("(GLuint index = %d)", index);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribArrayEnabled(index, true);

-	}

-}

-

-void APIENTRY glEndQueryEXT(GLenum target)

-{

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

-

-	switch(target)

-	{

-	case GL_ANY_SAMPLES_PASSED:

-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->endQuery(target);

-	}

-}

-

-void APIENTRY glFinishFenceNV(GLuint fence)

-{

-	TRACE("(GLuint fence = %d)", fence);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Fence* fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		fenceObject->finishFence();

-	}

-}

-

-void APIENTRY glFinish(void)

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->finish();

-	}

-}

-

-void APIENTRY glFlush(void)

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->flush();

-	}

-}

-

-void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "

-	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);

-

-	if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||

-	   (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Framebuffer *framebuffer = NULL;

-		GLuint framebufferName = 0;

-		if(target == GL_READ_FRAMEBUFFER_EXT)

-		{

-			framebuffer = context->getReadFramebuffer();

-			framebufferName = context->getReadFramebufferName();

-		}

-		else

-		{

-			framebuffer = context->getDrawFramebuffer();

-			framebufferName = context->getDrawFramebufferName();

-		}

-

-		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0:

-			framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);

-			break;

-		case GL_DEPTH_ATTACHMENT:

-			framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);

-			break;

-		case GL_STENCIL_ATTACHMENT:

-			framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "

-	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);

-

-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(attachment)

-	{

-	case GL_COLOR_ATTACHMENT0:

-	case GL_DEPTH_ATTACHMENT:

-	case GL_STENCIL_ATTACHMENT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(texture == 0)

-		{

-			textarget = GL_NONE;

-		}

-		else

-		{

-			gl::Texture *tex = context->getTexture(texture);

-

-			if(tex == NULL)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			if(tex->isCompressed(textarget, level))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			switch(textarget)

-			{

-			case GL_TEXTURE_2D:

-				if(tex->getTarget() != GL_TEXTURE_2D)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(level != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		gl::Framebuffer *framebuffer = NULL;

-		GLuint framebufferName = 0;

-		if(target == GL_READ_FRAMEBUFFER_EXT)

-		{

-			framebuffer = context->getReadFramebuffer();

-			framebufferName = context->getReadFramebufferName();

-		}

-		else

-		{

-			framebuffer = context->getDrawFramebuffer();

-			framebufferName = context->getDrawFramebufferName();

-		}

-

-		if(framebufferName == 0 || !framebuffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;

-		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;

-		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;

-		}

-	}

-}

-

-void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glFrontFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_CW:

-	case GL_CCW:

-		{

-			gl::Context *context = gl::getContext();

-

-			if(context)

-			{

-				context->setFrontFace(mode);

-			}

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			buffers[i] = context->createBuffer();

-		}

-	}

-}

-

-void APIENTRY glGenerateMipmap(GLenum target)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D(target);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->generateMipmaps();

-	}

-}

-

-void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)

-{

-	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		for(int i = 0; i < n; i++)

-		{

-			fences[i] = context->createFence();

-		}

-	}

-}

-

-void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		for(int i = 0; i < n; i++)

-		{

-			framebuffers[i] = context->createFramebuffer();

-		}

-	}

-}

-

-void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)

-{

-	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			ids[i] = context->createQuery();

-		}

-	}

-}

-

-void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		for(int i = 0; i < n; i++)

-		{

-			renderbuffers[i] = context->createRenderbuffer();

-		}

-	}

-}

-

-void APIENTRY glGenTextures(GLsizei n, GLuint* textures)

-{

-	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			textures[i] = context->createTexture();

-		}

-	}

-}

-

-void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "

-	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",

-	      program, index, bufsize, length, size, type, name);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(index >= programObject->getActiveAttributeCount())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->getActiveAttribute(index, bufsize, length, size, type, name);

-	}

-}

-

-void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "

-	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",

-	      program, index, bufsize, length, size, type, name);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(index >= programObject->getActiveUniformCount())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->getActiveUniform(index, bufsize, length, size, type, name);

-	}

-}

-

-void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)

-{

-	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",

-	      program, maxcount, count, shaders);

-

-	if(maxcount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		return programObject->getAttachedShaders(maxcount, count, shaders);

-	}

-}

-

-int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)

-{

-	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION, -1);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE, -1);

-			}

-		}

-

-		if(!programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION, -1);

-		}

-

-		return programObject->getAttributeLocation(name);

-	}

-

-	return -1;

-}

-

-void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(!(context->getBooleanv(pname, params)))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that the pname is valid, but there are no parameters to return

-

-			if(nativeType == GL_FLOAT)

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(floatParams[i] == 0.0f)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] floatParams;

-			}

-			else if(nativeType == GL_INT)

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(intParams[i] == 0)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] intParams;

-			}

-		}

-	}

-}

-

-void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_BUFFER_USAGE:

-			*params = buffer->usage();

-			break;

-		case GL_BUFFER_SIZE:

-			*params = buffer->size();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GLenum APIENTRY glGetError(void)

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		return context->getError();

-	}

-

-	return GL_NO_ERROR;

-}

-

-void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)

-{

-	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		fenceObject->getFenceiv(pname, params);

-	}

-}

-

-void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(!(context->getFloatv(pname, params)))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that the pname is valid, but that there are no parameters to return.

-

-			if(nativeType == GL_BOOL)

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(boolParams[i] == GL_FALSE)

-						params[i] = 0.0f;

-					else

-						params[i] = 1.0f;

-				}

-

-				delete [] boolParams;

-			}

-			else if(nativeType == GL_INT)

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					params[i] = (GLfloat)intParams[i];

-				}

-

-				delete [] intParams;

-			}

-		}

-	}

-}

-

-void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",

-	      target, attachment, pname, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		gl::Framebuffer *framebuffer = NULL;

-		if(target == GL_READ_FRAMEBUFFER_EXT)

-		{

-			if(context->getReadFramebufferName() == 0)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			framebuffer = context->getReadFramebuffer();

-		}

-		else

-		{

-			if(context->getDrawFramebufferName() == 0)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			framebuffer = context->getDrawFramebuffer();

-		}

-

-		GLenum attachmentType;

-		GLuint attachmentHandle;

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0:

-			attachmentType = framebuffer->getColorbufferType();

-			attachmentHandle = framebuffer->getColorbufferName();

-			break;

-		case GL_DEPTH_ATTACHMENT:

-			attachmentType = framebuffer->getDepthbufferType();

-			attachmentHandle = framebuffer->getDepthbufferName();

-			break;

-		case GL_STENCIL_ATTACHMENT:

-			attachmentType = framebuffer->getStencilbufferType();

-			attachmentHandle = framebuffer->getStencilbufferName();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		GLenum attachmentObjectType;   // Type category

-		if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)

-		{

-			attachmentObjectType = attachmentType;

-		}

-		else if(gl::IsTextureTarget(attachmentType))

-		{

-			attachmentObjectType = GL_TEXTURE;

-		}

-		else UNREACHABLE(attachmentType);

-

-		switch(pname)

-		{

-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:

-			*params = attachmentObjectType;

-			break;

-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:

-			if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)

-			{

-				*params = attachmentHandle;

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:

-			if(attachmentObjectType == GL_TEXTURE)

-			{

-				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:

-			if(attachmentObjectType == GL_TEXTURE)

-			{

-				if(gl::IsCubemapTextureTarget(attachmentType))

-				{

-					*params = attachmentType;

-				}

-				else

-				{

-					*params = 0;

-				}

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GLenum APIENTRY glGetGraphicsResetStatusEXT(void)

-{

-	TRACE("()");

-

-	return GL_NO_ERROR;

-}

-

-void APIENTRY glGetIntegerv(GLenum pname, GLint* params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(!(context->getIntegerv(pname, params)))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that pname is valid, but there are no parameters to return

-

-			if(nativeType == GL_BOOL)

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(boolParams[i] == GL_FALSE)

-						params[i] = 0;

-					else

-						params[i] = 1;

-				}

-

-				delete [] boolParams;

-			}

-			else if(nativeType == GL_FLOAT)

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)

-					{

-						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);

-					}

-					else

-					{

-						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

-					}

-				}

-

-				delete [] floatParams;

-			}

-		}

-	}

-}

-

-void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)

-{

-	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		switch(pname)

-		{

-		case GL_DELETE_STATUS:

-			*params = programObject->isFlaggedForDeletion();

-			return;

-		case GL_LINK_STATUS:

-			*params = programObject->isLinked();

-			return;

-		case GL_VALIDATE_STATUS:

-			*params = programObject->isValidated();

-			return;

-		case GL_INFO_LOG_LENGTH:

-			*params = programObject->getInfoLogLength();

-			return;

-		case GL_ATTACHED_SHADERS:

-			*params = programObject->getAttachedShadersCount();

-			return;

-		case GL_ACTIVE_ATTRIBUTES:

-			*params = programObject->getActiveAttributeCount();

-			return;

-		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:

-			*params = programObject->getActiveAttributeMaxLength();

-			return;

-		case GL_ACTIVE_UNIFORMS:

-			*params = programObject->getActiveUniformCount();

-			return;

-		case GL_ACTIVE_UNIFORM_MAX_LENGTH:

-			*params = programObject->getActiveUniformMaxLength();

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)

-{

-	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",

-	      program, bufsize, length, infolog);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->getInfoLog(bufsize, length, infolog);

-	}

-}

-

-void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)

-{

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

-

-	switch(pname)

-	{

-	case GL_CURRENT_QUERY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		params[0] = context->getActiveQuery(target);

-	}

-}

-

-void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)

-{

-	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);

-

-	switch(pname)

-	{

-	case GL_QUERY_RESULT:

-	case GL_QUERY_RESULT_AVAILABLE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);

-

-		if(!queryObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(context->getActiveQuery(queryObject->getType()) == name)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_QUERY_RESULT:

-			params[0] = queryObject->getResult();

-			break;

-		case GL_QUERY_RESULT_AVAILABLE:

-			params[0] = queryObject->isResultAvailable();

-			break;

-		default:

-			ASSERT(false);

-		}

-	}

-}

-

-void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(target != GL_RENDERBUFFER)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(context->getRenderbufferName() == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-

-		switch(pname)

-		{

-		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;

-		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;

-		case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;

-		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;

-		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;

-		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;

-		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;

-		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;

-		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;

-		case GL_RENDERBUFFER_SAMPLES_EXT:     *params = renderbuffer->getSamples();     break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)

-{

-	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		switch(pname)

-		{

-		case GL_SHADER_TYPE:

-			*params = shaderObject->getType();

-			return;

-		case GL_DELETE_STATUS:

-			*params = shaderObject->isFlaggedForDeletion();

-			return;

-		case GL_COMPILE_STATUS:

-			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;

-			return;

-		case GL_INFO_LOG_LENGTH:

-			*params = shaderObject->getInfoLogLength();

-			return;

-		case GL_SHADER_SOURCE_LENGTH:

-			*params = shaderObject->getSourceLength();

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)

-{

-	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",

-	      shader, bufsize, length, infolog);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		shaderObject->getInfoLog(bufsize, length, infolog);

-	}

-}

-

-void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)

-{

-	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",

-	      shadertype, precisiontype, range, precision);

-

-	switch(shadertype)

-	{

-	case GL_VERTEX_SHADER:

-	case GL_FRAGMENT_SHADER:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(precisiontype)

-	{

-	case GL_LOW_FLOAT:

-	case GL_MEDIUM_FLOAT:

-	case GL_HIGH_FLOAT:

-		// IEEE 754 single-precision

-		range[0] = 127;

-		range[1] = 127;

-		*precision = 23;

-		break;

-	case GL_LOW_INT:

-	case GL_MEDIUM_INT:

-	case GL_HIGH_INT:

-		// Full integer precision is supported

-		range[0] = 31;

-		range[1] = 30;

-		*precision = 0;

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)

-{

-	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",

-	      shader, bufsize, length, source);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		shaderObject->getSource(bufsize, length, source);

-	}

-}

-

-const GLubyte* APIENTRY glGetString(GLenum name)

-{

-	TRACE("(GLenum name = 0x%X)", name);

-

-	switch(name)

-	{

-	case GL_VENDOR:

-		return (GLubyte*)"TransGaming Inc.";

-	case GL_RENDERER:

-		return (GLubyte*)"SwiftShader";

-	case GL_VERSION:

-		return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;

-	case GL_SHADING_LANGUAGE_VERSION:

-		return (GLubyte*)"3.30 SwiftShader "VERSION_STRING;

-	case GL_EXTENSIONS:

-		// Keep list sorted in following order:

-		// OES extensions

-		// EXT extensions

-		// Vendor extensions

-		return (GLubyte*)

-			"GL_ARB_framebuffer_object "

-			"GL_EXT_blend_minmax "

-			"GL_EXT_depth_texture "

-			"GL_EXT_depth_texture_cube_map "

-			"GL_EXT_element_index_uint "

-			"GL_EXT_packed_depth_stencil "

-			"GL_EXT_rgb8_rgba8 "

-			"GL_EXT_standard_derivatives "

-			"GL_EXT_texture_float "

-			"GL_EXT_texture_float_linear "

-			"GL_EXT_texture_half_float "

-			"GL_EXT_texture_half_float_linear "

-			"GL_EXT_texture_npot "

-			"GL_EXT_occlusion_query_boolean "

-			"GL_EXT_read_format_bgra "

-			#if (S3TC_SUPPORT)

-			"GL_EXT_texture_compression_dxt1 "

-			#endif

-			"GL_EXT_blend_func_separate "

-			"GL_EXT_secondary_color "

-			"GL_EXT_texture_filter_anisotropic "

-			"GL_EXT_texture_format_BGRA8888 "

-			"GL_EXT_framebuffer_blit "

-			"GL_EXT_framebuffer_multisample "

-			#if (S3TC_SUPPORT)

-			"GL_EXT_texture_compression_dxt3 "

-			"GL_EXT_texture_compression_dxt5 "

-			#endif

-			"GL_NV_fence";

-	default:

-		return error(GL_INVALID_ENUM, (GLubyte*)NULL);

-	}

-

-	return NULL;

-}

-

-void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D(target);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_MAG_FILTER:

-			*params = (GLfloat)texture->getMagFilter();

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			*params = (GLfloat)texture->getMinFilter();

-			break;

-		case GL_TEXTURE_WRAP_S:

-			*params = (GLfloat)texture->getWrapS();

-			break;

-		case GL_TEXTURE_WRAP_T:

-			*params = (GLfloat)texture->getWrapT();

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			*params = texture->getMaxAnisotropy();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D(target);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_MAG_FILTER:

-			*params = texture->getMagFilter();

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			*params = texture->getMinFilter();

-			break;

-		case GL_TEXTURE_WRAP_S:

-			*params = texture->getWrapS();

-			break;

-		case GL_TEXTURE_WRAP_T:

-			*params = texture->getWrapT();

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			*params = (GLint)texture->getMaxAnisotropy();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",

-	      program, location, bufSize, params);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformfv(location, &bufSize, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformfv(location, NULL, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",

-	      program, location, bufSize, params);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformiv(location, &bufSize, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformiv(location, NULL, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)

-{

-	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

-

-	gl::Context *context = gl::getContext();

-

-	if(strstr(name, "gl_") == name)

-	{

-		return -1;

-	}

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION, -1);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE, -1);

-			}

-		}

-

-		if(!programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION, -1);

-		}

-

-		return programObject->getUniformLocation(name);

-	}

-

-	return -1;

-}

-

-void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(index >= gl::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);

-

-		switch(pname)

-		{

-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:

-			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:

-			*params = (GLfloat)attribState.mSize;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:

-			*params = (GLfloat)attribState.mStride;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:

-			*params = (GLfloat)attribState.mType;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:

-			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:

-			*params = (GLfloat)attribState.mBoundBuffer.name();

-			break;

-		case GL_CURRENT_VERTEX_ATTRIB:

-			for(int i = 0; i < 4; ++i)

-			{

-				params[i] = attribState.mCurrentValue[i];

-			}

-			break;

-		default: return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(index >= gl::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);

-

-		switch(pname)

-		{

-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:

-			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:

-			*params = attribState.mSize;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:

-			*params = attribState.mStride;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:

-			*params = attribState.mType;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:

-			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:

-			*params = attribState.mBoundBuffer.name();

-			break;

-		case GL_CURRENT_VERTEX_ATTRIB:

-			for(int i = 0; i < 4; ++i)

-			{

-				float currentValue = attribState.mCurrentValue[i];

-				params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));

-			}

-			break;

-		default: return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(index >= gl::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));

-	}

-}

-

-void APIENTRY glHint(GLenum target, GLenum mode)

-{

-	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);

-

-	switch(mode)

-	{

-	case GL_FASTEST:

-	case GL_NICEST:

-	case GL_DONT_CARE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-	switch(target)

-	{

-	case GL_GENERATE_MIPMAP_HINT:

-		if(context) context->setGenerateMipmapHint(mode);

-		break;

-	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:

-		if(context) context->setFragmentShaderDerivativeHint(mode);

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-GLboolean APIENTRY glIsBuffer(GLuint buffer)

-{

-	TRACE("(GLuint buffer = %d)", buffer);

-

-	gl::Context *context = gl::getContext();

-

-	if(context && buffer)

-	{

-		gl::Buffer *bufferObject = context->getBuffer(buffer);

-

-		if(bufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean APIENTRY glIsEnabled(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		switch(cap)

-		{

-		case GL_CULL_FACE:                return context->isCullFaceEnabled();

-		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();

-		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();

-		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();

-		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();

-		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();

-		case GL_BLEND:                    return context->isBlendEnabled();

-		case GL_DITHER:                   return context->isDitherEnabled();

-		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();

-		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-	}

-

-	return false;

-}

-

-GLboolean APIENTRY glIsFenceNV(GLuint fence)

-{

-	TRACE("(GLuint fence = %d)", fence);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return GL_FALSE;

-		}

-

-		return fenceObject->isFence();

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)

-{

-	TRACE("(GLuint framebuffer = %d)", framebuffer);

-

-	gl::Context *context = gl::getContext();

-

-	if(context && framebuffer)

-	{

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

-

-		if(framebufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean APIENTRY glIsProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	gl::Context *context = gl::getContext();

-

-	if(context && program)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(programObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean APIENTRY glIsQueryEXT(GLuint name)

-{

-	TRACE("(GLuint name = %d)", name);

-

-	if(name == 0)

-	{

-		return GL_FALSE;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);

-

-		if(queryObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)

-{

-	TRACE("(GLuint renderbuffer = %d)", renderbuffer);

-

-	gl::Context *context = gl::getContext();

-

-	if(context && renderbuffer)

-	{

-		gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);

-

-		if(renderbufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean APIENTRY glIsShader(GLuint shader)

-{

-	TRACE("(GLuint shader = %d)", shader);

-

-	gl::Context *context = gl::getContext();

-

-	if(context && shader)

-	{

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(shaderObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean APIENTRY glIsTexture(GLuint texture)

-{

-	TRACE("(GLuint texture = %d)", texture);

-

-	gl::Context *context = gl::getContext();

-

-	if(context && texture)

-	{

-		gl::Texture *textureObject = context->getTexture(texture);

-

-		if(textureObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-void APIENTRY glLineWidth(GLfloat width)

-{

-	TRACE("(GLfloat width = %f)", width);

-

-	if(width <= 0.0f)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setLineWidth(width);

-	}

-}

-

-void APIENTRY glLinkProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		programObject->link();

-	}

-}

-

-void APIENTRY glPixelStorei(GLenum pname, GLint param)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_UNPACK_ALIGNMENT:

-			if(param != 1 && param != 2 && param != 4 && param != 8)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setUnpackAlignment(param);

-			break;

-		case GL_PACK_ALIGNMENT:

-			if(param != 1 && param != 2 && param != 4 && param != 8)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPackAlignment(param);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)

-{

-	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setPolygonOffsetParams(factor, units);

-	}

-}

-

-void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,

-                                  GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",

-	      x, y, width, height, format, type, bufSize, data);

-

-	if(width < 0 || height < 0 || bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!validReadFormatType(format, type))

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->readPixels(x, y, width, height, format, type, &bufSize, data);

-	}

-}

-

-void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",

-	      x, y, width, height, format, type,  pixels);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!validReadFormatType(format, type))

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->readPixels(x, y, width, height, format, type, NULL, pixels);

-	}

-}

-

-void APIENTRY glReleaseShaderCompiler(void)

-{

-	TRACE("()");

-

-	gl::Shader::releaseCompiler();

-}

-

-void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",

-	      target, samples, internalformat, width, height);

-

-	switch(target)

-	{

-	case GL_RENDERBUFFER:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width < 0 || height < 0 || samples < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   samples > gl::IMPLEMENTATION_MAX_SAMPLES)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		GLuint handle = context->getRenderbufferName();

-		if(handle == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT16:

-		case GL_DEPTH_COMPONENT24:

-			context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));

-			break;

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_EXT:

-		case GL_RGBA8_EXT:

-			context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));

-			break;

-		case GL_STENCIL_INDEX8:

-			context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));

-			break;

-		case GL_DEPTH24_STENCIL8_EXT:

-			context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);

-}

-

-void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)

-{

-	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

-

-	gl::Context* context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);

-	}

-}

-

-void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)

-{

-	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);

-

-	if(condition != GL_ALL_COMPLETED_NV)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		fenceObject->setFence(condition);

-	}

-}

-

-void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context* context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

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

-	}

-}

-

-void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)

-{

-	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "

-	      "const GLvoid* binary = %p, GLsizei length = %d)",

-	      n, shaders, binaryformat, binary, length);

-

-	// No binary shader formats are supported.

-	return error(GL_INVALID_ENUM);

-}

-

-void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)

-{

-	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",

-	      shader, count, string, length);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		shaderObject->setSource(count, string, length);

-	}

-}

-

-void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)

-{

-	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);

-}

-

-void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)

-{

-	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);

-

-	switch(face)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(func)

-	{

-	case GL_NEVER:

-	case GL_ALWAYS:

-	case GL_LESS:

-	case GL_LEQUAL:

-	case GL_EQUAL:

-	case GL_GEQUAL:

-	case GL_GREATER:

-	case GL_NOTEQUAL:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilParams(func, ref, mask);

-		}

-

-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilBackParams(func, ref, mask);

-		}

-	}

-}

-

-void APIENTRY glStencilMask(GLuint mask)

-{

-	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);

-}

-

-void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)

-{

-	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);

-

-	switch(face)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilWritemask(mask);

-		}

-

-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilBackWritemask(mask);

-		}

-	}

-}

-

-void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)

-{

-	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);

-}

-

-void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)

-{

-	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",

-	      face, fail, zfail, zpass);

-

-	switch(face)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(fail)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP:

-	case GL_DECR_WRAP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(zfail)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP:

-	case GL_DECR_WRAP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(zpass)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP:

-	case GL_DECR_WRAP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilOperations(fail, zfail, zpass);

-		}

-

-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilBackOperations(fail, zfail, zpass);

-		}

-	}

-}

-

-GLboolean APIENTRY glTestFenceNV(GLuint fence)

-{

-	TRACE("(GLuint fence = %d)", fence);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION, GL_TRUE);

-		}

-

-		return fenceObject->testFence();

-	}

-

-	return GL_TRUE;

-}

-

-void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                              GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",

-	      target, level, internalformat, width, height, border, format, type, pixels);

-

-	if(!validImageSize(level, width, height))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(internalformat != (GLint)format)

-	{

-		//TRACE("UNIMPLEMENTED!!");

-		//return error(GL_INVALID_OPERATION);

-	}

-

-	switch(format)

-	{

-	case GL_ALPHA:

-	case GL_LUMINANCE:

-	case GL_LUMINANCE_ALPHA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_FLOAT:

-		case GL_HALF_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGB:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_5_6_5:

-		case GL_FLOAT:

-		case GL_HALF_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGBA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_4_4_4_4:

-		case GL_UNSIGNED_SHORT_5_5_5_1:

-		case GL_FLOAT:

-		case GL_HALF_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_BGRA_EXT:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_5_6_5:

-		case GL_UNSIGNED_INT_8_8_8_8_REV:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:

-		break;

-	case GL_DEPTH_COMPONENT:

-		switch(type)

-		{

-		case GL_UNSIGNED_SHORT:

-		case GL_UNSIGNED_INT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_DEPTH_STENCIL_EXT:

-		switch(type)

-		{

-		case GL_UNSIGNED_INT_24_8_EXT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(target)

-	{

-	case GL_TEXTURE_2D:

-		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-		break;

-	case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-	case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-	case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-	case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-		if(width != height)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||

-		   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-		break;

-	case GL_PROXY_TEXTURE_2D:

-		pixels = 0;

-

-		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-		{

-			//UNIMPLEMENTED();

-			width = 0;

-			height = 0;

-			internalformat = GL_NONE;

-			format = GL_NONE;

-			type = GL_NONE;

-

-			//return;// error(GL_INVALID_VALUE);

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||

-	   format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||

-	   format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||

-	   format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)

-	{

-		if(S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-		else

-		{

-			return error(GL_INVALID_ENUM);

-		}

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)

-		{

-			gl::Texture2D *texture = context->getTexture2D(target);

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);

-		}

-		else

-		{

-			gl::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

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

-		}

-	}

-}

-

-void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D(target);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_WRAP_S:

-			if(!texture->setWrapS((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_T:

-			if(!texture->setWrapT((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			if(!texture->setMinFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAG_FILTER:

-			if(!texture->setMagFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			if(!texture->setMaxAnisotropy(param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MIN_LOD:

-			//TRACE("() UNIMPLEMENTED!!");   // FIXME

-			//UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_MAX_LOD:

-			//TRACE("() UNIMPLEMENTED!!");   // FIXME

-			//UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_LOD_BIAS:

-			if(param != 0.0f)

-			{

-				UNIMPLEMENTED();

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)

-{

-	glTexParameterf(target, pname, *params);

-}

-

-void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D(target);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_WRAP_S:

-			if(!texture->setWrapS((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_T:

-			if(!texture->setWrapT((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			if(!texture->setMinFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAG_FILTER:

-			if(!texture->setMagFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			if(!texture->setMaxAnisotropy((GLfloat)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MAX_LEVEL:

-			if(!texture->setMaxLevel(param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)

-{

-	glTexParameteri(target, pname, *params);

-}

-

-void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                              GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "

-	      "const GLvoid* pixels = %p)",

-	      target, level, xoffset, yoffset, width, height, format, type, pixels);

-

-	if(!gl::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!gl::CheckTextureFormatType(format, type))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width == 0 || height == 0 || pixels == NULL)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			gl::Texture2D *texture = context->getTexture2D(target);

-

-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))

-			{

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

-			}

-		}

-		else if(gl::IsCubemapTextureTarget(target))

-		{

-			gl::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))

-			{

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

-			}

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void APIENTRY glUniform1f(GLint location, GLfloat x)

-{

-	glUniform1fv(location, 1, &x);

-}

-

-void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform1fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniform1i(GLint location, GLint x)

-{

-	glUniform1iv(location, 1, &x);

-}

-

-void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform1iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)

-{

-	GLfloat xy[2] = {x, y};

-

-	glUniform2fv(location, 1, (GLfloat*)&xy);

-}

-

-void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform2fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniform2i(GLint location, GLint x, GLint y)

-{

-	GLint xy[4] = {x, y};

-

-	glUniform2iv(location, 1, (GLint*)&xy);

-}

-

-void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform2iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)

-{

-	GLfloat xyz[3] = {x, y, z};

-

-	glUniform3fv(location, 1, (GLfloat*)&xyz);

-}

-

-void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform3fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)

-{

-	GLint xyz[3] = {x, y, z};

-

-	glUniform3iv(location, 1, (GLint*)&xyz);

-}

-

-void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform3iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	GLfloat xyzw[4] = {x, y, z, w};

-

-	glUniform4fv(location, 1, (GLfloat*)&xyzw);

-}

-

-void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform4fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)

-{

-	GLint xyzw[4] = {x, y, z, w};

-

-	glUniform4iv(location, 1, (GLint*)&xyzw);

-}

-

-void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform4iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",

-	      location, count, transpose, value);

-

-	if(count < 0 || transpose != GL_FALSE)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix2fv(location, count, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",

-	      location, count, transpose, value);

-

-	if(count < 0 || transpose != GL_FALSE)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix3fv(location, count, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",

-	      location, count, transpose, value);

-

-	if(count < 0 || transpose != GL_FALSE)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix4fv(location, count, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void APIENTRY glUseProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject && program != 0)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(program != 0 && !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->useProgram(program);

-	}

-}

-

-void APIENTRY glValidateProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		programObject->validate();

-	}

-}

-

-void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//GLfloat vals[4] = { x, 0, 0, 1 };

-		context->setVertexAttrib(index, x, 0, 0, 1);

-	}

-}

-

-void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//GLfloat vals[4] = { values[0], 0, 0, 1 };

-		context->setVertexAttrib(index, values[0], 0, 0, 1);

-	}

-}

-

-void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//GLfloat vals[4] = { x, y, 0, 1 };

-		context->setVertexAttrib(index, x, y, 0, 1);

-	}

-}

-

-void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//GLfloat vals[4] = {  };

-		context->setVertexAttrib(index, values[0], values[1], 0, 1);

-	}

-}

-

-void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//GLfloat vals[4] = { x, y, z, 1 };

-		context->setVertexAttrib(index, x, y, z, 1);

-	}

-}

-

-void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//GLfloat vals[4] = { values[0], values[1], values[2], 1 };

-		context->setVertexAttrib(index, values[0], values[1], values[2], 1);

-	}

-}

-

-void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//GLfloat vals[4] = { x, y, z, w };

-		context->setVertexAttrib(index, x, y, z, w);

-	}

-}

-

-void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);

-	}

-}

-

-void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)

-{

-	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "

-	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",

-	      index, size, type, normalized, stride, ptr);

-

-	if(index >= gl::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(size < 1 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(type)

-	{

-	case GL_BYTE:

-	case GL_UNSIGNED_BYTE:

-	case GL_SHORT:

-	case GL_UNSIGNED_SHORT:

-	case GL_FIXED:

-	case GL_FLOAT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(stride < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);

-	}

-}

-

-void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

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

-	}

-}

-

-void APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                                        GLbitfield mask, GLenum filter)

-{

-	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "

-	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "

-	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",

-	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);

-

-	switch(filter)

-	{

-	case GL_NEAREST:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)

-	{

-		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");

-		return error(GL_INVALID_OPERATION);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		if(context->getReadFramebufferName() == context->getDrawFramebufferName())

-		{

-			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);

-	}

-}

-

-void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,

-                                 GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "

-	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",

-	      target, level, internalformat, width, height, depth, border, format, type, pixels);

-

-	UNIMPLEMENTED();   // FIXME

-}

-

-void WINAPI GlmfBeginGlsBlock()

-{

-	UNIMPLEMENTED();

-}

-

-void WINAPI GlmfCloseMetaFile()

-{

-	UNIMPLEMENTED();

-}

-

-void WINAPI GlmfEndGlsBlock()

-{

-	UNIMPLEMENTED();

-}

-

-void WINAPI GlmfEndPlayback()

-{

-	UNIMPLEMENTED();

-}

-

-void WINAPI GlmfInitPlayback()

-{

-	UNIMPLEMENTED();

-}

-

-void WINAPI GlmfPlayGlsRecord()

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glAccum(GLenum op, GLfloat value)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->alphaFunc(func, ref);

-	}

-}

-

-GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)

-{

-	UNIMPLEMENTED();

-	return GL_FALSE;

-}

-

-void APIENTRY glArrayElement(GLint i)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glBegin(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_STRIP:

-	case GL_LINE_LOOP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_STRIP:

-	case GL_TRIANGLE_FAN:

-	case GL_QUADS:

-	case GL_QUAD_STRIP:

-	case GL_POLYGON:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->begin(mode);

-	}

-}

-

-void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glCallList(GLuint list)

-{

-	TRACE("(GLuint list = %d)", list);

-

-	if(list == 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->callList(list);

-	}

-}

-

-void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)

-{

-	TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		for(int i = 0; i < n; i++)

-		{

-			switch(type)

-			{

-			case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;

-			default:

-				UNIMPLEMENTED();

-				UNREACHABLE(type);

-			}

-		}

-	}

-}

-

-void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glClearDepth(GLclampd depth)

-{

-	TRACE("(GLclampd depth = %d)", depth);

-

-	glClearDepthf((float)depth);   // FIXME

-}

-

-void APIENTRY glClearIndex(GLfloat c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3bv(const GLbyte *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)

-{

-	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//context->color(red, green, blue, 1.0f);

-		//GLfloat vals[4] = {};

-		context->setVertexAttrib(sw::Color0, red, green, blue, 1);

-	}

-}

-

-void APIENTRY glColor3fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3i(GLint red, GLint green, GLint blue)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3ubv(const GLubyte *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3uiv(const GLuint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor3usv(const GLushort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4bv(const GLbyte *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)

-{

-	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//context->color(red, green, blue, alpha);

-		//GLfloat vals[4] = {red, green, blue, alpha};

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

-	}

-}

-

-void APIENTRY glColor4fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4ubv(const GLubyte *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4uiv(const GLuint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColor4usv(const GLushort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glColorMaterial(GLenum face, GLenum mode)

-{

-	TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);

-

-	// FIXME: Validate enums

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		switch(face)

-		{

-		case GL_FRONT:

-			context->setColorMaterialMode(mode);   // FIXME: Front only

-			break;

-		case GL_FRONT_AND_BACK:

-			context->setColorMaterialMode(mode);

-			break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(*)");

-

-	glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);

-}

-

-void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glDebugEntry()

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glDeleteLists(GLuint list, GLsizei range)

-{

-	TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);

-

-	if(range < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		for(GLuint i = list; i < list + range; i++)

-		{

-			context->deleteList(i);

-		}

-	}

-}

-

-void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glDisableClientState(GLenum array)

-{

-	TRACE("(GLenum array = 0x%X)", array);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-

-		switch(array)

-		{

-		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, false);                            break;

-		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;

-		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;

-		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;

-		default:                     UNIMPLEMENTED();

-		}

-	}

-}

-

-void APIENTRY glDrawBuffer(GLenum mode)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEdgeFlag(GLboolean flag)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEdgeFlagv(const GLboolean *flag)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEnableClientState(GLenum array)

-{

-	TRACE("(GLenum array = 0x%X)", array);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-

-		switch(array)

-		{

-		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, true);                            break;

-		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;

-		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;

-		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;

-		default:                     UNIMPLEMENTED();

-		}

-	}

-}

-

-void APIENTRY glEnd()

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->end();

-	}

-}

-

-void APIENTRY glEndList()

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->endList();

-	}

-}

-

-void APIENTRY glEvalCoord1d(GLdouble u)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalCoord1dv(const GLdouble *u)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalCoord1f(GLfloat u)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalCoord1fv(const GLfloat *u)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalCoord2dv(const GLdouble *u)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalCoord2fv(const GLfloat *u)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalPoint1(GLint i)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glEvalPoint2(GLint i, GLint j)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glFogf(GLenum pname, GLfloat param)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Device *device = gl::getDevice();   // FIXME

-

-		switch(pname)

-		{

-		case GL_FOG_START: device->setFogStart(param); break;

-		case GL_FOG_END:   device->setFogEnd(param);   break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glFogfv(GLenum pname, const GLfloat *params)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		switch(pname)

-		{

-		case GL_FOG_COLOR:

-			{

-				gl::Device *device = gl::getDevice();   // FIXME

-				device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));

-			}

-			break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glFogi(GLenum pname, GLint param)

-{

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

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		switch(pname)

-		{

-		case GL_FOG_MODE:

-			{

-				gl::Device *device = gl::getDevice();   // FIXME

-				switch(param)

-				{

-				case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;

-				default:

-					UNIMPLEMENTED();

-					return error(GL_INVALID_ENUM);

-				}

-			}

-			break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glFogiv(GLenum pname, const GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)

-{

-	TRACE("(GLdouble left = %f, GLdouble right = %f, GLdouble bottom = %f, GLdouble top = %f, GLdouble zNear = %f, GLdouble zFar = %f)", left, right, bottom, top, zNear, zFar);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

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

-	}

-}

-

-GLuint APIENTRY glGenLists(GLsizei range)

-{

-	TRACE("(GLsizei range = %d)", range);

-

-	if(range < 0)

-	{

-		return error(GL_INVALID_VALUE, 0);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		return context->genLists(range);

-	}

-

-	return 0;

-}

-

-void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetPolygonStipple(GLubyte *mask)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLint *pixels%p)", target, level, format, type, pixels);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D(target);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(format == texture->getFormat(target, level) && type == texture->getType(target, level))

-		{

-			gl::Image *image = texture->getRenderTarget(target, level);

-			void *source = image->lock(0, 0, sw::LOCK_READONLY);

-			memcpy(pixels, source, image->getPitch() * image->getHeight());

-			image->unlock();

-		}

-		else

-		{

-			UNIMPLEMENTED();

-		}

-	}

-}

-

-void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = %p)", target, level, pname, params);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		gl::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-		case GL_PROXY_TEXTURE_2D:

-			texture = context->getTexture2D(target);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_MAG_FILTER:

-			*params = texture->getMagFilter();

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			*params = texture->getMinFilter();

-			break;

-		case GL_TEXTURE_WRAP_S:

-			*params = texture->getWrapS();

-			break;

-		case GL_TEXTURE_WRAP_T:

-			*params = texture->getWrapT();

-			break;

-		case GL_TEXTURE_WIDTH:

-			*params = texture->getWidth(target, level);

-			break;

-		case GL_TEXTURE_HEIGHT:

-			*params = texture->getHeight(target, level);

-			break;

-		case GL_TEXTURE_INTERNAL_FORMAT:

-				*params = texture->getInternalFormat(target, level);

-			break;

-		case GL_TEXTURE_BORDER_COLOR:

-			UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_BORDER:

-			UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			*params = (GLint)texture->getMaxAnisotropy();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glIndexMask(GLuint mask)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexd(GLdouble c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexdv(const GLdouble *c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexf(GLfloat c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexfv(const GLfloat *c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexi(GLint c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexiv(const GLint *c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexs(GLshort c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexsv(const GLshort *c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexub(GLubyte c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glIndexubv(const GLubyte *c)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glInitNames(void)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)

-{

-	UNIMPLEMENTED();

-}

-

-GLboolean APIENTRY glIsList(GLuint list)

-{

-	UNIMPLEMENTED();

-	return GL_FALSE;

-}

-

-void APIENTRY glLightModelf(GLenum pname, GLfloat param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Device *device = gl::getDevice();   // FIXME

-

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_AMBIENT:

-			device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));

-			break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glLightModeli(GLenum pname, GLint param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLightModeliv(GLenum pname, const GLint *params)

-{

-	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		gl::Device *device = gl::getDevice();   // FIXME

-

-		switch(pname)

-		{

-		case GL_AMBIENT:  device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;

-		case GL_DIFFUSE:  device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;

-		case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;

-		case GL_POSITION:

-			if(params[3] == 0.0f)   // Directional light

-			{

-				// Create a very far out point light

-				float max = sw::max(abs(params[0]), abs(params[1]), abs(params[2]));

-				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));

-			}

-			else

-			{

-				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));

-			}

-			break;

-		default:

-			UNIMPLEMENTED();

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLineStipple(GLint factor, GLushort pattern)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glListBase(GLuint base)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLoadIdentity()

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->loadIdentity();

-	}

-}

-

-void APIENTRY glLoadMatrixd(const GLdouble *m)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLoadMatrixf(const GLfloat *m)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLoadName(GLuint name)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glLogicOp(GLenum opcode)

-{

-	TRACE("(GLenum opcode = 0x%X)", opcode);

-

-	switch(opcode)

-	{

-	case GL_CLEAR:

-	case GL_SET:

-	case GL_COPY:

-	case GL_COPY_INVERTED:

-	case GL_NOOP:

-	case GL_INVERT:

-	case GL_AND:

-	case GL_NAND:

-	case GL_OR:

-	case GL_NOR:

-	case GL_XOR:

-	case GL_EQUIV:

-	case GL_AND_REVERSE:

-	case GL_AND_INVERTED:

-	case GL_OR_REVERSE:

-	case GL_OR_INVERTED:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setLogicalOperation(opcode);

-	}

-}

-

-void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glMatrixMode(GLenum mode)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setMatrixMode(mode);

-	}

-}

-

-void APIENTRY glMultMatrixd(const GLdouble *m)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->multiply(m);

-	}

-}

-

-void APIENTRY glMultMatrixm(sw::Matrix m)

-{

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->multiply((GLfloat*)m.m);

-	}

-}

-

-void APIENTRY glMultMatrixf(const GLfloat *m)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));

-		}

-

-		context->multiply(m);

-	}

-}

-

-void APIENTRY glNewList(GLuint list, GLenum mode)

-{

-	TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);

-

-	if(list == 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(mode)

-	{

-	case GL_COMPILE:

-	case GL_COMPILE_AND_EXECUTE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->newList(list, mode);

-	}

-}

-

-void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3bv(const GLbyte *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)

-{

-	TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//context->normal(nx, ny, nz);

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

-	}

-}

-

-void APIENTRY glNormal3fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormal3sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(*)");

-

-	glVertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);

-}

-

-void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

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

-	}

-}

-

-void APIENTRY glPassThrough(GLfloat token)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPixelStoref(GLenum pname, GLfloat param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPixelTransferi(GLenum pname, GLint param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPointSize(GLfloat size)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPolygonMode(GLenum face, GLenum mode)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPolygonStipple(const GLubyte *mask)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPopAttrib(void)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPopClientAttrib(void)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPopMatrix(void)

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			return context->listCommand(gl::newCommand(glPopMatrix));

-		}

-

-		context->popMatrix();

-	}

-}

-

-void APIENTRY glPopName(void)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPushAttrib(GLbitfield mask)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPushClientAttrib(GLbitfield mask)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glPushMatrix(void)

-{

-	TRACE("()");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			return context->listCommand(gl::newCommand(glPushMatrix));

-		}

-

-		context->pushMatrix();

-	}

-}

-

-void APIENTRY glPushName(GLuint name)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2i(GLint x, GLint y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2s(GLshort x, GLshort y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos2sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos3sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRasterPos4sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glReadBuffer(GLenum mode)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRectiv(const GLint *v1, const GLint *v2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)

-{

-	UNIMPLEMENTED();

-}

-

-GLint APIENTRY glRenderMode(GLenum mode)

-{

-	UNIMPLEMENTED();

-	return 0;

-}

-

-void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

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

-	}

-}

-

-void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			return context->listCommand(gl::newCommand(glScalef, x, y, z));

-		}

-

-		context->scale(x, y, z);

-	}

-}

-

-void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glShadeModel(GLenum mode)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->setShadeModel(mode);

-	}

-}

-

-void APIENTRY glTexCoord1d(GLdouble s)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord1dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord1f(GLfloat s)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord1fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord1i(GLint s)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord1iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord1s(GLshort s)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord1sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord2dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)

-{

-	TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//context->texCoord(s, t, 0.0f, 1.0f);

-		unsigned int texture = context->getActiveTexture();

-		context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);

-	}

-}

-

-void APIENTRY glTexCoord2fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord2i(GLint s, GLint t)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord2iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord2s(GLshort s, GLshort t)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord2sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord3sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoord4sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-

-		glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);

-	}

-}

-

-void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)

-{

-	TRACE("(*)");

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			return context->listCommand(gl::newCommand(glTranslated, x, y, z));

-		}

-

-		context->translate(x, y, z);   // FIXME

-	}

-}

-

-void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			return context->listCommand(gl::newCommand(glTranslatef, x, y, z));

-		}

-

-		context->translate(x, y, z);

-	}

-}

-

-void APIENTRY glVertex2d(GLdouble x, GLdouble y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex2dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex2f(GLfloat x, GLfloat y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex2fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex2i(GLint x, GLint y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex2iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex2s(GLshort x, GLshort y)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex2sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex3dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		context->position(x, y, z, 1.0f);

-	}

-}

-

-void APIENTRY glVertex3fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex3i(GLint x, GLint y, GLint z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex3iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex3sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4dv(const GLdouble *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4fv(const GLfloat *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4iv(const GLint *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertex4sv(const GLshort *v)

-{

-	UNIMPLEMENTED();

-}

-

-void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

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

-

-	glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);

-}

-

-void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}

-void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}

-void APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}

-void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}

-

-void APIENTRY glClientActiveTexture(GLenum texture)

-{

-	TRACE("(GLenum texture = 0x%X)", texture);

-

-	switch(texture)

-	{

-	case GL_TEXTURE0:

-	case GL_TEXTURE1:

-		break;

-	default:

-		UNIMPLEMENTED();

-		UNREACHABLE(texture);

-	}

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		context->clientActiveTexture(texture);

-	}

-}

-

-void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}

-void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}

-void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}

-void APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}

-void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}

-void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}

-void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}

-

-void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)

-{

-	TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);

-

-	gl::Context *context = gl::getContext();

-

-	if(context)

-	{

-		if(context->getListIndex() != 0)

-		{

-			UNIMPLEMENTED();

-		}

-

-		//context->texCoord(s, t, 0.0f, 1.0f);

-		context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);

-	}

-}

-

-void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}

-void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}

-void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}

-void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}

-void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}

-void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}

-void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}

-void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}

-void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}

-void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}

-void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}

-void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}

-void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}

-void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}

-void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}

-void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}

-void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}

-void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}

-void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}

-void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}

-void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}

-void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}

-void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}

-void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}

-void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}

-void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}

-void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}

-void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}

-void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}

-void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}

-GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}

-void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}

-void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}

-void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}

-GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}

-void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}

-void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}

-void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}

-void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}

-void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}

-void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}

-void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}

-void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}

-void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}

-void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}

-void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}

-void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}

-void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}

-void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}

-

-void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}

-void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}

-void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}

-

-BOOL WINAPI wglSwapIntervalEXT(int interval)

-{

-	gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());

-

-	if(drawSurface)

-	{

-		drawSurface->setSwapInterval(interval);

-		return TRUE;

-	}

-

-	SetLastError(ERROR_DC_NOT_FOUND);

-	return FALSE;

-}

-

-int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)

-{

-	TRACE("(*)");

-

-	return 1;

-}

-

-BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-HGLRC WINAPI wglCreateContext(HDC hdc)

-{

-	TRACE("(*)");

-

-	gl::Display *display = gl::Display::getDisplay(hdc);

-	display->initialize();

-

-	gl::Context *context = display->createContext(nullptr);

-

-	return (HGLRC)context;

-}

-

-HGLRC WINAPI wglCreateLayerContext(HDC, int)

-{

-	UNIMPLEMENTED();

-	return 0;

-}

-

-BOOL WINAPI wglDeleteContext(HGLRC context)

-{

-	gl::Display *display = gl::getDisplay();

-

-	if(display && context)

-	{

-		display->destroyContext(reinterpret_cast<gl::Context*>(context));

-

-		return TRUE;

-	}

-

-	return FALSE;

-}

-

-BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)

-{

-	TRACE("(*)");

-

-	ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR));   // FIXME

-

-	ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);

-	ppfd->nVersion = 1;

-	ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

-	ppfd->iPixelType = PFD_TYPE_RGBA;

-	ppfd->cColorBits = 32;

-	ppfd->cRedBits = 8;

-	ppfd->cRedShift = 16;

-	ppfd->cGreenBits = 8;

-	ppfd->cGreenShift = 8;

-	ppfd->cBlueBits = 8;

-	ppfd->cBlueShift = 0;

-	ppfd->cAlphaBits = 0;

-	ppfd->cAlphaShift = 24;

-	ppfd->cAccumBits = 0;

-	ppfd->cAccumRedBits = 0;

-	ppfd->cAccumGreenBits = 0;

-	ppfd->cAccumBlueBits = 0;

-	ppfd->cAccumAlphaBits = 0;

-	ppfd->cDepthBits = 24;

-	ppfd->cStencilBits = 0;

-	ppfd->cAuxBuffers = 0;

-	ppfd->iLayerType = 0;

-	ppfd->bReserved = 0;

-	ppfd->dwLayerMask = 0;

-	ppfd->dwVisibleMask = 0;

-	ppfd->dwDamageMask = 0;

-

-	return 1;

-}

-

-HGLRC WINAPI wglGetCurrentContext(VOID)

-{

-	TRACE("(*)");

-	return (HGLRC)gl::getContext();

-}

-

-HDC WINAPI wglGetCurrentDC(VOID)

-{

-	TRACE("(*)");

-	gl::Display *display = gl::getDisplay();

-	return display ? display->getNativeDisplay() : 0;

-}

-

-void WINAPI wglGetDefaultProcAddress()

-{

-	UNIMPLEMENTED();

-}

-

-int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)

-{

-	UNIMPLEMENTED();

-	return 0;

-}

-

-void WINAPI wglGetPixelFormat()

-{

-	UNIMPLEMENTED();

-}

-

-const char *WINAPI wglGetExtensionsStringARB(HDC hdc)

-{

-	TRACE("(*)");

-

-	return "GL_ARB_framebuffer_object "

-		   "WGL_EXT_extensions_string "

-		   "WGL_EXT_swap_control";

-}

-

-const char *WINAPI wglGetExtensionsStringEXT()

-{

-	TRACE("(*)");

-	return wglGetExtensionsStringARB(0);

-}

-

-PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)

-{

-	TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);

-

-	struct Extension

-	{

-		const char *name;

-		PROC address;

-	};

-

-	static const Extension glExtensions[] =

-	{

-		#define EXT(function) {#function, (PROC)function}

-

-		// Core 2.1

-		EXT(glDrawRangeElements),

-		EXT(glTexImage3D),

-		EXT(glTexSubImage3D),

-		EXT(glCopyTexSubImage3D),

-		EXT(glActiveTexture),

-		EXT(glClientActiveTexture),

-		EXT(glCompressedTexImage1D),

-		EXT(glCompressedTexImage2D),

-		EXT(glCompressedTexImage3D),

-		EXT(glCompressedTexSubImage1D),

-		EXT(glCompressedTexSubImage2D),

-		EXT(glCompressedTexSubImage3D),

-		EXT(glGetCompressedTexImage),

-		EXT(glMultiTexCoord1f),

-		EXT(glMultiTexCoord1d),

-		EXT(glMultiTexCoord2f),

-		EXT(glMultiTexCoord2d),

-		EXT(glMultiTexCoord3f),

-		EXT(glMultiTexCoord3d),

-		EXT(glMultiTexCoord4f),

-		EXT(glMultiTexCoord4d),

-		EXT(glLoadTransposeMatrixf),

-		EXT(glLoadTransposeMatrixd),

-		EXT(glMultTransposeMatrixf),

-		EXT(glMultTransposeMatrixd),

-		EXT(glSampleCoverage),

-		EXT(glBlendEquation),

-		EXT(glBlendColor),

-		EXT(glFogCoordf),

-		EXT(glFogCoordd),

-		EXT(glFogCoordPointer),

-		EXT(glMultiDrawArrays),

-		EXT(glPointParameteri),

-		EXT(glPointParameterf),

-		EXT(glPointParameteriv),

-		EXT(glPointParameterfv),

-		EXT(glSecondaryColor3b),

-		EXT(glSecondaryColor3f),

-		EXT(glSecondaryColor3d),

-		EXT(glSecondaryColor3ub),

-		EXT(glSecondaryColorPointer),

-		EXT(glBlendFuncSeparate),

-		EXT(glWindowPos2f),

-		EXT(glWindowPos2d),

-		EXT(glWindowPos2i),

-		EXT(glWindowPos3f),

-		EXT(glWindowPos3d),

-		EXT(glWindowPos3i),

-		EXT(glBindBuffer),

-		EXT(glDeleteBuffers),

-		EXT(glGenBuffers),

-		EXT(glIsBuffer),

-		EXT(glBufferData),

-		EXT(glBufferSubData),

-		EXT(glGetBufferSubData),

-		EXT(glMapBuffer),

-		EXT(glUnmapBuffer),

-		EXT(glGetBufferParameteriv),

-		EXT(glGetBufferPointerv),

-		EXT(glGenQueries),

-		EXT(glDeleteQueries),

-		EXT(glIsQuery),

-		EXT(glBeginQuery),

-		EXT(glEndQuery),

-		EXT(glGetQueryiv),

-		EXT(glGetQueryObjectiv),

-		EXT(glGetQueryObjectuiv),

-		EXT(glShaderSource),

-		EXT(glCreateShader),

-		EXT(glIsShader),

-		EXT(glCompileShader),

-		EXT(glDeleteShader),

-		EXT(glCreateProgram),

-		EXT(glIsProgram),

-		EXT(glAttachShader),

-		EXT(glDetachShader),

-		EXT(glLinkProgram),

-		EXT(glUseProgram),

-		EXT(glValidateProgram),

-		EXT(glDeleteProgram),

-		EXT(glUniform1f),

-		EXT(glUniform2f),

-		EXT(glUniform3f),

-		EXT(glUniform4f),

-		EXT(glUniform1i),

-		EXT(glUniform2i),

-		EXT(glUniform3i),

-		EXT(glUniform4i),

-		EXT(glUniform1fv),

-		EXT(glUniform2fv),

-		EXT(glUniform3fv),

-		EXT(glUniform4fv),

-		EXT(glUniform1iv),

-		EXT(glUniform2iv),

-		EXT(glUniform3iv),

-		EXT(glUniform4iv),

-		EXT(glUniformMatrix2fv),

-		EXT(glUniformMatrix3fv),

-		EXT(glUniformMatrix4fv),

-		EXT(glGetShaderiv),

-		EXT(glGetProgramiv),

-		EXT(glGetShaderInfoLog),

-		EXT(glGetProgramInfoLog),

-		EXT(glGetAttachedShaders),

-		EXT(glGetUniformLocation),

-		EXT(glGetActiveUniform),

-		EXT(glGetUniformfv),

-		EXT(glGetUniformiv),

-		EXT(glGetShaderSource),

-		EXT(glVertexAttrib1s),

-		EXT(glVertexAttrib1f),

-		EXT(glVertexAttrib1d),

-		EXT(glVertexAttrib2s),

-		EXT(glVertexAttrib2f),

-		EXT(glVertexAttrib2d),

-		EXT(glVertexAttrib3s),

-		EXT(glVertexAttrib3f),

-		EXT(glVertexAttrib3d),

-		EXT(glVertexAttrib4s),

-		EXT(glVertexAttrib4f),

-		EXT(glVertexAttrib4d),

-		EXT(glVertexAttrib4Nub),

-		EXT(glVertexAttribPointer),

-		EXT(glEnableVertexAttribArray),

-		EXT(glDisableVertexAttribArray),

-		EXT(glGetVertexAttribfv),

-		EXT(glGetVertexAttribdv),

-		EXT(glGetVertexAttribiv),

-		EXT(glGetVertexAttribPointerv),

-		EXT(glBindAttribLocation),

-		EXT(glGetActiveAttrib),

-		EXT(glGetAttribLocation),

-		EXT(glDrawBuffers),

-		EXT(glStencilOpSeparate),

-		EXT(glStencilFuncSeparate),

-		EXT(glStencilMaskSeparate),

-		EXT(glBlendEquationSeparate),

-		EXT(glUniformMatrix2x3fv),

-		EXT(glUniformMatrix3x2fv),

-		EXT(glUniformMatrix2x4fv),

-		EXT(glUniformMatrix4x2fv),

-		EXT(glUniformMatrix3x4fv),

-		EXT(glUniformMatrix4x3fv),

-		EXT(glGenFencesNV),

-		EXT(glDeleteFencesNV),

-		EXT(glSetFenceNV),

-		EXT(glTestFenceNV),

-		EXT(glFinishFenceNV),

-		EXT(glIsFenceNV),

-		EXT(glGetFenceivNV),

-

-		EXT(glIsRenderbuffer),

-		EXT(glBindRenderbuffer),

-		EXT(glDeleteRenderbuffers),

-		EXT(glGenRenderbuffers),

-		EXT(glRenderbufferStorage),

-		EXT(glGetRenderbufferParameteriv),

-		EXT(glIsFramebuffer),

-		EXT(glBindFramebuffer),

-		EXT(glDeleteFramebuffers),

-		EXT(glGenFramebuffers),

-		EXT(glCheckFramebufferStatus),

-		EXT(glFramebufferTexture1D),

-		EXT(glFramebufferTexture2D),

-		EXT(glFramebufferTexture3D),

-		EXT(glFramebufferRenderbuffer),

-		EXT(glGetFramebufferAttachmentParameteriv),

-		EXT(glGenerateMipmap),

-		EXT(glReleaseShaderCompiler),

-		EXT(glShaderBinary),

-		EXT(glGetShaderPrecisionFormat),

-		EXT(glDepthRangef),

-		EXT(glClearDepthf),

-

-		// ARB

-		EXT(wglGetExtensionsStringARB),

-		EXT(glIsRenderbuffer),

-		EXT(glBindRenderbuffer),

-		EXT(glDeleteRenderbuffers),

-		EXT(glGenRenderbuffers),

-		EXT(glRenderbufferStorage),

-		EXT(glRenderbufferStorageMultisample),

-		EXT(glGetRenderbufferParameteriv),

-		EXT(glIsFramebuffer),

-		EXT(glBindFramebuffer),

-		EXT(glDeleteFramebuffers),

-		EXT(glGenFramebuffers),

-		EXT(glCheckFramebufferStatus),

-		EXT(glFramebufferTexture1D),

-		EXT(glFramebufferTexture2D),

-		EXT(glFramebufferTexture3D),

-		EXT(glFramebufferTextureLayer),

-		EXT(glFramebufferRenderbuffer),

-		EXT(glGetFramebufferAttachmentParameteriv),

-		EXT(glBlitFramebuffer),

-		EXT(glGenerateMipmap),

-

-		// EXT

-		EXT(wglSwapIntervalEXT),

-		EXT(wglGetExtensionsStringEXT),

-		#undef EXT

-	};

-

-	for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)

-	{

-		if(strcmp(lpszProc, glExtensions[ext].name) == 0)

-		{

-			return (PROC)glExtensions[ext].address;

-		}

-	}

-

-	FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc);  // FIXME?

-

-	if(proc)

-	{

-		return proc;

-	}

-

-	TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);

-

-	return 0;

-}

-

-BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)

-{

-	TRACE("(*)");

-

-	if(hdc && hglrc)

-	{

-		gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);

-		gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());

-		gl::setCurrentDrawSurface(display->getPrimarySurface());

-		gl::setCurrentDisplay(display);

-	}

-	else

-	{

-		gl::makeCurrent(0, 0, 0);

-	}

-

-	return TRUE;

-}

-

-BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)

-{

-	UNIMPLEMENTED();

-	return 0;

-}

-

-BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)

-{

-	TRACE("(*)");

-	//UNIMPLEMENTED();

-

-	return TRUE;

-}

-

-BOOL WINAPI wglShareLists(HGLRC, HGLRC)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-BOOL WINAPI wglSwapBuffers(HDC hdc)

-{

-	TRACE("(*)");

-

-	gl::Display *display = gl::getDisplay();

-

-	if(display)

-	{

-		display->getPrimarySurface()->swap();

-		return TRUE;

-	}

-

-	return FALSE;

-}

-

-BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)

-{

-	UNIMPLEMENTED();

-	return 0;

-}

-

-BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)

-{

-	UNIMPLEMENTED();

-	return FALSE;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// libGL.cpp: Implements the exported OpenGL functions.
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "Buffer.h"
+#include "Context.h"
+#include "Fence.h"
+#include "Framebuffer.h"
+#include "Program.h"
+#include "Renderbuffer.h"
+#include "Shader.h"
+#include "Texture.h"
+#include "Query.h"
+#include "common/debug.h"
+#include "Common/Version.h"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#include <limits>
+
+using std::abs;
+
+static bool validImageSize(GLint level, GLsizei width, GLsizei height)
+{
+	if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, gl::Texture *texture)
+{
+	if(!texture)
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(compressed != texture->isCompressed(target, level))
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(format != GL_NONE && format != texture->getFormat(target, level))
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(compressed)
+	{
+		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
+		   (height % 4 != 0 && height != texture->getHeight(target, 0)))
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+	}
+
+	if(xoffset + width > texture->getWidth(target, level) ||
+	   yoffset + height > texture->getHeight(target, level))
+	{
+		return error(GL_INVALID_VALUE, false);
+	}
+
+	return true;
+}
+
+// Check for combinations of format and type that are valid for ReadPixels
+static bool validReadFormatType(GLenum format, GLenum type)
+{
+	switch(format)
+	{
+	case GL_RGBA:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+			break;
+		default:
+			return false;
+		}
+		break;
+	case GL_BGRA_EXT:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+			break;
+		default:
+			return false;
+		}
+		break;
+	case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
+		switch(type)
+		{
+		case gl::IMPLEMENTATION_COLOR_READ_TYPE:
+			break;
+		default:
+			return false;
+		}
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+extern "C"
+{
+
+void APIENTRY glActiveTexture(GLenum texture)
+{
+	TRACE("(GLenum texture = 0x%X)", texture);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->setActiveSampler(texture - GL_TEXTURE0);
+	}
+}
+
+void APIENTRY glAttachShader(GLuint program, GLuint shader)
+{
+	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(!programObject->attachShader(shaderObject))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
+{
+	TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED:
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(name == 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->beginQuery(target, name);
+	}
+}
+
+void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(strncmp(name, "gl_", 3) == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		programObject->bindAttributeLocation(index, name);
+	}
+}
+
+void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			context->bindArrayBuffer(buffer);
+			return;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			context->bindElementArrayBuffer(buffer);
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
+
+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
+		{
+			context->bindReadFramebuffer(framebuffer);
+		}
+
+		if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
+		{
+			context->bindDrawFramebuffer(framebuffer);
+		}
+	}
+}
+
+void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
+
+	if(target != GL_RENDERBUFFER)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->bindRenderbuffer(renderbuffer);
+	}
+}
+
+void APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject && textureObject->getTarget() != target && texture != 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			context->bindTexture2D(texture);
+			return;
+		case GL_TEXTURE_CUBE_MAP:
+			context->bindTextureCubeMap(texture);
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
+	      red, green, blue, alpha);
+
+	gl::Context* context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
+	}
+}
+
+void APIENTRY glBlendEquation(GLenum mode)
+{
+	glBlendEquationSeparate(mode, mode);
+}
+
+void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
+
+	switch(modeRGB)
+	{
+	case GL_FUNC_ADD:
+	case GL_FUNC_SUBTRACT:
+	case GL_FUNC_REVERSE_SUBTRACT:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(modeAlpha)
+	{
+	case GL_FUNC_ADD:
+	case GL_FUNC_SUBTRACT:
+	case GL_FUNC_REVERSE_SUBTRACT:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setBlendEquation(modeRGB, modeAlpha);
+	}
+}
+
+void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
+}
+
+void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
+	      srcRGB, dstRGB, srcAlpha, dstAlpha);
+
+	switch(srcRGB)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+	case GL_SRC_ALPHA_SATURATE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(dstRGB)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(srcAlpha)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+	case GL_SRC_ALPHA_SATURATE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(dstAlpha)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
+	}
+}
+
+void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
+	      target, size, data, usage);
+
+	if(size < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(usage)
+	{
+	case GL_STREAM_DRAW:
+	case GL_STATIC_DRAW:
+	case GL_DYNAMIC_DRAW:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		buffer->bufferData(data, size, usage);
+	}
+}
+
+void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
+	      target, offset, size, data);
+
+	if(size < 0 || offset < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!data)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if((size_t)size + offset > buffer->size())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		buffer->bufferSubData(data, size, offset);
+	}
+}
+
+GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
+	{
+		return error(GL_INVALID_ENUM, 0);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Framebuffer *framebuffer = nullptr;
+		if(target == GL_READ_FRAMEBUFFER_EXT)
+		{
+			framebuffer = context->getReadFramebuffer();
+		}
+		else
+		{
+			framebuffer = context->getDrawFramebuffer();
+		}
+
+		return framebuffer->completeness();
+	}
+
+	return 0;
+}
+
+void APIENTRY glClear(GLbitfield mask)
+{
+	TRACE("(GLbitfield mask = %X)", mask);
+
+	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			return context->listCommand(gl::newCommand(glClear, mask));
+		}
+
+		context->clear(mask);
+	}
+}
+
+void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
+	      red, green, blue, alpha);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setClearColor(red, green, blue, alpha);
+	}
+}
+
+void APIENTRY glClearDepthf(GLclampf depth)
+{
+	TRACE("(GLclampf depth = %f)", depth);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setClearDepth(depth);
+	}
+}
+
+void APIENTRY glClearStencil(GLint s)
+{
+	TRACE("(GLint s = %d)", s);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setClearStencil(s);
+	}
+}
+
+void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
+	      red, green, blue, alpha);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
+	}
+}
+
+void APIENTRY glCompileShader(GLuint shader)
+{
+	TRACE("(GLuint shader = %d)", shader);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		shaderObject->compile();
+	}
+}
+
+void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                                     GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
+	      target, level, internalformat, width, height, border, imageSize, data);
+
+	if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(internalformat)
+	{
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+		if(!S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_COMPONENT16:
+	case GL_DEPTH_COMPONENT32:
+	case GL_DEPTH_STENCIL_EXT:
+	case GL_DEPTH24_STENCIL8_EXT:
+		return error(GL_INVALID_OPERATION);
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+			if(width != height)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
+			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			gl::Texture2D *texture = context->getTexture2D(target);
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+		}
+		else
+		{
+			gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			switch(target)
+			{
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+				texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+				break;
+			default: UNREACHABLE(target);
+			}
+		}
+	}
+}
+
+void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                        GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
+	      "GLsizei imageSize = %d, const GLvoid* data = %p)",
+	      target, level, xoffset, yoffset, width, height, format, imageSize, data);
+
+	if(!gl::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(format)
+	{
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+		if(!S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width == 0 || height == 0 || !data)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(imageSize != gl::ComputeCompressedSize(width, height, format))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(xoffset % 4 != 0 || yoffset % 4 != 0)
+		{
+			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			gl::Texture2D *texture = context->getTexture2D(target);
+
+			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+			}
+		}
+		else if(gl::IsCubemapTextureTarget(target))
+		{
+			gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+			}
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
+	      target, level, internalformat, x, y, width, height, border);
+
+	if(!validImageSize(level, width, height))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+			if(width != height)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
+			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
+
+		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		gl::Renderbuffer *source = framebuffer->getColorbuffer();
+		GLenum colorbufferFormat = source->getFormat();
+
+		switch(internalformat)
+		{
+		case GL_ALPHA:
+			if(colorbufferFormat != GL_ALPHA &&
+			   colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4 &&
+			   colorbufferFormat != GL_RGB5_A1 &&
+			   colorbufferFormat != GL_RGBA8_EXT)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_LUMINANCE:
+		case GL_RGB:
+			if(colorbufferFormat != GL_RGB &&
+			   colorbufferFormat != GL_RGB565 &&
+			   colorbufferFormat != GL_RGB8_EXT &&
+			   colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4 &&
+			   colorbufferFormat != GL_RGB5_A1 &&
+			   colorbufferFormat != GL_RGBA8_EXT)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_LUMINANCE_ALPHA:
+		case GL_RGBA:
+			if(colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4 &&
+			   colorbufferFormat != GL_RGB5_A1 &&
+			   colorbufferFormat != GL_RGBA8_EXT)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+			if(S3TC_SUPPORT)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			gl::Texture2D *texture = context->getTexture2D(target);
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+		}
+		else if(gl::IsCubemapTextureTarget(target))
+		{
+			gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+	      target, level, xoffset, yoffset, x, y, width, height);
+
+	if(!gl::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(width == 0 || height == 0)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
+
+		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		gl::Texture *texture = nullptr;
+
+		if(target == GL_TEXTURE_2D)
+		{
+			texture = context->getTexture2D(target);
+		}
+		else if(gl::IsCubemapTextureTarget(target))
+		{
+			texture = context->getTextureCubeMap();
+		}
+		else UNREACHABLE(target);
+
+		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
+		{
+			return;
+		}
+
+		texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
+	}
+}
+
+GLuint APIENTRY glCreateProgram(void)
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		return context->createProgram();
+	}
+
+	return 0;
+}
+
+GLuint APIENTRY glCreateShader(GLenum type)
+{
+	TRACE("(GLenum type = 0x%X)", type);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		switch(type)
+		{
+		case GL_FRAGMENT_SHADER:
+		case GL_VERTEX_SHADER:
+			return context->createShader(type);
+		default:
+			return error(GL_INVALID_ENUM, 0);
+		}
+	}
+
+	return 0;
+}
+
+void APIENTRY glCullFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		{
+			gl::Context *context = gl::getContext();
+
+			if(context)
+			{
+				context->setCullMode(mode);
+			}
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteBuffer(buffers[i]);
+		}
+	}
+}
+
+void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+	TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteFence(fences[i]);
+		}
+	}
+}
+
+void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		for(int i = 0; i < n; i++)
+		{
+			if(framebuffers[i] != 0)
+			{
+				context->deleteFramebuffer(framebuffers[i]);
+			}
+		}
+	}
+}
+
+void APIENTRY glDeleteProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	if(program == 0)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(!context->getProgram(program))
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		context->deleteProgram(program);
+	}
+}
+
+void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteQuery(ids[i]);
+		}
+	}
+}
+
+void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteRenderbuffer(renderbuffers[i]);
+		}
+	}
+}
+
+void APIENTRY glDeleteShader(GLuint shader)
+{
+	TRACE("(GLuint shader = %d)", shader);
+
+	if(shader == 0)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(!context->getShader(shader))
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		context->deleteShader(shader);
+	}
+}
+
+void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+	TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			if(textures[i] != 0)
+			{
+				context->deleteTexture(textures[i]);
+			}
+		}
+	}
+}
+
+void APIENTRY glDepthFunc(GLenum func)
+{
+	TRACE("(GLenum func = 0x%X)", func);
+
+	switch(func)
+	{
+	case GL_NEVER:
+	case GL_ALWAYS:
+	case GL_LESS:
+	case GL_LEQUAL:
+	case GL_EQUAL:
+	case GL_GREATER:
+	case GL_GEQUAL:
+	case GL_NOTEQUAL:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setDepthFunc(func);
+	}
+}
+
+void APIENTRY glDepthMask(GLboolean flag)
+{
+	TRACE("(GLboolean flag = %d)", flag);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setDepthMask(flag != GL_FALSE);
+	}
+}
+
+void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setDepthRange(zNear, zFar);
+	}
+}
+
+void APIENTRY glDetachShader(GLuint program, GLuint shader)
+{
+	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(!programObject)
+		{
+			gl::Shader *shaderByProgramHandle;
+			shaderByProgramHandle = context->getShader(program);
+			if(!shaderByProgramHandle)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
+		if(!shaderObject)
+		{
+			gl::Program *programByShaderHandle = context->getProgram(shader);
+			if(!programByShaderHandle)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
+		if(!programObject->detachShader(shaderObject))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glDisable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		switch(cap)
+		{
+		case GL_CULL_FACE:                context->setCullFaceEnabled(false);              break;
+		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(false);     break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
+		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(false);        break;
+		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(false);           break;
+		case GL_STENCIL_TEST:             context->setStencilTestEnabled(false);           break;
+		case GL_DEPTH_TEST:               context->setDepthTestEnabled(false);             break;
+		case GL_BLEND:                    context->setBlendEnabled(false);                 break;
+		case GL_DITHER:                   context->setDitherEnabled(false);                break;
+		case GL_LIGHTING:                 context->setLightingEnabled(false);              break;
+		case GL_FOG:                      context->setFogEnabled(false);                   break;
+		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;
+		case GL_TEXTURE_2D:               context->setTexture2DEnabled(false);             break;
+		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;
+		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;
+		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;
+		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;
+		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;
+		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;
+		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;
+		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;
+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;
+		case GL_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(false);      break;
+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;
+		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glDisableVertexAttribArray(GLuint index)
+{
+	TRACE("(GLuint index = %d)", index);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribArrayEnabled(index, false);
+	}
+}
+
+void APIENTRY glCaptureAttribs()
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->captureAttribs();
+	}
+}
+
+void APIENTRY glRestoreAttribs()
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->restoreAttribs();
+	}
+}
+
+void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
+
+	if(count < 0 || first < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE);   // UNIMPLEMENTED!
+
+			context->listCommand(gl::newCommand(glCaptureAttribs));
+			context->captureDrawArrays(mode, first, count);
+			context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));
+			context->listCommand(gl::newCommand(glRestoreAttribs));
+
+			return;
+		}
+
+		context->drawArrays(mode, first, count);
+	}
+}
+
+void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
+	      mode, count, type, indices);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT:
+		case GL_UNSIGNED_INT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->drawElements(mode, count, type, indices);
+	}
+}
+
+void APIENTRY glEnable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		switch(cap)
+		{
+		case GL_CULL_FACE:                context->setCullFaceEnabled(true);              break;
+		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(true);     break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
+		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(true);        break;
+		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(true);           break;
+		case GL_STENCIL_TEST:             context->setStencilTestEnabled(true);           break;
+		case GL_DEPTH_TEST:               context->setDepthTestEnabled(true);             break;
+		case GL_BLEND:                    context->setBlendEnabled(true);                 break;
+		case GL_DITHER:                   context->setDitherEnabled(true);                break;
+		case GL_TEXTURE_2D:               context->setTexture2DEnabled(true);             break;
+		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;
+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;
+		case GL_FOG:                      context->setFogEnabled(true);                   break;
+		case GL_LIGHTING:                 context->setLightingEnabled(true);              break;
+		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;
+		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;
+		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;
+		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;
+		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;
+		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;
+		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;
+		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;
+		case GL_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(true);      break;
+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;
+		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glEnableVertexAttribArray(GLuint index)
+{
+	TRACE("(GLuint index = %d)", index);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribArrayEnabled(index, true);
+	}
+}
+
+void APIENTRY glEndQueryEXT(GLenum target)
+{
+	TRACE("GLenum target = 0x%X)", target);
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED:
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->endQuery(target);
+	}
+}
+
+void APIENTRY glFinishFenceNV(GLuint fence)
+{
+	TRACE("(GLuint fence = %d)", fence);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Fence* fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		fenceObject->finishFence();
+	}
+}
+
+void APIENTRY glFinish(void)
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->finish();
+	}
+}
+
+void APIENTRY glFlush(void)
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->flush();
+	}
+}
+
+void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
+	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
+
+	if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||
+	   (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Framebuffer *framebuffer = nullptr;
+		GLuint framebufferName = 0;
+		if(target == GL_READ_FRAMEBUFFER_EXT)
+		{
+			framebuffer = context->getReadFramebuffer();
+			framebufferName = context->getReadFramebufferName();
+		}
+		else
+		{
+			framebuffer = context->getDrawFramebuffer();
+			framebufferName = context->getDrawFramebufferName();
+		}
+
+		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0:
+			framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
+			break;
+		case GL_DEPTH_ATTACHMENT:
+			framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
+			break;
+		case GL_STENCIL_ATTACHMENT:
+			framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
+	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
+
+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(attachment)
+	{
+	case GL_COLOR_ATTACHMENT0:
+	case GL_DEPTH_ATTACHMENT:
+	case GL_STENCIL_ATTACHMENT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(texture == 0)
+		{
+			textarget = GL_NONE;
+		}
+		else
+		{
+			gl::Texture *tex = context->getTexture(texture);
+
+			if(!tex)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			if(tex->isCompressed(textarget, level))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			switch(textarget)
+			{
+			case GL_TEXTURE_2D:
+				if(tex->getTarget() != GL_TEXTURE_2D)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(level != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		gl::Framebuffer *framebuffer = nullptr;
+		GLuint framebufferName = 0;
+		if(target == GL_READ_FRAMEBUFFER_EXT)
+		{
+			framebuffer = context->getReadFramebuffer();
+			framebufferName = context->getReadFramebufferName();
+		}
+		else
+		{
+			framebuffer = context->getDrawFramebuffer();
+			framebufferName = context->getDrawFramebufferName();
+		}
+
+		if(framebufferName == 0 || !framebuffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;
+		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
+		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
+		}
+	}
+}
+
+void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glFrontFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_CW:
+	case GL_CCW:
+		{
+			gl::Context *context = gl::getContext();
+
+			if(context)
+			{
+				context->setFrontFace(mode);
+			}
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			buffers[i] = context->createBuffer();
+		}
+	}
+}
+
+void APIENTRY glGenerateMipmap(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D(target);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->generateMipmaps();
+	}
+}
+
+void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
+{
+	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		for(int i = 0; i < n; i++)
+		{
+			fences[i] = context->createFence();
+		}
+	}
+}
+
+void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		for(int i = 0; i < n; i++)
+		{
+			framebuffers[i] = context->createFramebuffer();
+		}
+	}
+}
+
+void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
+{
+	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			ids[i] = context->createQuery();
+		}
+	}
+}
+
+void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		for(int i = 0; i < n; i++)
+		{
+			renderbuffers[i] = context->createRenderbuffer();
+		}
+	}
+}
+
+void APIENTRY glGenTextures(GLsizei n, GLuint* textures)
+{
+	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			textures[i] = context->createTexture();
+		}
+	}
+}
+
+void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
+	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
+	      program, index, bufsize, length, size, type, name);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(index >= programObject->getActiveAttributeCount())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->getActiveAttribute(index, bufsize, length, size, type, name);
+	}
+}
+
+void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
+	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
+	      program, index, bufsize, length, size, type, name);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(index >= programObject->getActiveUniformCount())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->getActiveUniform(index, bufsize, length, size, type, name);
+	}
+}
+
+void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
+	      program, maxcount, count, shaders);
+
+	if(maxcount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		return programObject->getAttachedShaders(maxcount, count, shaders);
+	}
+}
+
+int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
+{
+	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION, -1);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE, -1);
+			}
+		}
+
+		if(!programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION, -1);
+		}
+
+		return programObject->getAttributeLocation(name);
+	}
+
+	return -1;
+}
+
+void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(!(context->getBooleanv(pname, params)))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that the pname is valid, but there are no parameters to return
+
+			if(nativeType == GL_FLOAT)
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(floatParams[i] == 0.0f)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] floatParams;
+			}
+			else if(nativeType == GL_INT)
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(intParams[i] == 0)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] intParams;
+			}
+		}
+	}
+}
+
+void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_BUFFER_USAGE:
+			*params = buffer->usage();
+			break;
+		case GL_BUFFER_SIZE:
+			*params = buffer->size();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GLenum APIENTRY glGetError(void)
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		return context->getError();
+	}
+
+	return GL_NO_ERROR;
+}
+
+void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		fenceObject->getFenceiv(pname, params);
+	}
+}
+
+void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(!(context->getFloatv(pname, params)))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that the pname is valid, but that there are no parameters to return.
+
+			if(nativeType == GL_BOOL)
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(boolParams[i] == GL_FALSE)
+						params[i] = 0.0f;
+					else
+						params[i] = 1.0f;
+				}
+
+				delete [] boolParams;
+			}
+			else if(nativeType == GL_INT)
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					params[i] = (GLfloat)intParams[i];
+				}
+
+				delete [] intParams;
+			}
+		}
+	}
+}
+
+void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
+	      target, attachment, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		gl::Framebuffer *framebuffer = nullptr;
+		if(target == GL_READ_FRAMEBUFFER_EXT)
+		{
+			if(context->getReadFramebufferName() == 0)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			framebuffer = context->getReadFramebuffer();
+		}
+		else
+		{
+			if(context->getDrawFramebufferName() == 0)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			framebuffer = context->getDrawFramebuffer();
+		}
+
+		GLenum attachmentType;
+		GLuint attachmentHandle;
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0:
+			attachmentType = framebuffer->getColorbufferType();
+			attachmentHandle = framebuffer->getColorbufferName();
+			break;
+		case GL_DEPTH_ATTACHMENT:
+			attachmentType = framebuffer->getDepthbufferType();
+			attachmentHandle = framebuffer->getDepthbufferName();
+			break;
+		case GL_STENCIL_ATTACHMENT:
+			attachmentType = framebuffer->getStencilbufferType();
+			attachmentHandle = framebuffer->getStencilbufferName();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		GLenum attachmentObjectType;   // Type category
+		if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
+		{
+			attachmentObjectType = attachmentType;
+		}
+		else if(gl::IsTextureTarget(attachmentType))
+		{
+			attachmentObjectType = GL_TEXTURE;
+		}
+		else UNREACHABLE(attachmentType);
+
+		switch(pname)
+		{
+		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+			*params = attachmentObjectType;
+			break;
+		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+			if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
+			{
+				*params = attachmentHandle;
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+			if(attachmentObjectType == GL_TEXTURE)
+			{
+				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+			if(attachmentObjectType == GL_TEXTURE)
+			{
+				if(gl::IsCubemapTextureTarget(attachmentType))
+				{
+					*params = attachmentType;
+				}
+				else
+				{
+					*params = 0;
+				}
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GLenum APIENTRY glGetGraphicsResetStatusEXT(void)
+{
+	TRACE("()");
+
+	return GL_NO_ERROR;
+}
+
+void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(!(context->getIntegerv(pname, params)))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that pname is valid, but there are no parameters to return
+
+			if(nativeType == GL_BOOL)
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(boolParams[i] == GL_FALSE)
+						params[i] = 0;
+					else
+						params[i] = 1;
+				}
+
+				delete [] boolParams;
+			}
+			else if(nativeType == GL_FLOAT)
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
+					{
+						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
+					}
+					else
+					{
+						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
+					}
+				}
+
+				delete [] floatParams;
+			}
+		}
+	}
+}
+
+void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		switch(pname)
+		{
+		case GL_DELETE_STATUS:
+			*params = programObject->isFlaggedForDeletion();
+			return;
+		case GL_LINK_STATUS:
+			*params = programObject->isLinked();
+			return;
+		case GL_VALIDATE_STATUS:
+			*params = programObject->isValidated();
+			return;
+		case GL_INFO_LOG_LENGTH:
+			*params = programObject->getInfoLogLength();
+			return;
+		case GL_ATTACHED_SHADERS:
+			*params = programObject->getAttachedShadersCount();
+			return;
+		case GL_ACTIVE_ATTRIBUTES:
+			*params = programObject->getActiveAttributeCount();
+			return;
+		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+			*params = programObject->getActiveAttributeMaxLength();
+			return;
+		case GL_ACTIVE_UNIFORMS:
+			*params = programObject->getActiveUniformCount();
+			return;
+		case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+			*params = programObject->getActiveUniformMaxLength();
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
+	      program, bufsize, length, infolog);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->getInfoLog(bufsize, length, infolog);
+	}
+}
+
+void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+	TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
+
+	switch(pname)
+	{
+	case GL_CURRENT_QUERY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		params[0] = context->getActiveQuery(target);
+	}
+}
+
+void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
+{
+	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
+
+	switch(pname)
+	{
+	case GL_QUERY_RESULT:
+	case GL_QUERY_RESULT_AVAILABLE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
+
+		if(!queryObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(context->getActiveQuery(queryObject->getType()) == name)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_QUERY_RESULT:
+			params[0] = queryObject->getResult();
+			break;
+		case GL_QUERY_RESULT_AVAILABLE:
+			params[0] = queryObject->isResultAvailable();
+			break;
+		default:
+			ASSERT(false);
+		}
+	}
+}
+
+void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(target != GL_RENDERBUFFER)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(context->getRenderbufferName() == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
+
+		switch(pname)
+		{
+		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;
+		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;
+		case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;
+		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;
+		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;
+		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;
+		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;
+		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;
+		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;
+		case GL_RENDERBUFFER_SAMPLES_EXT:     *params = renderbuffer->getSamples();     break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		switch(pname)
+		{
+		case GL_SHADER_TYPE:
+			*params = shaderObject->getType();
+			return;
+		case GL_DELETE_STATUS:
+			*params = shaderObject->isFlaggedForDeletion();
+			return;
+		case GL_COMPILE_STATUS:
+			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
+			return;
+		case GL_INFO_LOG_LENGTH:
+			*params = shaderObject->getInfoLogLength();
+			return;
+		case GL_SHADER_SOURCE_LENGTH:
+			*params = shaderObject->getSourceLength();
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
+	      shader, bufsize, length, infolog);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		shaderObject->getInfoLog(bufsize, length, infolog);
+	}
+}
+
+void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
+	      shadertype, precisiontype, range, precision);
+
+	switch(shadertype)
+	{
+	case GL_VERTEX_SHADER:
+	case GL_FRAGMENT_SHADER:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(precisiontype)
+	{
+	case GL_LOW_FLOAT:
+	case GL_MEDIUM_FLOAT:
+	case GL_HIGH_FLOAT:
+		// IEEE 754 single-precision
+		range[0] = 127;
+		range[1] = 127;
+		*precision = 23;
+		break;
+	case GL_LOW_INT:
+	case GL_MEDIUM_INT:
+	case GL_HIGH_INT:
+		// Full integer precision is supported
+		range[0] = 31;
+		range[1] = 30;
+		*precision = 0;
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
+	      shader, bufsize, length, source);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		shaderObject->getSource(bufsize, length, source);
+	}
+}
+
+const GLubyte* APIENTRY glGetString(GLenum name)
+{
+	TRACE("(GLenum name = 0x%X)", name);
+
+	switch(name)
+	{
+	case GL_VENDOR:
+		return (GLubyte*)"Google Inc.";
+	case GL_RENDERER:
+		return (GLubyte*)"SwiftShader";
+	case GL_VERSION:
+		return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;
+	case GL_SHADING_LANGUAGE_VERSION:
+		return (GLubyte*)"3.30 SwiftShader "VERSION_STRING;
+	case GL_EXTENSIONS:
+		// Keep list sorted in following order:
+		// OES extensions
+		// EXT extensions
+		// Vendor extensions
+		return (GLubyte*)
+			"GL_ARB_framebuffer_object "
+			"GL_EXT_blend_minmax "
+			"GL_EXT_depth_texture "
+			"GL_EXT_depth_texture_cube_map "
+			"GL_EXT_element_index_uint "
+			"GL_EXT_packed_depth_stencil "
+			"GL_EXT_rgb8_rgba8 "
+			"GL_EXT_standard_derivatives "
+			"GL_EXT_texture_float "
+			"GL_EXT_texture_float_linear "
+			"GL_EXT_texture_half_float "
+			"GL_EXT_texture_half_float_linear "
+			"GL_EXT_texture_npot "
+			"GL_EXT_occlusion_query_boolean "
+			"GL_EXT_read_format_bgra "
+			#if (S3TC_SUPPORT)
+			"GL_EXT_texture_compression_dxt1 "
+			#endif
+			"GL_EXT_blend_func_separate "
+			"GL_EXT_secondary_color "
+			"GL_EXT_texture_filter_anisotropic "
+			"GL_EXT_texture_format_BGRA8888 "
+			"GL_EXT_framebuffer_blit "
+			"GL_EXT_framebuffer_multisample "
+			#if (S3TC_SUPPORT)
+			"GL_EXT_texture_compression_dxt3 "
+			"GL_EXT_texture_compression_dxt5 "
+			#endif
+			"GL_NV_fence";
+	default:
+		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
+	}
+
+	return nullptr;
+}
+
+void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D(target);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_MAG_FILTER:
+			*params = (GLfloat)texture->getMagFilter();
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			*params = (GLfloat)texture->getMinFilter();
+			break;
+		case GL_TEXTURE_WRAP_S:
+			*params = (GLfloat)texture->getWrapS();
+			break;
+		case GL_TEXTURE_WRAP_T:
+			*params = (GLfloat)texture->getWrapT();
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			*params = texture->getMaxAnisotropy();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D(target);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_MAG_FILTER:
+			*params = texture->getMagFilter();
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			*params = texture->getMinFilter();
+			break;
+		case GL_TEXTURE_WRAP_S:
+			*params = texture->getWrapS();
+			break;
+		case GL_TEXTURE_WRAP_T:
+			*params = texture->getWrapT();
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			*params = (GLint)texture->getMaxAnisotropy();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
+	      program, location, bufSize, params);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformfv(location, &bufSize, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformfv(location, nullptr, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
+	      program, location, bufSize, params);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformiv(location, &bufSize, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformiv(location, nullptr, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
+{
+	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
+
+	gl::Context *context = gl::getContext();
+
+	if(strstr(name, "gl_") == name)
+	{
+		return -1;
+	}
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION, -1);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE, -1);
+			}
+		}
+
+		if(!programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION, -1);
+		}
+
+		return programObject->getUniformLocation(name);
+	}
+
+	return -1;
+}
+
+void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(index >= gl::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
+
+		switch(pname)
+		{
+		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+			*params = (GLfloat)attribState.mSize;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+			*params = (GLfloat)attribState.mStride;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+			*params = (GLfloat)attribState.mType;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+			*params = (GLfloat)attribState.mBoundBuffer.name();
+			break;
+		case GL_CURRENT_VERTEX_ATTRIB:
+			for(int i = 0; i < 4; ++i)
+			{
+				params[i] = attribState.mCurrentValue[i];
+			}
+			break;
+		default: return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(index >= gl::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
+
+		switch(pname)
+		{
+		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+			*params = attribState.mSize;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+			*params = attribState.mStride;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+			*params = attribState.mType;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+			*params = attribState.mBoundBuffer.name();
+			break;
+		case GL_CURRENT_VERTEX_ATTRIB:
+			for(int i = 0; i < 4; ++i)
+			{
+				float currentValue = attribState.mCurrentValue[i];
+				params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
+			}
+			break;
+		default: return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(index >= gl::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
+	}
+}
+
+void APIENTRY glHint(GLenum target, GLenum mode)
+{
+	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
+
+	switch(mode)
+	{
+	case GL_FASTEST:
+	case GL_NICEST:
+	case GL_DONT_CARE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+	switch(target)
+	{
+	case GL_GENERATE_MIPMAP_HINT:
+		if(context) context->setGenerateMipmapHint(mode);
+		break;
+	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+		if(context) context->setFragmentShaderDerivativeHint(mode);
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+GLboolean APIENTRY glIsBuffer(GLuint buffer)
+{
+	TRACE("(GLuint buffer = %d)", buffer);
+
+	gl::Context *context = gl::getContext();
+
+	if(context && buffer)
+	{
+		gl::Buffer *bufferObject = context->getBuffer(buffer);
+
+		if(bufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean APIENTRY glIsEnabled(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		switch(cap)
+		{
+		case GL_CULL_FACE:                return context->isCullFaceEnabled();
+		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
+		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
+		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
+		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
+		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
+		case GL_BLEND:                    return context->isBlendEnabled();
+		case GL_DITHER:                   return context->isDitherEnabled();
+		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();
+		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+	}
+
+	return false;
+}
+
+GLboolean APIENTRY glIsFenceNV(GLuint fence)
+{
+	TRACE("(GLuint fence = %d)", fence);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return GL_FALSE;
+		}
+
+		return fenceObject->isFence();
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
+{
+	TRACE("(GLuint framebuffer = %d)", framebuffer);
+
+	gl::Context *context = gl::getContext();
+
+	if(context && framebuffer)
+	{
+		gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
+
+		if(framebufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean APIENTRY glIsProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	gl::Context *context = gl::getContext();
+
+	if(context && program)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(programObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean APIENTRY glIsQueryEXT(GLuint name)
+{
+	TRACE("(GLuint name = %d)", name);
+
+	if(name == 0)
+	{
+		return GL_FALSE;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
+
+		if(queryObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
+{
+	TRACE("(GLuint renderbuffer = %d)", renderbuffer);
+
+	gl::Context *context = gl::getContext();
+
+	if(context && renderbuffer)
+	{
+		gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
+
+		if(renderbufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean APIENTRY glIsShader(GLuint shader)
+{
+	TRACE("(GLuint shader = %d)", shader);
+
+	gl::Context *context = gl::getContext();
+
+	if(context && shader)
+	{
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(shaderObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean APIENTRY glIsTexture(GLuint texture)
+{
+	TRACE("(GLuint texture = %d)", texture);
+
+	gl::Context *context = gl::getContext();
+
+	if(context && texture)
+	{
+		gl::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+void APIENTRY glLineWidth(GLfloat width)
+{
+	TRACE("(GLfloat width = %f)", width);
+
+	if(width <= 0.0f)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setLineWidth(width);
+	}
+}
+
+void APIENTRY glLinkProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		programObject->link();
+	}
+}
+
+void APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_UNPACK_ALIGNMENT:
+			if(param != 1 && param != 2 && param != 4 && param != 8)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setUnpackAlignment(param);
+			break;
+		case GL_PACK_ALIGNMENT:
+			if(param != 1 && param != 2 && param != 4 && param != 8)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPackAlignment(param);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setPolygonOffsetParams(factor, units);
+	}
+}
+
+void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+							   GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
+		  "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
+		  x, y, width, height, format, type, bufSize, data);
+
+	if(width < 0 || height < 0 || bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!validReadFormatType(format, type))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->readPixels(x, y, width, height, format, type, &bufSize, data);
+	}
+}
+
+void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
+	      x, y, width, height, format, type,  pixels);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!validReadFormatType(format, type))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
+	}
+}
+
+void APIENTRY glReleaseShaderCompiler(void)
+{
+	TRACE("()");
+
+	gl::Shader::releaseCompiler();
+}
+
+void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+	      target, samples, internalformat, width, height);
+
+	switch(target)
+	{
+	case GL_RENDERBUFFER:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width < 0 || height < 0 || samples < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   samples > gl::IMPLEMENTATION_MAX_SAMPLES)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		GLuint handle = context->getRenderbufferName();
+		if(handle == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+			context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
+			break;
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_EXT:
+		case GL_RGBA8_EXT:
+			context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
+			break;
+		case GL_STENCIL_INDEX8:
+			context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
+			break;
+		case GL_DEPTH24_STENCIL8_EXT:
+			context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
+}
+
+void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+{
+	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
+
+	gl::Context* context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
+	}
+}
+
+void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
+{
+	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
+
+	if(condition != GL_ALL_COMPLETED_NV)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		fenceObject->setFence(condition);
+	}
+}
+
+void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context* context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setScissorParams(x, y, width, height);
+	}
+}
+
+void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
+	      "const GLvoid* binary = %p, GLsizei length = %d)",
+	      n, shaders, binaryformat, binary, length);
+
+	// No binary shader formats are supported.
+	return error(GL_INVALID_ENUM);
+}
+
+void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
+{
+	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
+	      shader, count, string, length);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		shaderObject->setSource(count, string, length);
+	}
+}
+
+void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
+}
+
+void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
+
+	switch(face)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(func)
+	{
+	case GL_NEVER:
+	case GL_ALWAYS:
+	case GL_LESS:
+	case GL_LEQUAL:
+	case GL_EQUAL:
+	case GL_GEQUAL:
+	case GL_GREATER:
+	case GL_NOTEQUAL:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilParams(func, ref, mask);
+		}
+
+		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilBackParams(func, ref, mask);
+		}
+	}
+}
+
+void APIENTRY glStencilMask(GLuint mask)
+{
+	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
+}
+
+void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
+
+	switch(face)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilWritemask(mask);
+		}
+
+		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilBackWritemask(mask);
+		}
+	}
+}
+
+void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
+}
+
+void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
+	      face, fail, zfail, zpass);
+
+	switch(face)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(fail)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP:
+	case GL_DECR_WRAP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(zfail)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP:
+	case GL_DECR_WRAP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(zpass)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP:
+	case GL_DECR_WRAP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilOperations(fail, zfail, zpass);
+		}
+
+		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilBackOperations(fail, zfail, zpass);
+		}
+	}
+}
+
+GLboolean APIENTRY glTestFenceNV(GLuint fence)
+{
+	TRACE("(GLuint fence = %d)", fence);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION, GL_TRUE);
+		}
+
+		return fenceObject->testFence();
+	}
+
+	return GL_TRUE;
+}
+
+void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                           GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
+	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",
+	      target, level, internalformat, width, height, border, format, type, pixels);
+
+	if(!validImageSize(level, width, height))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(internalformat != (GLint)format)
+	{
+		//TRACE("UNIMPLEMENTED!!");
+		//return error(GL_INVALID_OPERATION);
+	}
+
+	switch(format)
+	{
+	case GL_ALPHA:
+	case GL_LUMINANCE:
+	case GL_LUMINANCE_ALPHA:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_FLOAT:
+		case GL_HALF_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_RGB:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_5_6_5:
+		case GL_FLOAT:
+		case GL_HALF_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_RGBA:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_4_4_4_4:
+		case GL_UNSIGNED_SHORT_5_5_5_1:
+		case GL_FLOAT:
+		case GL_HALF_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_BGRA_EXT:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_5_6_5:
+		case GL_UNSIGNED_INT_8_8_8_8_REV:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+		break;
+	case GL_DEPTH_COMPONENT:
+		switch(type)
+		{
+		case GL_UNSIGNED_SHORT:
+		case GL_UNSIGNED_INT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_DEPTH_STENCIL_EXT:
+		switch(type)
+		{
+		case GL_UNSIGNED_INT_24_8_EXT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(target)
+	{
+	case GL_TEXTURE_2D:
+		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+		break;
+	case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+	case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+	case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+	case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+		if(width != height)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
+		   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+		break;
+	case GL_PROXY_TEXTURE_2D:
+		pixels = 0;
+
+		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+		{
+			//UNIMPLEMENTED();
+			width = 0;
+			height = 0;
+			internalformat = GL_NONE;
+			format = GL_NONE;
+			type = GL_NONE;
+
+			//return;// error(GL_INVALID_VALUE);
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+	   format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+	   format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+	   format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+	{
+		if(S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+		else
+		{
+			return error(GL_INVALID_ENUM);
+		}
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
+		{
+			gl::Texture2D *texture = context->getTexture2D(target);
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
+		}
+		else
+		{
+			gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
+		}
+	}
+}
+
+void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D(target);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_WRAP_S:
+			if(!texture->setWrapS((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_T:
+			if(!texture->setWrapT((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			if(!texture->setMinFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAG_FILTER:
+			if(!texture->setMagFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			if(!texture->setMaxAnisotropy(param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MIN_LOD:
+			//TRACE("() UNIMPLEMENTED!!");   // FIXME
+			//UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_MAX_LOD:
+			//TRACE("() UNIMPLEMENTED!!");   // FIXME
+			//UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_LOD_BIAS:
+			if(param != 0.0f)
+			{
+				UNIMPLEMENTED();
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	glTexParameterf(target, pname, *params);
+}
+
+void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D(target);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_WRAP_S:
+			if(!texture->setWrapS((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_T:
+			if(!texture->setWrapT((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			if(!texture->setMinFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAG_FILTER:
+			if(!texture->setMagFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			if(!texture->setMaxAnisotropy((GLfloat)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MAX_LEVEL:
+			if(!texture->setMaxLevel(param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	glTexParameteri(target, pname, *params);
+}
+
+void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                              GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
+	      "const GLvoid* pixels = %p)",
+	      target, level, xoffset, yoffset, width, height, format, type, pixels);
+
+	if(!gl::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!gl::CheckTextureFormatType(format, type))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width == 0 || height == 0 || !pixels)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			gl::Texture2D *texture = context->getTexture2D(target);
+
+			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
+			}
+		}
+		else if(gl::IsCubemapTextureTarget(target))
+		{
+			gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
+			}
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void APIENTRY glUniform1f(GLint location, GLfloat x)
+{
+	glUniform1fv(location, 1, &x);
+}
+
+void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform1fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniform1i(GLint location, GLint x)
+{
+	glUniform1iv(location, 1, &x);
+}
+
+void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform1iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+	GLfloat xy[2] = {x, y};
+
+	glUniform2fv(location, 1, (GLfloat*)&xy);
+}
+
+void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform2fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
+{
+	GLint xy[4] = {x, y};
+
+	glUniform2iv(location, 1, (GLint*)&xy);
+}
+
+void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform2iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+	GLfloat xyz[3] = {x, y, z};
+
+	glUniform3fv(location, 1, (GLfloat*)&xyz);
+}
+
+void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform3fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+	GLint xyz[3] = {x, y, z};
+
+	glUniform3iv(location, 1, (GLint*)&xyz);
+}
+
+void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform3iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	GLfloat xyzw[4] = {x, y, z, w};
+
+	glUniform4fv(location, 1, (GLfloat*)&xyzw);
+}
+
+void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform4fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+	GLint xyzw[4] = {x, y, z, w};
+
+	glUniform4iv(location, 1, (GLint*)&xyzw);
+}
+
+void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform4iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
+	      location, count, transpose, value);
+
+	if(count < 0 || transpose != GL_FALSE)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix2fv(location, count, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
+	      location, count, transpose, value);
+
+	if(count < 0 || transpose != GL_FALSE)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix3fv(location, count, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
+	      location, count, transpose, value);
+
+	if(count < 0 || transpose != GL_FALSE)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix4fv(location, count, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void APIENTRY glUseProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject && program != 0)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(program != 0 && !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->useProgram(program);
+	}
+}
+
+void APIENTRY glValidateProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		programObject->validate();
+	}
+}
+
+void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//GLfloat vals[4] = { x, 0, 0, 1 };
+		context->setVertexAttrib(index, x, 0, 0, 1);
+	}
+}
+
+void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//GLfloat vals[4] = { values[0], 0, 0, 1 };
+		context->setVertexAttrib(index, values[0], 0, 0, 1);
+	}
+}
+
+void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//GLfloat vals[4] = { x, y, 0, 1 };
+		context->setVertexAttrib(index, x, y, 0, 1);
+	}
+}
+
+void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//GLfloat vals[4] = {  };
+		context->setVertexAttrib(index, values[0], values[1], 0, 1);
+	}
+}
+
+void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//GLfloat vals[4] = { x, y, z, 1 };
+		context->setVertexAttrib(index, x, y, z, 1);
+	}
+}
+
+void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//GLfloat vals[4] = { values[0], values[1], values[2], 1 };
+		context->setVertexAttrib(index, values[0], values[1], values[2], 1);
+	}
+}
+
+void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//GLfloat vals[4] = { x, y, z, w };
+		context->setVertexAttrib(index, x, y, z, w);
+	}
+}
+
+void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
+	}
+}
+
+void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
+	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
+	      index, size, type, normalized, stride, ptr);
+
+	if(index >= gl::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(size < 1 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(type)
+	{
+	case GL_BYTE:
+	case GL_UNSIGNED_BYTE:
+	case GL_SHORT:
+	case GL_UNSIGNED_SHORT:
+	case GL_FIXED:
+	case GL_FLOAT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(stride < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
+	}
+}
+
+void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setViewportParams(x, y, width, height);
+	}
+}
+
+void APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                                     GLbitfield mask, GLenum filter)
+{
+	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
+	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
+	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+	switch(filter)
+	{
+	case GL_NEAREST:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
+	{
+		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
+		return error(GL_INVALID_OPERATION);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		if(context->getReadFramebufferName() == context->getDrawFramebufferName())
+		{
+			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
+	}
+}
+
+void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+                              GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
+	      target, level, internalformat, width, height, depth, border, format, type, pixels);
+
+	UNIMPLEMENTED();   // FIXME
+}
+
+void WINAPI GlmfBeginGlsBlock()
+{
+	UNIMPLEMENTED();
+}
+
+void WINAPI GlmfCloseMetaFile()
+{
+	UNIMPLEMENTED();
+}
+
+void WINAPI GlmfEndGlsBlock()
+{
+	UNIMPLEMENTED();
+}
+
+void WINAPI GlmfEndPlayback()
+{
+	UNIMPLEMENTED();
+}
+
+void WINAPI GlmfInitPlayback()
+{
+	UNIMPLEMENTED();
+}
+
+void WINAPI GlmfPlayGlsRecord()
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glAccum(GLenum op, GLfloat value)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
+{
+	TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->alphaFunc(func, ref);
+	}
+}
+
+GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
+{
+	UNIMPLEMENTED();
+	return GL_FALSE;
+}
+
+void APIENTRY glArrayElement(GLint i)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glBegin(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_STRIP:
+	case GL_LINE_LOOP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_STRIP:
+	case GL_TRIANGLE_FAN:
+	case GL_QUADS:
+	case GL_QUAD_STRIP:
+	case GL_POLYGON:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->begin(mode);
+	}
+}
+
+void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glCallList(GLuint list)
+{
+	TRACE("(GLuint list = %d)", list);
+
+	if(list == 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->callList(list);
+	}
+}
+
+void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
+{
+	TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		for(int i = 0; i < n; i++)
+		{
+			switch(type)
+			{
+			case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
+			default:
+				UNIMPLEMENTED();
+				UNREACHABLE(type);
+			}
+		}
+	}
+}
+
+void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glClearDepth(GLclampd depth)
+{
+	TRACE("(GLclampd depth = %d)", depth);
+
+	glClearDepthf((float)depth);   // FIXME
+}
+
+void APIENTRY glClearIndex(GLfloat c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3bv(const GLbyte *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//context->color(red, green, blue, 1.0f);
+		//GLfloat vals[4] = {};
+		context->setVertexAttrib(sw::Color0, red, green, blue, 1);
+	}
+}
+
+void APIENTRY glColor3fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3ubv(const GLubyte *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3uiv(const GLuint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor3usv(const GLushort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4bv(const GLbyte *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//context->color(red, green, blue, alpha);
+		//GLfloat vals[4] = {red, green, blue, alpha};
+		context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
+	}
+}
+
+void APIENTRY glColor4fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4ubv(const GLubyte *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4uiv(const GLuint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColor4usv(const GLushort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glColorMaterial(GLenum face, GLenum mode)
+{
+	TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);
+
+	// FIXME: Validate enums
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		switch(face)
+		{
+		case GL_FRONT:
+			context->setColorMaterialMode(mode);   // FIXME: Front only
+			break;
+		case GL_FRONT_AND_BACK:
+			context->setColorMaterialMode(mode);
+			break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(*)");
+
+	glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
+}
+
+void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glDebugEntry()
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glDeleteLists(GLuint list, GLsizei range)
+{
+	TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);
+
+	if(range < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		for(GLuint i = list; i < list + range; i++)
+		{
+			context->deleteList(i);
+		}
+	}
+}
+
+void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glDisableClientState(GLenum array)
+{
+	TRACE("(GLenum array = 0x%X)", array);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+
+		switch(array)
+		{
+		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, false);                            break;
+		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;
+		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
+		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;
+		default:                     UNIMPLEMENTED();
+		}
+	}
+}
+
+void APIENTRY glDrawBuffer(GLenum mode)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEdgeFlag(GLboolean flag)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEdgeFlagv(const GLboolean *flag)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEnableClientState(GLenum array)
+{
+	TRACE("(GLenum array = 0x%X)", array);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+
+		switch(array)
+		{
+		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, true);                            break;
+		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;
+		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
+		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;
+		default:                     UNIMPLEMENTED();
+		}
+	}
+}
+
+void APIENTRY glEnd()
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->end();
+	}
+}
+
+void APIENTRY glEndList()
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->endList();
+	}
+}
+
+void APIENTRY glEvalCoord1d(GLdouble u)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalCoord1dv(const GLdouble *u)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalCoord1f(GLfloat u)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalCoord1fv(const GLfloat *u)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalCoord2dv(const GLdouble *u)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalCoord2fv(const GLfloat *u)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalPoint1(GLint i)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glEvalPoint2(GLint i, GLint j)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glFogf(GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Device *device = gl::getDevice();   // FIXME
+
+		switch(pname)
+		{
+		case GL_FOG_START: device->setFogStart(param); break;
+		case GL_FOG_END:   device->setFogEnd(param);   break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		switch(pname)
+		{
+		case GL_FOG_COLOR:
+			{
+				gl::Device *device = gl::getDevice();   // FIXME
+				device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
+			}
+			break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glFogi(GLenum pname, GLint param)
+{
+	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		switch(pname)
+		{
+		case GL_FOG_MODE:
+			{
+				gl::Device *device = gl::getDevice();   // FIXME
+				switch(param)
+				{
+				case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
+				default:
+					UNIMPLEMENTED();
+					return error(GL_INVALID_ENUM);
+				}
+			}
+			break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glFogiv(GLenum pname, const GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+	TRACE("(GLdouble left = %f, GLdouble right = %f, GLdouble bottom = %f, GLdouble top = %f, GLdouble zNear = %f, GLdouble zFar = %f)", left, right, bottom, top, zNear, zFar);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->frustum(left, right, bottom, top, zNear, zFar);
+	}
+}
+
+GLuint APIENTRY glGenLists(GLsizei range)
+{
+	TRACE("(GLsizei range = %d)", range);
+
+	if(range < 0)
+	{
+		return error(GL_INVALID_VALUE, 0);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		return context->genLists(range);
+	}
+
+	return 0;
+}
+
+void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetPolygonStipple(GLubyte *mask)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLint *pixels%p)", target, level, format, type, pixels);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D(target);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
+		{
+			gl::Image *image = texture->getRenderTarget(target, level);
+			void *source = image->lock(0, 0, sw::LOCK_READONLY);
+			memcpy(pixels, source, image->getPitch() * image->getHeight());
+			image->unlock();
+		}
+		else
+		{
+			UNIMPLEMENTED();
+		}
+	}
+}
+
+void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = %p)", target, level, pname, params);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		gl::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+		case GL_PROXY_TEXTURE_2D:
+			texture = context->getTexture2D(target);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_MAG_FILTER:
+			*params = texture->getMagFilter();
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			*params = texture->getMinFilter();
+			break;
+		case GL_TEXTURE_WRAP_S:
+			*params = texture->getWrapS();
+			break;
+		case GL_TEXTURE_WRAP_T:
+			*params = texture->getWrapT();
+			break;
+		case GL_TEXTURE_WIDTH:
+			*params = texture->getWidth(target, level);
+			break;
+		case GL_TEXTURE_HEIGHT:
+			*params = texture->getHeight(target, level);
+			break;
+		case GL_TEXTURE_INTERNAL_FORMAT:
+				*params = texture->getInternalFormat(target, level);
+			break;
+		case GL_TEXTURE_BORDER_COLOR:
+			UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_BORDER:
+			UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			*params = (GLint)texture->getMaxAnisotropy();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glIndexMask(GLuint mask)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexd(GLdouble c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexdv(const GLdouble *c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexf(GLfloat c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexfv(const GLfloat *c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexi(GLint c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexiv(const GLint *c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexs(GLshort c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexsv(const GLshort *c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexub(GLubyte c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glIndexubv(const GLubyte *c)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glInitNames(void)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
+{
+	UNIMPLEMENTED();
+}
+
+GLboolean APIENTRY glIsList(GLuint list)
+{
+	UNIMPLEMENTED();
+	return GL_FALSE;
+}
+
+void APIENTRY glLightModelf(GLenum pname, GLfloat param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Device *device = gl::getDevice();   // FIXME
+
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_AMBIENT:
+			device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
+			break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glLightModeli(GLenum pname, GLint param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		gl::Device *device = gl::getDevice();   // FIXME
+
+		switch(pname)
+		{
+		case GL_AMBIENT:  device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;
+		case GL_DIFFUSE:  device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;
+		case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
+		case GL_POSITION:
+			if(params[3] == 0.0f)   // Directional light
+			{
+				// Create a very far out point light
+				float max = sw::max(abs(params[0]), abs(params[1]), abs(params[2]));
+				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
+			}
+			else
+			{
+				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
+			}
+			break;
+		default:
+			UNIMPLEMENTED();
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLineStipple(GLint factor, GLushort pattern)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glListBase(GLuint base)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLoadIdentity()
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->loadIdentity();
+	}
+}
+
+void APIENTRY glLoadMatrixd(const GLdouble *m)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLoadMatrixf(const GLfloat *m)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLoadName(GLuint name)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glLogicOp(GLenum opcode)
+{
+	TRACE("(GLenum opcode = 0x%X)", opcode);
+
+	switch(opcode)
+	{
+	case GL_CLEAR:
+	case GL_SET:
+	case GL_COPY:
+	case GL_COPY_INVERTED:
+	case GL_NOOP:
+	case GL_INVERT:
+	case GL_AND:
+	case GL_NAND:
+	case GL_OR:
+	case GL_NOR:
+	case GL_XOR:
+	case GL_EQUIV:
+	case GL_AND_REVERSE:
+	case GL_AND_INVERTED:
+	case GL_OR_REVERSE:
+	case GL_OR_INVERTED:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setLogicalOperation(opcode);
+	}
+}
+
+void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glMatrixMode(GLenum mode)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setMatrixMode(mode);
+	}
+}
+
+void APIENTRY glMultMatrixd(const GLdouble *m)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->multiply(m);
+	}
+}
+
+void APIENTRY glMultMatrixm(sw::Matrix m)
+{
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->multiply((GLfloat*)m.m);
+	}
+}
+
+void APIENTRY glMultMatrixf(const GLfloat *m)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
+		}
+
+		context->multiply(m);
+	}
+}
+
+void APIENTRY glNewList(GLuint list, GLenum mode)
+{
+	TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);
+
+	if(list == 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(mode)
+	{
+	case GL_COMPILE:
+	case GL_COMPILE_AND_EXECUTE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->newList(list, mode);
+	}
+}
+
+void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3bv(const GLbyte *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+	TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//context->normal(nx, ny, nz);
+		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
+	}
+}
+
+void APIENTRY glNormal3fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormal3sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(*)");
+
+	glVertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
+}
+
+void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->ortho(left, right, bottom, top, zNear, zFar);
+	}
+}
+
+void APIENTRY glPassThrough(GLfloat token)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPixelTransferi(GLenum pname, GLint param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPointSize(GLfloat size)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPolygonMode(GLenum face, GLenum mode)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPolygonStipple(const GLubyte *mask)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPopAttrib(void)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPopClientAttrib(void)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPopMatrix(void)
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			return context->listCommand(gl::newCommand(glPopMatrix));
+		}
+
+		context->popMatrix();
+	}
+}
+
+void APIENTRY glPopName(void)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPushAttrib(GLbitfield mask)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPushClientAttrib(GLbitfield mask)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glPushMatrix(void)
+{
+	TRACE("()");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			return context->listCommand(gl::newCommand(glPushMatrix));
+		}
+
+		context->pushMatrix();
+	}
+}
+
+void APIENTRY glPushName(GLuint name)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2i(GLint x, GLint y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2s(GLshort x, GLshort y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos2sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos3sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRasterPos4sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glReadBuffer(GLenum mode)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
+{
+	UNIMPLEMENTED();
+}
+
+GLint APIENTRY glRenderMode(GLenum mode)
+{
+	UNIMPLEMENTED();
+	return 0;
+}
+
+void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->rotate(angle, x, y, z);
+	}
+}
+
+void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			return context->listCommand(gl::newCommand(glScalef, x, y, z));
+		}
+
+		context->scale(x, y, z);
+	}
+}
+
+void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glShadeModel(GLenum mode)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->setShadeModel(mode);
+	}
+}
+
+void APIENTRY glTexCoord1d(GLdouble s)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord1dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord1f(GLfloat s)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord1fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord1i(GLint s)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord1iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord1s(GLshort s)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord1sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord2dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
+{
+	TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//context->texCoord(s, t, 0.0f, 1.0f);
+		unsigned int texture = context->getActiveTexture();
+		context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
+	}
+}
+
+void APIENTRY glTexCoord2fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord2i(GLint s, GLint t)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord2iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord2s(GLshort s, GLshort t)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord2sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord3sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoord4sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+
+		glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
+	}
+}
+
+void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
+{
+	TRACE("(*)");
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			return context->listCommand(gl::newCommand(glTranslated, x, y, z));
+		}
+
+		context->translate(x, y, z);   // FIXME
+	}
+}
+
+void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
+		}
+
+		context->translate(x, y, z);
+	}
+}
+
+void APIENTRY glVertex2d(GLdouble x, GLdouble y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex2dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex2f(GLfloat x, GLfloat y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex2fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex2i(GLint x, GLint y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex2iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex2s(GLshort x, GLshort y)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex2sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex3dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		context->position(x, y, z, 1.0f);
+	}
+}
+
+void APIENTRY glVertex3fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex3iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex3sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4dv(const GLdouble *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4fv(const GLfloat *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4iv(const GLint *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertex4sv(const GLshort *v)
+{
+	UNIMPLEMENTED();
+}
+
+void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
+
+	glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
+}
+
+void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
+void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
+void APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
+void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
+
+void APIENTRY glClientActiveTexture(GLenum texture)
+{
+	TRACE("(GLenum texture = 0x%X)", texture);
+
+	switch(texture)
+	{
+	case GL_TEXTURE0:
+	case GL_TEXTURE1:
+		break;
+	default:
+		UNIMPLEMENTED();
+		UNREACHABLE(texture);
+	}
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		context->clientActiveTexture(texture);
+	}
+}
+
+void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
+void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
+void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
+void APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
+void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
+void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
+void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}
+
+void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
+{
+	TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
+
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		if(context->getListIndex() != 0)
+		{
+			UNIMPLEMENTED();
+		}
+
+		//context->texCoord(s, t, 0.0f, 1.0f);
+		context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
+	}
+}
+
+void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
+void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
+void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
+void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
+void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
+void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
+void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
+void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
+void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
+void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
+void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
+void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
+void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
+void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
+void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
+void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
+void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
+void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
+void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
+void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
+void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
+void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
+void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
+void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
+void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
+void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
+void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
+void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
+void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
+void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
+GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
+void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
+void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
+void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
+GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
+void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
+void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
+void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
+void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
+void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
+void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
+void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
+void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
+void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
+void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
+void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
+void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
+void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
+void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
+
+void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
+void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
+void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}
+
+BOOL WINAPI wglSwapIntervalEXT(int interval)
+{
+	gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());
+
+	if(drawSurface)
+	{
+		drawSurface->setSwapInterval(interval);
+		return TRUE;
+	}
+
+	SetLastError(ERROR_DC_NOT_FOUND);
+	return FALSE;
+}
+
+int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+	TRACE("(*)");
+
+	return 1;
+}
+
+BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+HGLRC WINAPI wglCreateContext(HDC hdc)
+{
+	TRACE("(*)");
+
+	gl::Display *display = gl::Display::getDisplay(hdc);
+	display->initialize();
+
+	gl::Context *context = display->createContext(nullptr);
+
+	return (HGLRC)context;
+}
+
+HGLRC WINAPI wglCreateLayerContext(HDC, int)
+{
+	UNIMPLEMENTED();
+	return 0;
+}
+
+BOOL WINAPI wglDeleteContext(HGLRC context)
+{
+	gl::Display *display = gl::getDisplay();
+
+	if(display && context)
+	{
+		display->destroyContext(reinterpret_cast<gl::Context*>(context));
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
+{
+	TRACE("(*)");
+
+	ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR));   // FIXME
+
+	ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
+	ppfd->nVersion = 1;
+	ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+	ppfd->iPixelType = PFD_TYPE_RGBA;
+	ppfd->cColorBits = 32;
+	ppfd->cRedBits = 8;
+	ppfd->cRedShift = 16;
+	ppfd->cGreenBits = 8;
+	ppfd->cGreenShift = 8;
+	ppfd->cBlueBits = 8;
+	ppfd->cBlueShift = 0;
+	ppfd->cAlphaBits = 0;
+	ppfd->cAlphaShift = 24;
+	ppfd->cAccumBits = 0;
+	ppfd->cAccumRedBits = 0;
+	ppfd->cAccumGreenBits = 0;
+	ppfd->cAccumBlueBits = 0;
+	ppfd->cAccumAlphaBits = 0;
+	ppfd->cDepthBits = 24;
+	ppfd->cStencilBits = 0;
+	ppfd->cAuxBuffers = 0;
+	ppfd->iLayerType = 0;
+	ppfd->bReserved = 0;
+	ppfd->dwLayerMask = 0;
+	ppfd->dwVisibleMask = 0;
+	ppfd->dwDamageMask = 0;
+
+	return 1;
+}
+
+HGLRC WINAPI wglGetCurrentContext(VOID)
+{
+	TRACE("(*)");
+	return (HGLRC)gl::getContext();
+}
+
+HDC WINAPI wglGetCurrentDC(VOID)
+{
+	TRACE("(*)");
+	gl::Display *display = gl::getDisplay();
+	return display ? display->getNativeDisplay() : 0;
+}
+
+void WINAPI wglGetDefaultProcAddress()
+{
+	UNIMPLEMENTED();
+}
+
+int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
+{
+	UNIMPLEMENTED();
+	return 0;
+}
+
+void WINAPI wglGetPixelFormat()
+{
+	UNIMPLEMENTED();
+}
+
+const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
+{
+	TRACE("(*)");
+
+	return "GL_ARB_framebuffer_object "
+	       "WGL_EXT_extensions_string "
+	       "WGL_EXT_swap_control";
+}
+
+const char *WINAPI wglGetExtensionsStringEXT()
+{
+	TRACE("(*)");
+	return wglGetExtensionsStringARB(0);
+}
+
+PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
+{
+	TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);
+
+	struct Extension
+	{
+		const char *name;
+		PROC address;
+	};
+
+	static const Extension glExtensions[] =
+	{
+		#define EXT(function) {#function, (PROC)function}
+
+		// Core 2.1
+		EXT(glDrawRangeElements),
+		EXT(glTexImage3D),
+		EXT(glTexSubImage3D),
+		EXT(glCopyTexSubImage3D),
+		EXT(glActiveTexture),
+		EXT(glClientActiveTexture),
+		EXT(glCompressedTexImage1D),
+		EXT(glCompressedTexImage2D),
+		EXT(glCompressedTexImage3D),
+		EXT(glCompressedTexSubImage1D),
+		EXT(glCompressedTexSubImage2D),
+		EXT(glCompressedTexSubImage3D),
+		EXT(glGetCompressedTexImage),
+		EXT(glMultiTexCoord1f),
+		EXT(glMultiTexCoord1d),
+		EXT(glMultiTexCoord2f),
+		EXT(glMultiTexCoord2d),
+		EXT(glMultiTexCoord3f),
+		EXT(glMultiTexCoord3d),
+		EXT(glMultiTexCoord4f),
+		EXT(glMultiTexCoord4d),
+		EXT(glLoadTransposeMatrixf),
+		EXT(glLoadTransposeMatrixd),
+		EXT(glMultTransposeMatrixf),
+		EXT(glMultTransposeMatrixd),
+		EXT(glSampleCoverage),
+		EXT(glBlendEquation),
+		EXT(glBlendColor),
+		EXT(glFogCoordf),
+		EXT(glFogCoordd),
+		EXT(glFogCoordPointer),
+		EXT(glMultiDrawArrays),
+		EXT(glPointParameteri),
+		EXT(glPointParameterf),
+		EXT(glPointParameteriv),
+		EXT(glPointParameterfv),
+		EXT(glSecondaryColor3b),
+		EXT(glSecondaryColor3f),
+		EXT(glSecondaryColor3d),
+		EXT(glSecondaryColor3ub),
+		EXT(glSecondaryColorPointer),
+		EXT(glBlendFuncSeparate),
+		EXT(glWindowPos2f),
+		EXT(glWindowPos2d),
+		EXT(glWindowPos2i),
+		EXT(glWindowPos3f),
+		EXT(glWindowPos3d),
+		EXT(glWindowPos3i),
+		EXT(glBindBuffer),
+		EXT(glDeleteBuffers),
+		EXT(glGenBuffers),
+		EXT(glIsBuffer),
+		EXT(glBufferData),
+		EXT(glBufferSubData),
+		EXT(glGetBufferSubData),
+		EXT(glMapBuffer),
+		EXT(glUnmapBuffer),
+		EXT(glGetBufferParameteriv),
+		EXT(glGetBufferPointerv),
+		EXT(glGenQueries),
+		EXT(glDeleteQueries),
+		EXT(glIsQuery),
+		EXT(glBeginQuery),
+		EXT(glEndQuery),
+		EXT(glGetQueryiv),
+		EXT(glGetQueryObjectiv),
+		EXT(glGetQueryObjectuiv),
+		EXT(glShaderSource),
+		EXT(glCreateShader),
+		EXT(glIsShader),
+		EXT(glCompileShader),
+		EXT(glDeleteShader),
+		EXT(glCreateProgram),
+		EXT(glIsProgram),
+		EXT(glAttachShader),
+		EXT(glDetachShader),
+		EXT(glLinkProgram),
+		EXT(glUseProgram),
+		EXT(glValidateProgram),
+		EXT(glDeleteProgram),
+		EXT(glUniform1f),
+		EXT(glUniform2f),
+		EXT(glUniform3f),
+		EXT(glUniform4f),
+		EXT(glUniform1i),
+		EXT(glUniform2i),
+		EXT(glUniform3i),
+		EXT(glUniform4i),
+		EXT(glUniform1fv),
+		EXT(glUniform2fv),
+		EXT(glUniform3fv),
+		EXT(glUniform4fv),
+		EXT(glUniform1iv),
+		EXT(glUniform2iv),
+		EXT(glUniform3iv),
+		EXT(glUniform4iv),
+		EXT(glUniformMatrix2fv),
+		EXT(glUniformMatrix3fv),
+		EXT(glUniformMatrix4fv),
+		EXT(glGetShaderiv),
+		EXT(glGetProgramiv),
+		EXT(glGetShaderInfoLog),
+		EXT(glGetProgramInfoLog),
+		EXT(glGetAttachedShaders),
+		EXT(glGetUniformLocation),
+		EXT(glGetActiveUniform),
+		EXT(glGetUniformfv),
+		EXT(glGetUniformiv),
+		EXT(glGetShaderSource),
+		EXT(glVertexAttrib1s),
+		EXT(glVertexAttrib1f),
+		EXT(glVertexAttrib1d),
+		EXT(glVertexAttrib2s),
+		EXT(glVertexAttrib2f),
+		EXT(glVertexAttrib2d),
+		EXT(glVertexAttrib3s),
+		EXT(glVertexAttrib3f),
+		EXT(glVertexAttrib3d),
+		EXT(glVertexAttrib4s),
+		EXT(glVertexAttrib4f),
+		EXT(glVertexAttrib4d),
+		EXT(glVertexAttrib4Nub),
+		EXT(glVertexAttribPointer),
+		EXT(glEnableVertexAttribArray),
+		EXT(glDisableVertexAttribArray),
+		EXT(glGetVertexAttribfv),
+		EXT(glGetVertexAttribdv),
+		EXT(glGetVertexAttribiv),
+		EXT(glGetVertexAttribPointerv),
+		EXT(glBindAttribLocation),
+		EXT(glGetActiveAttrib),
+		EXT(glGetAttribLocation),
+		EXT(glDrawBuffers),
+		EXT(glStencilOpSeparate),
+		EXT(glStencilFuncSeparate),
+		EXT(glStencilMaskSeparate),
+		EXT(glBlendEquationSeparate),
+		EXT(glUniformMatrix2x3fv),
+		EXT(glUniformMatrix3x2fv),
+		EXT(glUniformMatrix2x4fv),
+		EXT(glUniformMatrix4x2fv),
+		EXT(glUniformMatrix3x4fv),
+		EXT(glUniformMatrix4x3fv),
+		EXT(glGenFencesNV),
+		EXT(glDeleteFencesNV),
+		EXT(glSetFenceNV),
+		EXT(glTestFenceNV),
+		EXT(glFinishFenceNV),
+		EXT(glIsFenceNV),
+		EXT(glGetFenceivNV),
+
+		EXT(glIsRenderbuffer),
+		EXT(glBindRenderbuffer),
+		EXT(glDeleteRenderbuffers),
+		EXT(glGenRenderbuffers),
+		EXT(glRenderbufferStorage),
+		EXT(glGetRenderbufferParameteriv),
+		EXT(glIsFramebuffer),
+		EXT(glBindFramebuffer),
+		EXT(glDeleteFramebuffers),
+		EXT(glGenFramebuffers),
+		EXT(glCheckFramebufferStatus),
+		EXT(glFramebufferTexture1D),
+		EXT(glFramebufferTexture2D),
+		EXT(glFramebufferTexture3D),
+		EXT(glFramebufferRenderbuffer),
+		EXT(glGetFramebufferAttachmentParameteriv),
+		EXT(glGenerateMipmap),
+		EXT(glReleaseShaderCompiler),
+		EXT(glShaderBinary),
+		EXT(glGetShaderPrecisionFormat),
+		EXT(glDepthRangef),
+		EXT(glClearDepthf),
+
+		// ARB
+		EXT(wglGetExtensionsStringARB),
+		EXT(glIsRenderbuffer),
+		EXT(glBindRenderbuffer),
+		EXT(glDeleteRenderbuffers),
+		EXT(glGenRenderbuffers),
+		EXT(glRenderbufferStorage),
+		EXT(glRenderbufferStorageMultisample),
+		EXT(glGetRenderbufferParameteriv),
+		EXT(glIsFramebuffer),
+		EXT(glBindFramebuffer),
+		EXT(glDeleteFramebuffers),
+		EXT(glGenFramebuffers),
+		EXT(glCheckFramebufferStatus),
+		EXT(glFramebufferTexture1D),
+		EXT(glFramebufferTexture2D),
+		EXT(glFramebufferTexture3D),
+		EXT(glFramebufferTextureLayer),
+		EXT(glFramebufferRenderbuffer),
+		EXT(glGetFramebufferAttachmentParameteriv),
+		EXT(glBlitFramebuffer),
+		EXT(glGenerateMipmap),
+
+		// EXT
+		EXT(wglSwapIntervalEXT),
+		EXT(wglGetExtensionsStringEXT),
+		#undef EXT
+	};
+
+	for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
+	{
+		if(strcmp(lpszProc, glExtensions[ext].name) == 0)
+		{
+			return (PROC)glExtensions[ext].address;
+		}
+	}
+
+	FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc);  // FIXME?
+
+	if(proc)
+	{
+		return proc;
+	}
+
+	TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);
+
+	return 0;
+}
+
+BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
+{
+	TRACE("(*)");
+
+	if(hdc && hglrc)
+	{
+		gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
+		gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
+		gl::setCurrentDrawSurface(display->getPrimarySurface());
+		gl::setCurrentDisplay(display);
+	}
+	else
+	{
+		gl::makeCurrent(0, 0, 0);
+	}
+
+	return TRUE;
+}
+
+BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
+{
+	UNIMPLEMENTED();
+	return 0;
+}
+
+BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+	TRACE("(*)");
+	//UNIMPLEMENTED();
+
+	return TRUE;
+}
+
+BOOL WINAPI wglShareLists(HGLRC, HGLRC)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+BOOL WINAPI wglSwapBuffers(HDC hdc)
+{
+	TRACE("(*)");
+
+	gl::Display *display = gl::getDisplay();
+
+	if(display)
+	{
+		display->getPrimarySurface()->swap();
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
+{
+	UNIMPLEMENTED();
+	return 0;
+}
+
+BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
+{
+	UNIMPLEMENTED();
+	return FALSE;
+}
+
+}
diff --git a/src/OpenGL/libGL/libGL.rc b/src/OpenGL/libGL/libGL.rc
index cb21123..d3bc569 100644
--- a/src/OpenGL/libGL/libGL.rc
+++ b/src/OpenGL/libGL/libGL.rc
@@ -75,7 +75,7 @@
 			#endif
             VALUE "FileVersion", VERSION_STRING
             VALUE "InternalName", "libGL"
-            VALUE "LegalCopyright", "Copyright (C) 2012 TransGaming Inc."
+            VALUE "LegalCopyright", "Copyright (C) 2016 Google Inc."
             VALUE "OriginalFilename", "opengl32.dll"
             VALUE "PrivateBuild", VERSION_STRING
             VALUE "ProductName", "SwiftShader openGL Dynamic Link Library"
diff --git a/src/OpenGL/libGL/main.cpp b/src/OpenGL/libGL/main.cpp
index 0c7eabe..73daa9d 100644
--- a/src/OpenGL/libGL/main.cpp
+++ b/src/OpenGL/libGL/main.cpp
@@ -1,285 +1,288 @@
-// 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.

-//

-

-// main.cpp: DLL entry point and management of thread-local data.

-

-#include "main.h"

-

-#include "resource.h"

-#include "Framebuffer.h"

-#include "Surface.h"

-#include "Common/Thread.hpp"

-#include "common/debug.h"

-

-static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;

-

-#if !defined(_MSC_VER)

-#define CONSTRUCTOR __attribute__((constructor))

-#define DESTRUCTOR __attribute__((destructor))

-#else

-#define CONSTRUCTOR

-#define DESTRUCTOR

-#endif

-

-static void glAttachThread()

-{

-    TRACE("()");

-

-	gl::Current *current = new gl::Current;

-

-    if(current)

-    {

-		sw::Thread::setLocalStorage(currentTLS, current);

-

-        current->context = 0;

-        current->display = 0;

-        current->drawSurface = 0;

-        current->readSurface = 0;

-    }

-}

-

-static void glDetachThread()

-{

-    TRACE("()");

-

-	gl::Current *current = (gl::Current*)sw::Thread::getLocalStorage(currentTLS);

-

-    if(current)

-    {

-        delete current;

-    }

-}

-

-CONSTRUCTOR static bool glAttachProcess()

-{

-    TRACE("()");

-

-	#if !(ANGLE_DISABLE_TRACE)

-        FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");

-

-        if(debug)

-        {

-            fclose(debug);

-            debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase

-            fclose(debug);

-        }

-	#endif

-

-	currentTLS = sw::Thread::allocateLocalStorageKey();

-

-    if(currentTLS == TLS_OUT_OF_INDEXES)

-    {

-        return false;

-    }

-

-    glAttachThread();

-

-    return true;

-}

-

-DESTRUCTOR static void glDetachProcess()

-{

-    TRACE("()");

-

-	glDetachThread();

-

-    sw::Thread::freeLocalStorageKey(currentTLS);

-}

-

-#if defined(_WIN32)

-static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

-{

-	RECT rect;

-

-    switch(uMsg)

-    {

-    case WM_INITDIALOG:

-		GetWindowRect(GetDesktopWindow(), &rect);

-		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);

-		SetTimer(hwnd, 1, 100, NULL);

-		return TRUE;

-    case WM_COMMAND:

-        if(LOWORD(wParam) == IDCANCEL)

-		{

-			EndDialog(hwnd, 0);

-		}

-        break;

-    case WM_TIMER:

-		if(IsDebuggerPresent())

-		{

-			EndDialog(hwnd, 0);

-		}

-    }

-

-    return FALSE;

-}

-

-static void WaitForDebugger(HINSTANCE instance)

-{

-    if(!IsDebuggerPresent())

-    {

-        HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);

-		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);

-		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);

-    }

-}

-

-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)

-{

-    switch(reason)

-    {

-    case DLL_PROCESS_ATTACH:

-		#ifndef NDEBUG

-			WaitForDebugger(instance);

-		#endif

-        return glAttachProcess();

-        break;

-    case DLL_THREAD_ATTACH:

-        glAttachThread();

-        break;

-    case DLL_THREAD_DETACH:

-        glDetachThread();

-        break;

-    case DLL_PROCESS_DETACH:

-        glDetachProcess();

-        break;

-    default:

-        break;

-    }

-

-    return TRUE;

-}

-#endif

-

-namespace gl

-{

-static gl::Current *getCurrent(void)

-{

-	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);

-

-	if(!current)

-	{

-		glAttachThread();

-	}

-

-	return (Current*)sw::Thread::getLocalStorage(currentTLS);

-}

-

-void makeCurrent(Context *context, Display *display, Surface *surface)

-{

-    Current *current = getCurrent();

-

-    current->context = context;

-    current->display = display;

-

-    if(context && display && surface)

-    {

-        context->makeCurrent(surface);

-    }

-}

-

-Context *getContext()

-{

-    Current *current = getCurrent();

-

-    return current->context;

-}

-

-Display *getDisplay()

-{

-    Current *current = getCurrent();

-

-    return current->display;

-}

-

-Device *getDevice()

-{

-    Context *context = getContext();

-

-    return context ? context->getDevice() : 0;

-}

-

-void setCurrentDisplay(Display *dpy)

-{

-    Current *current = getCurrent();

-

-    current->display = dpy;

-}

-

-void setCurrentContext(gl::Context *ctx)

-{

-	Current *current = getCurrent();

-

-	current->context = ctx;

-}

-

-void setCurrentDrawSurface(Surface *surface)

-{

-    Current *current = getCurrent();

-

-    current->drawSurface = surface;

-}

-

-Surface *getCurrentDrawSurface()

-{

-    Current *current = getCurrent();

-

-    return current->drawSurface;

-}

-

-void setCurrentReadSurface(Surface *surface)

-{

-    Current *current = getCurrent();

-

-    current->readSurface = surface;

-}

-

-Surface *getCurrentReadSurface()

-{

-    Current *current = getCurrent();

-

-    return current->readSurface;

-}

-}

-

-// Records an error code

-void error(GLenum errorCode)

-{

-    gl::Context *context = gl::getContext();

-

-    if(context)

-    {

-        switch(errorCode)

-        {

-        case GL_INVALID_ENUM:

-            context->recordInvalidEnum();

-            TRACE("\t! Error generated: invalid enum\n");

-            break;

-        case GL_INVALID_VALUE:

-            context->recordInvalidValue();

-            TRACE("\t! Error generated: invalid value\n");

-            break;

-        case GL_INVALID_OPERATION:

-            context->recordInvalidOperation();

-            TRACE("\t! Error generated: invalid operation\n");

-            break;

-        case GL_OUT_OF_MEMORY:

-            context->recordOutOfMemory();

-            TRACE("\t! Error generated: out of memory\n");

-            break;

-        case GL_INVALID_FRAMEBUFFER_OPERATION:

-            context->recordInvalidFramebufferOperation();

-            TRACE("\t! Error generated: invalid framebuffer operation\n");

-            break;

-        default: UNREACHABLE(errorCode);

-        }

-    }

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// main.cpp: DLL entry point and management of thread-local data.
+
+#include "main.h"
+
+#include "resource.h"
+#include "Framebuffer.h"
+#include "Surface.h"
+#include "Common/Thread.hpp"
+#include "common/debug.h"
+
+static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
+
+#if !defined(_MSC_VER)
+#define CONSTRUCTOR __attribute__((constructor))
+#define DESTRUCTOR __attribute__((destructor))
+#else
+#define CONSTRUCTOR
+#define DESTRUCTOR
+#endif
+
+static void glAttachThread()
+{
+	TRACE("()");
+
+	gl::Current *current = new gl::Current;
+
+	if(current)
+	{
+		sw::Thread::setLocalStorage(currentTLS, current);
+
+		current->context = 0;
+		current->display = 0;
+		current->drawSurface = 0;
+		current->readSurface = 0;
+	}
+}
+
+static void glDetachThread()
+{
+	TRACE("()");
+
+	gl::Current *current = (gl::Current*)sw::Thread::getLocalStorage(currentTLS);
+
+	if(current)
+	{
+		delete current;
+	}
+}
+
+CONSTRUCTOR static bool glAttachProcess()
+{
+	TRACE("()");
+
+	#if !(ANGLE_DISABLE_TRACE)
+		FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
+
+		if(debug)
+		{
+			fclose(debug);
+			debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
+			fclose(debug);
+		}
+	#endif
+
+	currentTLS = sw::Thread::allocateLocalStorageKey();
+
+	if(currentTLS == TLS_OUT_OF_INDEXES)
+	{
+		return false;
+	}
+
+	glAttachThread();
+
+	return true;
+}
+
+DESTRUCTOR static void glDetachProcess()
+{
+	TRACE("()");
+
+	glDetachThread();
+
+	sw::Thread::freeLocalStorageKey(currentTLS);
+}
+
+#if defined(_WIN32)
+static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	RECT rect;
+
+	switch(uMsg)
+	{
+	case WM_INITDIALOG:
+		GetWindowRect(GetDesktopWindow(), &rect);
+		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
+		SetTimer(hwnd, 1, 100, NULL);
+		return TRUE;
+	case WM_COMMAND:
+		if(LOWORD(wParam) == IDCANCEL)
+		{
+			EndDialog(hwnd, 0);
+		}
+		break;
+	case WM_TIMER:
+		if(IsDebuggerPresent())
+		{
+			EndDialog(hwnd, 0);
+		}
+	}
+
+	return FALSE;
+}
+
+static void WaitForDebugger(HINSTANCE instance)
+{
+	if(!IsDebuggerPresent())
+	{
+		HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
+		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
+		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
+	}
+}
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+	switch(reason)
+	{
+	case DLL_PROCESS_ATTACH:
+		#ifndef NDEBUG
+			WaitForDebugger(instance);
+		#endif
+		return glAttachProcess();
+		break;
+	case DLL_THREAD_ATTACH:
+		glAttachThread();
+		break;
+	case DLL_THREAD_DETACH:
+		glDetachThread();
+		break;
+	case DLL_PROCESS_DETACH:
+		glDetachProcess();
+		break;
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+#endif
+
+namespace gl
+{
+static gl::Current *getCurrent(void)
+{
+	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
+
+	if(!current)
+	{
+		glAttachThread();
+	}
+
+	return (Current*)sw::Thread::getLocalStorage(currentTLS);
+}
+
+void makeCurrent(Context *context, Display *display, Surface *surface)
+{
+	Current *current = getCurrent();
+
+	current->context = context;
+	current->display = display;
+
+	if(context && display && surface)
+	{
+		context->makeCurrent(surface);
+	}
+}
+
+Context *getContext()
+{
+	Current *current = getCurrent();
+
+	return current->context;
+}
+
+Display *getDisplay()
+{
+	Current *current = getCurrent();
+
+	return current->display;
+}
+
+Device *getDevice()
+{
+	Context *context = getContext();
+
+	return context ? context->getDevice() : 0;
+}
+
+void setCurrentDisplay(Display *dpy)
+{
+	Current *current = getCurrent();
+
+	current->display = dpy;
+}
+
+void setCurrentContext(gl::Context *ctx)
+{
+	Current *current = getCurrent();
+
+	current->context = ctx;
+}
+
+void setCurrentDrawSurface(Surface *surface)
+{
+	Current *current = getCurrent();
+
+	current->drawSurface = surface;
+}
+
+Surface *getCurrentDrawSurface()
+{
+	Current *current = getCurrent();
+
+	return current->drawSurface;
+}
+
+void setCurrentReadSurface(Surface *surface)
+{
+	Current *current = getCurrent();
+
+	current->readSurface = surface;
+}
+
+Surface *getCurrentReadSurface()
+{
+	Current *current = getCurrent();
+
+	return current->readSurface;
+}
+}
+
+// Records an error code
+void error(GLenum errorCode)
+{
+	gl::Context *context = gl::getContext();
+
+	if(context)
+	{
+		switch(errorCode)
+		{
+		case GL_INVALID_ENUM:
+			context->recordInvalidEnum();
+			TRACE("\t! Error generated: invalid enum\n");
+			break;
+		case GL_INVALID_VALUE:
+			context->recordInvalidValue();
+			TRACE("\t! Error generated: invalid value\n");
+			break;
+		case GL_INVALID_OPERATION:
+			context->recordInvalidOperation();
+			TRACE("\t! Error generated: invalid operation\n");
+			break;
+		case GL_OUT_OF_MEMORY:
+			context->recordOutOfMemory();
+			TRACE("\t! Error generated: out of memory\n");
+			break;
+		case GL_INVALID_FRAMEBUFFER_OPERATION:
+			context->recordInvalidFramebufferOperation();
+			TRACE("\t! Error generated: invalid framebuffer operation\n");
+			break;
+		default: UNREACHABLE(errorCode);
+		}
+	}
+}
diff --git a/src/OpenGL/libGL/main.h b/src/OpenGL/libGL/main.h
index 6b86940..5a49b2b 100644
--- a/src/OpenGL/libGL/main.h
+++ b/src/OpenGL/libGL/main.h
@@ -1,71 +1,74 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// main.h: Management of thread-local data.

-

-#ifndef LIBGL_MAIN_H_

-#define LIBGL_MAIN_H_

-

-#include "Context.h"

-#include "Device.hpp"

-#include "common/debug.h"

-#include "Display.h"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-namespace gl

-{

-	struct Current

-	{

-		Context *context;

-		Display *display;

-		Surface *drawSurface;

-		Surface *readSurface;

-	};

-

-	void makeCurrent(Context *context, Display *display, Surface *surface);

-

-	Context *getContext();

-	Display *getDisplay();

-	Device *getDevice();

-	Surface *getCurrentDrawSurface();

-	Surface *getCurrentReadSurface();

-	

-	void setCurrentDisplay(Display *dpy);

-	void setCurrentContext(gl::Context *ctx);

-	void setCurrentDrawSurface(Surface *surface);

-	void setCurrentReadSurface(Surface *surface);

-}

-

-void error(GLenum errorCode);

-

-template<class T>

-T &error(GLenum errorCode, T &returnValue)

-{

-    error(errorCode);

-

-    return returnValue;

-}

-

-template<class T>

-const T &error(GLenum errorCode, const T &returnValue)

-{

-    error(errorCode);

-

-    return returnValue;

-}

-

-extern sw::FrameBuffer *createFrameBuffer(void *display, NativeWindowType window, int width, int height);

-

-#endif   // LIBGL_MAIN_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// main.h: Management of thread-local data.
+
+#ifndef LIBGL_MAIN_H_
+#define LIBGL_MAIN_H_
+
+#include "Context.h"
+#include "Device.hpp"
+#include "common/debug.h"
+#include "Display.h"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+namespace gl
+{
+	struct Current
+	{
+		Context *context;
+		Display *display;
+		Surface *drawSurface;
+		Surface *readSurface;
+	};
+
+	void makeCurrent(Context *context, Display *display, Surface *surface);
+
+	Context *getContext();
+	Display *getDisplay();
+	Device *getDevice();
+	Surface *getCurrentDrawSurface();
+	Surface *getCurrentReadSurface();
+
+	void setCurrentDisplay(Display *dpy);
+	void setCurrentContext(gl::Context *ctx);
+	void setCurrentDrawSurface(Surface *surface);
+	void setCurrentReadSurface(Surface *surface);
+}
+
+void error(GLenum errorCode);
+
+template<class T>
+T &error(GLenum errorCode, T &returnValue)
+{
+	error(errorCode);
+
+	return returnValue;
+}
+
+template<class T>
+const T &error(GLenum errorCode, const T &returnValue)
+{
+	error(errorCode);
+
+	return returnValue;
+}
+
+extern sw::FrameBuffer *createFrameBuffer(void *display, NativeWindowType window, int width, int height);
+
+#endif   // LIBGL_MAIN_H_
diff --git a/src/OpenGL/libGL/mathutil.h b/src/OpenGL/libGL/mathutil.h
index c0856e2..e6f9ddd 100644
--- a/src/OpenGL/libGL/mathutil.h
+++ b/src/OpenGL/libGL/mathutil.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // mathutil.h: Math and bit manipulation functions.
 
@@ -21,27 +24,27 @@
 {
 inline bool isPow2(int x)
 {
-    return (x & (x - 1)) == 0 && (x != 0);
+	return (x & (x - 1)) == 0 && (x != 0);
 }
 
 inline int log2(int x)
 {
-    int r = 0;
-    while((x >> r) > 1) r++;
-    return r;
+	int r = 0;
+	while((x >> r) > 1) r++;
+	return r;
 }
 
 inline unsigned int ceilPow2(unsigned int x)
 {
-    if(x != 0) x--;
-    x |= x >> 1;
-    x |= x >> 2;
-    x |= x >> 4;
-    x |= x >> 8;
-    x |= x >> 16;
-    x++;
+	if(x != 0) x--;
+	x |= x >> 1;
+	x |= x >> 2;
+	x |= x >> 4;
+	x |= x >> 8;
+	x |= x >> 16;
+	x++;
 
-    return x;
+	return x;
 }
 
 using sw::clamp;
@@ -50,20 +53,20 @@
 template<const int n>
 inline unsigned int unorm(float x)
 {
-    const unsigned int max = 0xFFFFFFFF >> (32 - n);
+	const unsigned int max = 0xFFFFFFFF >> (32 - n);
 
-    if(x > 1)
-    {
-        return max;
-    }
-    else if(x < 0)
-    {
-        return 0;
-    }
-    else
-    {
-        return (unsigned int)(max * x + 0.5f);
-    }
+	if(x > 1)
+	{
+		return max;
+	}
+	else if(x < 0)
+	{
+		return 0;
+	}
+	else
+	{
+		return (unsigned int)(max * x + 0.5f);
+	}
 }
 }
 
diff --git a/src/OpenGL/libGL/utilities.cpp b/src/OpenGL/libGL/utilities.cpp
index f7feb20..5f1e0c2 100644
--- a/src/OpenGL/libGL/utilities.cpp
+++ b/src/OpenGL/libGL/utilities.cpp
@@ -1,868 +1,871 @@
-// 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 gl

-{

-	unsigned int UniformComponentCount(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_BOOL:

-		case GL_FLOAT:

-		case GL_INT:

-		case GL_SAMPLER_2D:

-		case GL_SAMPLER_CUBE:

-			return 1;

-		case GL_BOOL_VEC2:

-		case GL_FLOAT_VEC2:

-		case GL_INT_VEC2:

-			return 2;

-		case GL_INT_VEC3:

-		case GL_FLOAT_VEC3:

-		case GL_BOOL_VEC3:

-			return 3;

-		case GL_BOOL_VEC4:

-		case GL_FLOAT_VEC4:

-		case GL_INT_VEC4:

-		case GL_FLOAT_MAT2:

-			return 4;

-		case GL_FLOAT_MAT3:

-			return 9;

-		case GL_FLOAT_MAT4:

-			return 16;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return 0;

-	}

-

-	GLenum UniformComponentType(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_BOOL:

-		case GL_BOOL_VEC2:

-		case GL_BOOL_VEC3:

-		case GL_BOOL_VEC4:

-			return GL_BOOL;

-		case GL_FLOAT:

-		case GL_FLOAT_VEC2:

-		case GL_FLOAT_VEC3:

-		case GL_FLOAT_VEC4:

-		case GL_FLOAT_MAT2:

-		case GL_FLOAT_MAT3:

-		case GL_FLOAT_MAT4:

-			return GL_FLOAT;

-		case GL_INT:

-		case GL_SAMPLER_2D:

-		case GL_SAMPLER_CUBE:

-		case GL_INT_VEC2:

-		case GL_INT_VEC3:

-		case GL_INT_VEC4:

-			return GL_INT;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return GL_NONE;

-	}

-

-	size_t UniformTypeSize(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_BOOL:  return sizeof(GLboolean);

-		case GL_FLOAT: return sizeof(GLfloat);

-		case GL_INT:   return sizeof(GLint);

-		}

-

-		return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);

-	}

-

-	int VariableRowCount(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_NONE:

-			return 0;

-		case GL_BOOL:

-		case GL_FLOAT:

-		case GL_INT:

-		case GL_BOOL_VEC2:

-		case GL_FLOAT_VEC2:

-		case GL_INT_VEC2:

-		case GL_INT_VEC3:

-		case GL_FLOAT_VEC3:

-		case GL_BOOL_VEC3:

-		case GL_BOOL_VEC4:

-		case GL_FLOAT_VEC4:

-		case GL_INT_VEC4:

-		case GL_SAMPLER_2D:

-		case GL_SAMPLER_CUBE:

-			return 1;

-		case GL_FLOAT_MAT2:

-			return 2;

-		case GL_FLOAT_MAT3:

-			return 3;

-		case GL_FLOAT_MAT4:

-			return 4;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return 0;

-	}

-

-	int VariableColumnCount(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_NONE:

-			return 0;

-		case GL_BOOL:

-		case GL_FLOAT:

-		case GL_INT:

-			return 1;

-		case GL_BOOL_VEC2:

-		case GL_FLOAT_VEC2:

-		case GL_INT_VEC2:

-		case GL_FLOAT_MAT2:

-			return 2;

-		case GL_INT_VEC3:

-		case GL_FLOAT_VEC3:

-		case GL_BOOL_VEC3:

-		case GL_FLOAT_MAT3:

-			return 3;

-		case GL_BOOL_VEC4:

-		case GL_FLOAT_VEC4:

-		case GL_INT_VEC4:

-		case GL_FLOAT_MAT4:

-			return 4;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return 0;

-	}

-

-	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)

-	{

-		ASSERT(allocationSize <= bitsSize);

-

-		unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);

-

-		for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)

-		{

-			if((*bits & mask) == 0)

-			{

-				*bits |= mask;

-				return i;

-			}

-

-			mask <<= 1;

-		}

-

-		return -1;

-	}

-

-	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)

-	{

-		ASSERT(alignment > 0 && isPow2(alignment));

-

-		GLsizei rawPitch = ComputePixelSize(format, type) * width;

-		return (rawPitch + alignment - 1) & ~(alignment - 1);

-	}

-

-	GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)

-	{

-		return ComputeCompressedSize(width, 1, format);

-	}

-

-	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)

-	{

-		switch(format)

-		{

-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-			return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);

-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:

-			return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);

-		default:

-			return 0;

-		}

-	}

-

-	bool IsCompressed(GLenum format)

-	{

-		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||

-		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||

-		       format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||

-		       format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;

-	}

-

-	bool IsDepthTexture(GLenum format)

-	{

-		return format == GL_DEPTH_COMPONENT ||

-		       format == GL_DEPTH_STENCIL_EXT;

-	}

-

-	bool IsStencilTexture(GLenum format)

-	{

-		return format == GL_STENCIL_INDEX ||

-		       format == GL_DEPTH_STENCIL_EXT;

-	}

-

-	// Returns the size, in bytes, of a single texel in an Image

-	int ComputePixelSize(GLenum format, GLenum type)

-	{

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-			switch(format)

-			{

-			case GL_ALPHA:           return sizeof(unsigned char);

-			case GL_LUMINANCE:       return sizeof(unsigned char);

-			case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;

-			case GL_RGB:             return sizeof(unsigned char) * 3;

-			case GL_RGBA:            return sizeof(unsigned char) * 4;

-			case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;

-			default: UNREACHABLE(format);

-			}

-			break;

-		case GL_UNSIGNED_SHORT_4_4_4_4:

-		case GL_UNSIGNED_SHORT_5_5_5_1:

-		case GL_UNSIGNED_SHORT_5_6_5:

-		case GL_UNSIGNED_SHORT:

-			return sizeof(unsigned short);

-		case GL_UNSIGNED_INT:

-		case GL_UNSIGNED_INT_24_8_EXT:

-		case GL_UNSIGNED_INT_8_8_8_8_REV:

-			return sizeof(unsigned int);

-		case GL_FLOAT:

-			switch(format)

-			{

-			case GL_ALPHA:           return sizeof(float);

-			case GL_LUMINANCE:       return sizeof(float);

-			case GL_DEPTH_COMPONENT: return sizeof(float);

-			case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;

-			case GL_RGB:             return sizeof(float) * 3;

-			case GL_RGBA:            return sizeof(float) * 4;

-			default: UNREACHABLE(format);

-			}

-			break;

-		case GL_HALF_FLOAT:

-			switch(format)

-			{

-			case GL_ALPHA:           return sizeof(unsigned short);

-			case GL_LUMINANCE:       return sizeof(unsigned short);

-			case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;

-			case GL_RGB:             return sizeof(unsigned short) * 3;

-			case GL_RGBA:            return sizeof(unsigned short) * 4;

-			default: UNREACHABLE(format);

-			}

-			break;

-		default: UNREACHABLE(type);

-		}

-

-		return 0;

-	}

-

-	bool IsCubemapTextureTarget(GLenum target)

-	{

-		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);

-	}

-

-	int CubeFaceIndex(GLenum cubeFace)

-	{

-		switch(cubeFace)

-		{

-		case GL_TEXTURE_CUBE_MAP:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;

-		default: UNREACHABLE(cubeFace); return 0;

-		}

-	}

-

-	bool IsTextureTarget(GLenum target)

-	{

-		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);

-	}

-

-	// Verify that format/type are one of the combinations from table 3.4.

-	bool CheckTextureFormatType(GLenum format, GLenum type)

-	{

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-			switch(format)

-			{

-			case GL_RGBA:

-			case GL_BGRA_EXT:

-			case GL_RGB:

-			case GL_ALPHA:

-			case GL_LUMINANCE:

-			case GL_LUMINANCE_ALPHA:

-				return true;

-			default:

-				return false;

-			}

-		case GL_FLOAT:

-		case GL_HALF_FLOAT:

-			switch(format)

-			{

-			case GL_RGBA:

-			case GL_RGB:

-			case GL_ALPHA:

-			case GL_LUMINANCE:

-			case GL_LUMINANCE_ALPHA:

-				return true;

-			default:

-				return false;

-			}

-		case GL_UNSIGNED_SHORT_4_4_4_4:

-		case GL_UNSIGNED_SHORT_5_5_5_1:

-			return (format == GL_RGBA);

-		case GL_UNSIGNED_SHORT_5_6_5:

-			return (format == GL_RGB);

-		case GL_UNSIGNED_INT:

-			return (format == GL_DEPTH_COMPONENT);

-		case GL_UNSIGNED_INT_24_8_EXT:

-			return (format == GL_DEPTH_STENCIL_EXT);

-        case GL_UNSIGNED_INT_8_8_8_8_REV:

-            return (format == GL_BGRA);

-		default:

-			return false;

-		}

-	}

-

-	bool IsColorRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_EXT:

-		case GL_RGBA8_EXT:

-			return true;

-		case GL_DEPTH_COMPONENT16:

-        case GL_DEPTH_COMPONENT24:

-		case GL_STENCIL_INDEX8:

-		case GL_DEPTH24_STENCIL8_EXT:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsDepthRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT16:

-        case GL_DEPTH_COMPONENT24:

-		case GL_DEPTH24_STENCIL8_EXT:

-			return true;

-		case GL_STENCIL_INDEX8:

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_EXT:

-		case GL_RGBA8_EXT:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsStencilRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_STENCIL_INDEX8:

-		case GL_DEPTH24_STENCIL8_EXT:

-			return true;

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_EXT:

-		case GL_RGBA8_EXT:

-		case GL_DEPTH_COMPONENT16:

-        case GL_DEPTH_COMPONENT24:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-}

-

-namespace es2sw

-{

-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::DEPTH_NEVER;

-		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;

-		case GL_LESS:     return sw::DEPTH_LESS;

-		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;

-		case GL_EQUAL:    return sw::DEPTH_EQUAL;

-		case GL_GREATER:  return sw::DEPTH_GREATER;

-		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::DEPTH_ALWAYS;

-	}

-

-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::STENCIL_NEVER;

-		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;

-		case GL_LESS:     return sw::STENCIL_LESS;

-		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;

-		case GL_EQUAL:    return sw::STENCIL_EQUAL;

-		case GL_GREATER:  return sw::STENCIL_GREATER;

-		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::STENCIL_ALWAYS;

-	}

-

-	sw::Color<float> ConvertColor(gl::Color color)

-	{

-		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);

-	}

-

-	sw::BlendFactor ConvertBlendFunc(GLenum blend)

-	{

-		switch(blend)

-		{

-		case GL_ZERO:                     return sw::BLEND_ZERO;

-		case GL_ONE:                      return sw::BLEND_ONE;

-		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;

-		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;

-		case GL_DST_COLOR:                return sw::BLEND_DEST;

-		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;

-		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;

-		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;

-		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;

-		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;

-		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;

-		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;

-		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;

-		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;

-		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;

-		default: UNREACHABLE(blend);

-		}

-

-		return sw::BLEND_ZERO;

-	}

-

-	sw::BlendOperation ConvertBlendOp(GLenum blendOp)

-	{

-		switch(blendOp)

-		{

-		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;

-		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;

-		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;

-		case GL_MIN_EXT:               return sw::BLENDOP_MIN;

-		case GL_MAX_EXT:               return sw::BLENDOP_MAX;

-		default: UNREACHABLE(blendOp);

-		}

-

-		return sw::BLENDOP_ADD;

-	}

-

-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)

-	{

-		switch(logicalOperation)

-		{

-		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;

-		case GL_SET:           return sw::LOGICALOP_SET;

-		case GL_COPY:          return sw::LOGICALOP_COPY;

-		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;

-		case GL_NOOP:          return sw::LOGICALOP_NOOP;

-		case GL_INVERT:        return sw::LOGICALOP_INVERT;

-		case GL_AND:           return sw::LOGICALOP_AND;

-		case GL_NAND:          return sw::LOGICALOP_NAND;

-		case GL_OR:            return sw::LOGICALOP_OR;

-		case GL_NOR:           return sw::LOGICALOP_NOR;

-		case GL_XOR:           return sw::LOGICALOP_XOR;

-		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;

-		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;

-		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;

-		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;

-		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;

-		default: UNREACHABLE(logicalOperation);

-		}

-

-		return sw::LOGICALOP_COPY;

-	}

-

-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)

-	{

-		switch(stencilOp)

-		{

-		case GL_ZERO:      return sw::OPERATION_ZERO;

-		case GL_KEEP:      return sw::OPERATION_KEEP;

-		case GL_REPLACE:   return sw::OPERATION_REPLACE;

-		case GL_INCR:      return sw::OPERATION_INCRSAT;

-		case GL_DECR:      return sw::OPERATION_DECRSAT;

-		case GL_INVERT:    return sw::OPERATION_INVERT;

-		case GL_INCR_WRAP: return sw::OPERATION_INCR;

-		case GL_DECR_WRAP: return sw::OPERATION_DECR;

-		default: UNREACHABLE(stencilOp);

-		}

-

-		return sw::OPERATION_KEEP;

-	}

-

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap)

-	{

-		switch(wrap)

-		{

-        case GL_CLAMP:             return sw::ADDRESSING_CLAMP;

-		case GL_REPEAT:            return sw::ADDRESSING_WRAP;

-		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;

-		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;

-		default: UNREACHABLE(wrap);

-		}

-

-		return sw::ADDRESSING_WRAP;

-	}

-

-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)

-	{

-		switch(cullFace)

-		{

-		case GL_FRONT:

-			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);

-		case GL_BACK:

-			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);

-		case GL_FRONT_AND_BACK:

-			return sw::CULL_NONE;   // culling will be handled during draw

-		default: UNREACHABLE(cullFace);

-		}

-

-		return sw::CULL_COUNTERCLOCKWISE;

-	}

-

-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)

-	{

-		return (red   ? 0x00000001 : 0) |

-			   (green ? 0x00000002 : 0) |

-			   (blue  ? 0x00000004 : 0) |

-			   (alpha ? 0x00000008 : 0);

-	}

-

-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)

-	{

-		switch(minFilter)

-		{

-		case GL_NEAREST:

-		case GL_LINEAR:

-			return sw::MIPMAP_NONE;

-			break;

-		case GL_NEAREST_MIPMAP_NEAREST:

-		case GL_LINEAR_MIPMAP_NEAREST:

-			return sw::MIPMAP_POINT;

-			break;

-		case GL_NEAREST_MIPMAP_LINEAR:

-		case GL_LINEAR_MIPMAP_LINEAR:

-			return sw::MIPMAP_LINEAR;

-			break;

-		default:

-			UNREACHABLE(minFilter);

-			return sw::MIPMAP_NONE;

-		}

-	}

-

-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)

-	{

-		if(maxAnisotropy > 1.0f)

-		{

-			return sw::FILTER_ANISOTROPIC;

-		}

-

-		switch(minFilter)

-		{

-		case GL_NEAREST:

-		case GL_NEAREST_MIPMAP_NEAREST:

-		case GL_NEAREST_MIPMAP_LINEAR:

-			return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;

-		case GL_LINEAR:

-		case GL_LINEAR_MIPMAP_NEAREST:

-		case GL_LINEAR_MIPMAP_LINEAR:

-			return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;

-		default:

-			UNREACHABLE(minFilter);

-			return sw::FILTER_LINEAR;

-		}

-	}

-

-	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  gl::PrimitiveType &swPrimitiveType, int &primitiveCount)

-	{

-		switch(primitiveType)

-		{

-		case GL_POINTS:

-			swPrimitiveType = gl::DRAW_POINTLIST;

-			primitiveCount = elementCount;

-			break;

-		case GL_LINES:

-			swPrimitiveType = gl::DRAW_LINELIST;

-			primitiveCount = elementCount / 2;

-			break;

-		case GL_LINE_LOOP:

-			swPrimitiveType = gl::DRAW_LINELOOP;

-			primitiveCount = elementCount;

-			break;

-		case GL_LINE_STRIP:

-			swPrimitiveType = gl::DRAW_LINESTRIP;

-			primitiveCount = elementCount - 1;

-			break;

-		case GL_TRIANGLES:

-			swPrimitiveType = gl::DRAW_TRIANGLELIST;

-			primitiveCount = elementCount / 3;

-			break;

-		case GL_TRIANGLE_STRIP:

-			swPrimitiveType = gl::DRAW_TRIANGLESTRIP;

-			primitiveCount = elementCount - 2;

-			break;

-		case GL_TRIANGLE_FAN:

-			swPrimitiveType = gl::DRAW_TRIANGLEFAN;

-			primitiveCount = elementCount - 2;

-			break;

-        case GL_QUADS:

-            swPrimitiveType = gl::DRAW_QUADLIST;

-			primitiveCount = (elementCount / 4) * 2;

-			break;

-		default:

-			return false;

-		}

-

-		return true;

-	}

-

-	sw::Format ConvertRenderbufferFormat(GLenum format)

-	{

-		switch(format)

-		{

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGBA8_EXT:            return sw::FORMAT_A8R8G8B8;

-		case GL_RGB565:               return sw::FORMAT_R5G6B5;

-		case GL_RGB8_EXT:             return sw::FORMAT_X8R8G8B8;

-		case GL_DEPTH_COMPONENT16:

-        case GL_DEPTH_COMPONENT24:

-		case GL_STENCIL_INDEX8:

-		case GL_DEPTH24_STENCIL8_EXT: return sw::FORMAT_D24S8;

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

-		}

-	}

-}

-

-namespace sw2es

-{

-	unsigned int GetStencilSize(sw::Format stencilFormat)

-	{

-		switch(stencilFormat)

-		{

-		case sw::FORMAT_D24FS8:

-		case sw::FORMAT_D24S8:

-		case sw::FORMAT_D32FS8_TEXTURE:

-			return 8;

-	//	case sw::FORMAT_D24X4S4:

-	//		return 4;

-	//	case sw::FORMAT_D15S1:

-	//		return 1;

-	//	case sw::FORMAT_D16_LOCKABLE:

-		case sw::FORMAT_D32:

-		case sw::FORMAT_D24X8:

-		case sw::FORMAT_D32F_LOCKABLE:

-		case sw::FORMAT_D16:

-			return 0;

-	//	case sw::FORMAT_D32_LOCKABLE:  return 0;

-	//	case sw::FORMAT_S8_LOCKABLE:   return 8;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetAlphaSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 2;

-		case sw::FORMAT_A8R8G8B8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-			return 1;

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_R5G6B5:

-			return 0;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetRedSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_X8R8G8B8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-		case sw::FORMAT_R5G6B5:

-			return 5;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetGreenSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_X8R8G8B8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-			return 5;

-		case sw::FORMAT_R5G6B5:

-			return 6;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetBlueSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_X8R8G8B8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-		case sw::FORMAT_R5G6B5:

-			return 5;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetDepthSize(sw::Format depthFormat)

-	{

-		switch(depthFormat)

-		{

-	//	case sw::FORMAT_D16_LOCKABLE:   return 16;

-		case sw::FORMAT_D32:            return 32;

-	//	case sw::FORMAT_D15S1:          return 15;

-		case sw::FORMAT_D24S8:          return 24;

-		case sw::FORMAT_D24X8:          return 24;

-	//	case sw::FORMAT_D24X4S4:        return 24;

-		case sw::FORMAT_D16:            return 16;

-		case sw::FORMAT_D32F_LOCKABLE:  return 32;

-		case sw::FORMAT_D24FS8:         return 24;

-	//	case sw::FORMAT_D32_LOCKABLE:   return 32;

-	//	case sw::FORMAT_S8_LOCKABLE:    return 0;

-		case sw::FORMAT_D32FS8_TEXTURE: return 32;

-		default:                        return 0;

-		}

-	}

-

-	GLenum ConvertBackBufferFormat(sw::Format format)

-	{

-		switch(format)

-		{

-		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;

-		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_EXT;

-		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;

-		case sw::FORMAT_R5G6B5:   return GL_RGB565;

-		case sw::FORMAT_X8R8G8B8: return GL_RGB8_EXT;

-		default:

-			UNREACHABLE(format);

-		}

-

-		return GL_RGBA4;

-	}

-

-	GLenum ConvertDepthStencilFormat(sw::Format format)

-	{

-		switch(format)

-		{

-		case sw::FORMAT_D16:

-			return GL_DEPTH_COMPONENT16;

-		case sw::FORMAT_D32:

-			return GL_DEPTH_COMPONENT32;

-        case sw::FORMAT_D24X8:

-            return GL_DEPTH_COMPONENT24;

-		case sw::FORMAT_D24S8:

-			return GL_DEPTH24_STENCIL8_EXT;

-		default:

-			UNREACHABLE(format);

-		}

-

-		return GL_DEPTH24_STENCIL8_EXT;

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// utilities.cpp: Conversion functions and other utility routines.
+
+#include "utilities.h"
+
+#include "mathutil.h"
+#include "Context.h"
+#include "common/debug.h"
+
+#include <limits>
+#include <stdio.h>
+
+namespace gl
+{
+	unsigned int UniformComponentCount(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_BOOL:
+		case GL_FLOAT:
+		case GL_INT:
+		case GL_SAMPLER_2D:
+		case GL_SAMPLER_CUBE:
+			return 1;
+		case GL_BOOL_VEC2:
+		case GL_FLOAT_VEC2:
+		case GL_INT_VEC2:
+			return 2;
+		case GL_INT_VEC3:
+		case GL_FLOAT_VEC3:
+		case GL_BOOL_VEC3:
+			return 3;
+		case GL_BOOL_VEC4:
+		case GL_FLOAT_VEC4:
+		case GL_INT_VEC4:
+		case GL_FLOAT_MAT2:
+			return 4;
+		case GL_FLOAT_MAT3:
+			return 9;
+		case GL_FLOAT_MAT4:
+			return 16;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return 0;
+	}
+
+	GLenum UniformComponentType(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_BOOL:
+		case GL_BOOL_VEC2:
+		case GL_BOOL_VEC3:
+		case GL_BOOL_VEC4:
+			return GL_BOOL;
+		case GL_FLOAT:
+		case GL_FLOAT_VEC2:
+		case GL_FLOAT_VEC3:
+		case GL_FLOAT_VEC4:
+		case GL_FLOAT_MAT2:
+		case GL_FLOAT_MAT3:
+		case GL_FLOAT_MAT4:
+			return GL_FLOAT;
+		case GL_INT:
+		case GL_SAMPLER_2D:
+		case GL_SAMPLER_CUBE:
+		case GL_INT_VEC2:
+		case GL_INT_VEC3:
+		case GL_INT_VEC4:
+			return GL_INT;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return GL_NONE;
+	}
+
+	size_t UniformTypeSize(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_BOOL:  return sizeof(GLboolean);
+		case GL_FLOAT: return sizeof(GLfloat);
+		case GL_INT:   return sizeof(GLint);
+		}
+
+		return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
+	}
+
+	int VariableRowCount(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_NONE:
+			return 0;
+		case GL_BOOL:
+		case GL_FLOAT:
+		case GL_INT:
+		case GL_BOOL_VEC2:
+		case GL_FLOAT_VEC2:
+		case GL_INT_VEC2:
+		case GL_INT_VEC3:
+		case GL_FLOAT_VEC3:
+		case GL_BOOL_VEC3:
+		case GL_BOOL_VEC4:
+		case GL_FLOAT_VEC4:
+		case GL_INT_VEC4:
+		case GL_SAMPLER_2D:
+		case GL_SAMPLER_CUBE:
+			return 1;
+		case GL_FLOAT_MAT2:
+			return 2;
+		case GL_FLOAT_MAT3:
+			return 3;
+		case GL_FLOAT_MAT4:
+			return 4;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return 0;
+	}
+
+	int VariableColumnCount(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_NONE:
+			return 0;
+		case GL_BOOL:
+		case GL_FLOAT:
+		case GL_INT:
+			return 1;
+		case GL_BOOL_VEC2:
+		case GL_FLOAT_VEC2:
+		case GL_INT_VEC2:
+		case GL_FLOAT_MAT2:
+			return 2;
+		case GL_INT_VEC3:
+		case GL_FLOAT_VEC3:
+		case GL_BOOL_VEC3:
+		case GL_FLOAT_MAT3:
+			return 3;
+		case GL_BOOL_VEC4:
+		case GL_FLOAT_VEC4:
+		case GL_INT_VEC4:
+		case GL_FLOAT_MAT4:
+			return 4;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return 0;
+	}
+
+	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
+	{
+		ASSERT(allocationSize <= bitsSize);
+
+		unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
+
+		for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
+		{
+			if((*bits & mask) == 0)
+			{
+				*bits |= mask;
+				return i;
+			}
+
+			mask <<= 1;
+		}
+
+		return -1;
+	}
+
+	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
+	{
+		ASSERT(alignment > 0 && isPow2(alignment));
+
+		GLsizei rawPitch = ComputePixelSize(format, type) * width;
+		return (rawPitch + alignment - 1) & ~(alignment - 1);
+	}
+
+	GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
+	{
+		return ComputeCompressedSize(width, 1, format);
+	}
+
+	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
+	{
+		switch(format)
+		{
+		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+			return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
+		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+			return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
+		default:
+			return 0;
+		}
+	}
+
+	bool IsCompressed(GLenum format)
+	{
+		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+		       format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+		       format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+	}
+
+	bool IsDepthTexture(GLenum format)
+	{
+		return format == GL_DEPTH_COMPONENT ||
+		       format == GL_DEPTH_STENCIL_EXT;
+	}
+
+	bool IsStencilTexture(GLenum format)
+	{
+		return format == GL_STENCIL_INDEX ||
+		       format == GL_DEPTH_STENCIL_EXT;
+	}
+
+	// Returns the size, in bytes, of a single texel in an Image
+	int ComputePixelSize(GLenum format, GLenum type)
+	{
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+			switch(format)
+			{
+			case GL_ALPHA:           return sizeof(unsigned char);
+			case GL_LUMINANCE:       return sizeof(unsigned char);
+			case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
+			case GL_RGB:             return sizeof(unsigned char) * 3;
+			case GL_RGBA:            return sizeof(unsigned char) * 4;
+			case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
+			default: UNREACHABLE(format);
+			}
+			break;
+		case GL_UNSIGNED_SHORT_4_4_4_4:
+		case GL_UNSIGNED_SHORT_5_5_5_1:
+		case GL_UNSIGNED_SHORT_5_6_5:
+		case GL_UNSIGNED_SHORT:
+			return sizeof(unsigned short);
+		case GL_UNSIGNED_INT:
+		case GL_UNSIGNED_INT_24_8_EXT:
+		case GL_UNSIGNED_INT_8_8_8_8_REV:
+			return sizeof(unsigned int);
+		case GL_FLOAT:
+			switch(format)
+			{
+			case GL_ALPHA:           return sizeof(float);
+			case GL_LUMINANCE:       return sizeof(float);
+			case GL_DEPTH_COMPONENT: return sizeof(float);
+			case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
+			case GL_RGB:             return sizeof(float) * 3;
+			case GL_RGBA:            return sizeof(float) * 4;
+			default: UNREACHABLE(format);
+			}
+			break;
+		case GL_HALF_FLOAT:
+			switch(format)
+			{
+			case GL_ALPHA:           return sizeof(unsigned short);
+			case GL_LUMINANCE:       return sizeof(unsigned short);
+			case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
+			case GL_RGB:             return sizeof(unsigned short) * 3;
+			case GL_RGBA:            return sizeof(unsigned short) * 4;
+			default: UNREACHABLE(format);
+			}
+			break;
+		default: UNREACHABLE(type);
+		}
+
+		return 0;
+	}
+
+	bool IsCubemapTextureTarget(GLenum target)
+	{
+		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+	}
+
+	int CubeFaceIndex(GLenum cubeFace)
+	{
+		switch(cubeFace)
+		{
+		case GL_TEXTURE_CUBE_MAP:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
+		default: UNREACHABLE(cubeFace); return 0;
+		}
+	}
+
+	bool IsTextureTarget(GLenum target)
+	{
+		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
+	}
+
+	// Verify that format/type are one of the combinations from table 3.4.
+	bool CheckTextureFormatType(GLenum format, GLenum type)
+	{
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+			switch(format)
+			{
+			case GL_RGBA:
+			case GL_BGRA_EXT:
+			case GL_RGB:
+			case GL_ALPHA:
+			case GL_LUMINANCE:
+			case GL_LUMINANCE_ALPHA:
+				return true;
+			default:
+				return false;
+			}
+		case GL_FLOAT:
+		case GL_HALF_FLOAT:
+			switch(format)
+			{
+			case GL_RGBA:
+			case GL_RGB:
+			case GL_ALPHA:
+			case GL_LUMINANCE:
+			case GL_LUMINANCE_ALPHA:
+				return true;
+			default:
+				return false;
+			}
+		case GL_UNSIGNED_SHORT_4_4_4_4:
+		case GL_UNSIGNED_SHORT_5_5_5_1:
+			return (format == GL_RGBA);
+		case GL_UNSIGNED_SHORT_5_6_5:
+			return (format == GL_RGB);
+		case GL_UNSIGNED_INT:
+			return (format == GL_DEPTH_COMPONENT);
+		case GL_UNSIGNED_INT_24_8_EXT:
+			return (format == GL_DEPTH_STENCIL_EXT);
+		case GL_UNSIGNED_INT_8_8_8_8_REV:
+			return (format == GL_BGRA);
+		default:
+			return false;
+		}
+	}
+
+	bool IsColorRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_EXT:
+		case GL_RGBA8_EXT:
+			return true;
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+		case GL_STENCIL_INDEX8:
+		case GL_DEPTH24_STENCIL8_EXT:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsDepthRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+		case GL_DEPTH24_STENCIL8_EXT:
+			return true;
+		case GL_STENCIL_INDEX8:
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_EXT:
+		case GL_RGBA8_EXT:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsStencilRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_STENCIL_INDEX8:
+		case GL_DEPTH24_STENCIL8_EXT:
+			return true;
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_EXT:
+		case GL_RGBA8_EXT:
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+}
+
+namespace es2sw
+{
+	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::DEPTH_NEVER;
+		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
+		case GL_LESS:     return sw::DEPTH_LESS;
+		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
+		case GL_EQUAL:    return sw::DEPTH_EQUAL;
+		case GL_GREATER:  return sw::DEPTH_GREATER;
+		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::DEPTH_ALWAYS;
+	}
+
+	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::STENCIL_NEVER;
+		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
+		case GL_LESS:     return sw::STENCIL_LESS;
+		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
+		case GL_EQUAL:    return sw::STENCIL_EQUAL;
+		case GL_GREATER:  return sw::STENCIL_GREATER;
+		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::STENCIL_ALWAYS;
+	}
+
+	sw::Color<float> ConvertColor(gl::Color color)
+	{
+		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
+	}
+
+	sw::BlendFactor ConvertBlendFunc(GLenum blend)
+	{
+		switch(blend)
+		{
+		case GL_ZERO:                     return sw::BLEND_ZERO;
+		case GL_ONE:                      return sw::BLEND_ONE;
+		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
+		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
+		case GL_DST_COLOR:                return sw::BLEND_DEST;
+		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
+		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
+		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
+		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
+		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
+		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;
+		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
+		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;
+		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
+		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
+		default: UNREACHABLE(blend);
+		}
+
+		return sw::BLEND_ZERO;
+	}
+
+	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
+	{
+		switch(blendOp)
+		{
+		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;
+		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;
+		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
+		case GL_MIN_EXT:               return sw::BLENDOP_MIN;
+		case GL_MAX_EXT:               return sw::BLENDOP_MAX;
+		default: UNREACHABLE(blendOp);
+		}
+
+		return sw::BLENDOP_ADD;
+	}
+
+	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)
+	{
+		switch(logicalOperation)
+		{
+		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;
+		case GL_SET:           return sw::LOGICALOP_SET;
+		case GL_COPY:          return sw::LOGICALOP_COPY;
+		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;
+		case GL_NOOP:          return sw::LOGICALOP_NOOP;
+		case GL_INVERT:        return sw::LOGICALOP_INVERT;
+		case GL_AND:           return sw::LOGICALOP_AND;
+		case GL_NAND:          return sw::LOGICALOP_NAND;
+		case GL_OR:            return sw::LOGICALOP_OR;
+		case GL_NOR:           return sw::LOGICALOP_NOR;
+		case GL_XOR:           return sw::LOGICALOP_XOR;
+		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;
+		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;
+		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;
+		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;
+		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;
+		default: UNREACHABLE(logicalOperation);
+		}
+
+		return sw::LOGICALOP_COPY;
+	}
+
+	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
+	{
+		switch(stencilOp)
+		{
+		case GL_ZERO:      return sw::OPERATION_ZERO;
+		case GL_KEEP:      return sw::OPERATION_KEEP;
+		case GL_REPLACE:   return sw::OPERATION_REPLACE;
+		case GL_INCR:      return sw::OPERATION_INCRSAT;
+		case GL_DECR:      return sw::OPERATION_DECRSAT;
+		case GL_INVERT:    return sw::OPERATION_INVERT;
+		case GL_INCR_WRAP: return sw::OPERATION_INCR;
+		case GL_DECR_WRAP: return sw::OPERATION_DECR;
+		default: UNREACHABLE(stencilOp);
+		}
+
+		return sw::OPERATION_KEEP;
+	}
+
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
+	{
+		switch(wrap)
+		{
+		case GL_CLAMP:             return sw::ADDRESSING_CLAMP;
+		case GL_REPEAT:            return sw::ADDRESSING_WRAP;
+		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;
+		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;
+		default: UNREACHABLE(wrap);
+		}
+
+		return sw::ADDRESSING_WRAP;
+	}
+
+	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
+	{
+		switch(cullFace)
+		{
+		case GL_FRONT:
+			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
+		case GL_BACK:
+			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
+		case GL_FRONT_AND_BACK:
+			return sw::CULL_NONE;   // culling will be handled during draw
+		default: UNREACHABLE(cullFace);
+		}
+
+		return sw::CULL_COUNTERCLOCKWISE;
+	}
+
+	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+	{
+		return (red   ? 0x00000001 : 0) |
+			   (green ? 0x00000002 : 0) |
+			   (blue  ? 0x00000004 : 0) |
+			   (alpha ? 0x00000008 : 0);
+	}
+
+	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
+	{
+		switch(minFilter)
+		{
+		case GL_NEAREST:
+		case GL_LINEAR:
+			return sw::MIPMAP_NONE;
+			break;
+		case GL_NEAREST_MIPMAP_NEAREST:
+		case GL_LINEAR_MIPMAP_NEAREST:
+			return sw::MIPMAP_POINT;
+			break;
+		case GL_NEAREST_MIPMAP_LINEAR:
+		case GL_LINEAR_MIPMAP_LINEAR:
+			return sw::MIPMAP_LINEAR;
+			break;
+		default:
+			UNREACHABLE(minFilter);
+			return sw::MIPMAP_NONE;
+		}
+	}
+
+	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
+	{
+		if(maxAnisotropy > 1.0f)
+		{
+			return sw::FILTER_ANISOTROPIC;
+		}
+
+		switch(minFilter)
+		{
+		case GL_NEAREST:
+		case GL_NEAREST_MIPMAP_NEAREST:
+		case GL_NEAREST_MIPMAP_LINEAR:
+			return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
+		case GL_LINEAR:
+		case GL_LINEAR_MIPMAP_NEAREST:
+		case GL_LINEAR_MIPMAP_LINEAR:
+			return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
+		default:
+			UNREACHABLE(minFilter);
+			return sw::FILTER_LINEAR;
+		}
+	}
+
+	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  gl::PrimitiveType &swPrimitiveType, int &primitiveCount)
+	{
+		switch(primitiveType)
+		{
+		case GL_POINTS:
+			swPrimitiveType = gl::DRAW_POINTLIST;
+			primitiveCount = elementCount;
+			break;
+		case GL_LINES:
+			swPrimitiveType = gl::DRAW_LINELIST;
+			primitiveCount = elementCount / 2;
+			break;
+		case GL_LINE_LOOP:
+			swPrimitiveType = gl::DRAW_LINELOOP;
+			primitiveCount = elementCount;
+			break;
+		case GL_LINE_STRIP:
+			swPrimitiveType = gl::DRAW_LINESTRIP;
+			primitiveCount = elementCount - 1;
+			break;
+		case GL_TRIANGLES:
+			swPrimitiveType = gl::DRAW_TRIANGLELIST;
+			primitiveCount = elementCount / 3;
+			break;
+		case GL_TRIANGLE_STRIP:
+			swPrimitiveType = gl::DRAW_TRIANGLESTRIP;
+			primitiveCount = elementCount - 2;
+			break;
+		case GL_TRIANGLE_FAN:
+			swPrimitiveType = gl::DRAW_TRIANGLEFAN;
+			primitiveCount = elementCount - 2;
+			break;
+		case GL_QUADS:
+			swPrimitiveType = gl::DRAW_QUADLIST;
+			primitiveCount = (elementCount / 4) * 2;
+			break;
+		default:
+			return false;
+		}
+
+		return true;
+	}
+
+	sw::Format ConvertRenderbufferFormat(GLenum format)
+	{
+		switch(format)
+		{
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGBA8_EXT:            return sw::FORMAT_A8R8G8B8;
+		case GL_RGB565:               return sw::FORMAT_R5G6B5;
+		case GL_RGB8_EXT:             return sw::FORMAT_X8R8G8B8;
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+		case GL_STENCIL_INDEX8:
+		case GL_DEPTH24_STENCIL8_EXT: return sw::FORMAT_D24S8;
+		default: UNREACHABLE(format); return sw::FORMAT_A8R8G8B8;
+		}
+	}
+}
+
+namespace sw2es
+{
+	unsigned int GetStencilSize(sw::Format stencilFormat)
+	{
+		switch(stencilFormat)
+		{
+		case sw::FORMAT_D24FS8:
+		case sw::FORMAT_D24S8:
+		case sw::FORMAT_D32FS8_TEXTURE:
+			return 8;
+	//	case sw::FORMAT_D24X4S4:
+	//		return 4;
+	//	case sw::FORMAT_D15S1:
+	//		return 1;
+	//	case sw::FORMAT_D16_LOCKABLE:
+		case sw::FORMAT_D32:
+		case sw::FORMAT_D24X8:
+		case sw::FORMAT_D32F_LOCKABLE:
+		case sw::FORMAT_D16:
+			return 0;
+	//	case sw::FORMAT_D32_LOCKABLE:  return 0;
+	//	case sw::FORMAT_S8_LOCKABLE:   return 8;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetAlphaSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 2;
+		case sw::FORMAT_A8R8G8B8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+			return 1;
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_R5G6B5:
+			return 0;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetRedSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_X8R8G8B8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+		case sw::FORMAT_R5G6B5:
+			return 5;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetGreenSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_X8R8G8B8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+			return 5;
+		case sw::FORMAT_R5G6B5:
+			return 6;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetBlueSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_X8R8G8B8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+		case sw::FORMAT_R5G6B5:
+			return 5;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetDepthSize(sw::Format depthFormat)
+	{
+		switch(depthFormat)
+		{
+	//	case sw::FORMAT_D16_LOCKABLE:   return 16;
+		case sw::FORMAT_D32:            return 32;
+	//	case sw::FORMAT_D15S1:          return 15;
+		case sw::FORMAT_D24S8:          return 24;
+		case sw::FORMAT_D24X8:          return 24;
+	//	case sw::FORMAT_D24X4S4:        return 24;
+		case sw::FORMAT_D16:            return 16;
+		case sw::FORMAT_D32F_LOCKABLE:  return 32;
+		case sw::FORMAT_D24FS8:         return 24;
+	//	case sw::FORMAT_D32_LOCKABLE:   return 32;
+	//	case sw::FORMAT_S8_LOCKABLE:    return 0;
+		case sw::FORMAT_D32FS8_TEXTURE: return 32;
+		default:                        return 0;
+		}
+	}
+
+	GLenum ConvertBackBufferFormat(sw::Format format)
+	{
+		switch(format)
+		{
+		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
+		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_EXT;
+		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
+		case sw::FORMAT_R5G6B5:   return GL_RGB565;
+		case sw::FORMAT_X8R8G8B8: return GL_RGB8_EXT;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_RGBA4;
+	}
+
+	GLenum ConvertDepthStencilFormat(sw::Format format)
+	{
+		switch(format)
+		{
+		case sw::FORMAT_D16:
+			return GL_DEPTH_COMPONENT16;
+		case sw::FORMAT_D32:
+			return GL_DEPTH_COMPONENT32;
+		case sw::FORMAT_D24X8:
+			return GL_DEPTH_COMPONENT24;
+		case sw::FORMAT_D24S8:
+			return GL_DEPTH24_STENCIL8_EXT;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_DEPTH24_STENCIL8_EXT;
+	}
+}
diff --git a/src/OpenGL/libGL/utilities.h b/src/OpenGL/libGL/utilities.h
index 28f9989..82feeaf 100644
--- a/src/OpenGL/libGL/utilities.h
+++ b/src/OpenGL/libGL/utilities.h
@@ -1,88 +1,91 @@
-// 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.h: Conversion functions and other utility routines.

-

-#ifndef LIBGL_UTILITIES_H

-#define LIBGL_UTILITIES_H

-

-#include "Device.hpp"

-#include "Image.hpp"

-#include "Texture.h"

-

-#define _GDI32_

-#include <windows.h>

-#include <GL/GL.h>

-#include <GL/glext.h>

-

-#include <string>

-

-namespace gl

-{

-	struct Color;

-

-	unsigned int UniformComponentCount(GLenum type);

-	GLenum UniformComponentType(GLenum type);

-	size_t UniformTypeSize(GLenum type);

-	int VariableRowCount(GLenum type);

-	int VariableColumnCount(GLenum type);

-

-	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);

-

-	int ComputePixelSize(GLenum format, GLenum type);

-	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);

-	GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);

-	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);

-	bool IsCompressed(GLenum format);

-	bool IsDepthTexture(GLenum format);

-	bool IsStencilTexture(GLenum format);

-	bool IsCubemapTextureTarget(GLenum target);

-	int CubeFaceIndex(GLenum cubeTarget);

-	bool IsTextureTarget(GLenum target);

-	bool CheckTextureFormatType(GLenum format, GLenum type);

-

-	bool IsColorRenderable(GLenum internalformat);

-	bool IsDepthRenderable(GLenum internalformat);

-	bool IsStencilRenderable(GLenum internalformat);

-}

-

-namespace es2sw

-{

-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);

-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);

-	sw::Color<float> ConvertColor(gl::Color color);

-	sw::BlendFactor ConvertBlendFunc(GLenum blend);

-	sw::BlendOperation ConvertBlendOp(GLenum blendOp);

-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);

-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap);

-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);

-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);

-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);

-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);

-	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  gl::PrimitiveType &swPrimitiveType, int &primitiveCount);

-	sw::Format ConvertRenderbufferFormat(GLenum format);

-}

-

-namespace sw2es

-{

-	GLuint GetAlphaSize(sw::Format colorFormat);

-	GLuint GetRedSize(sw::Format colorFormat);

-	GLuint GetGreenSize(sw::Format colorFormat);

-	GLuint GetBlueSize(sw::Format colorFormat);

-	GLuint GetDepthSize(sw::Format depthFormat);

-	GLuint GetStencilSize(sw::Format stencilFormat);

-

-	GLenum ConvertBackBufferFormat(sw::Format format);

-	GLenum ConvertDepthStencilFormat(sw::Format format);

-}

-

-#endif  // LIBGL_UTILITIES_H

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// utilities.h: Conversion functions and other utility routines.
+
+#ifndef LIBGL_UTILITIES_H
+#define LIBGL_UTILITIES_H
+
+#include "Device.hpp"
+#include "Image.hpp"
+#include "Texture.h"
+
+#define _GDI32_
+#include <windows.h>
+#include <GL/GL.h>
+#include <GL/glext.h>
+
+#include <string>
+
+namespace gl
+{
+	struct Color;
+
+	unsigned int UniformComponentCount(GLenum type);
+	GLenum UniformComponentType(GLenum type);
+	size_t UniformTypeSize(GLenum type);
+	int VariableRowCount(GLenum type);
+	int VariableColumnCount(GLenum type);
+
+	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
+
+	int ComputePixelSize(GLenum format, GLenum type);
+	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
+	GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
+	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
+	bool IsCompressed(GLenum format);
+	bool IsDepthTexture(GLenum format);
+	bool IsStencilTexture(GLenum format);
+	bool IsCubemapTextureTarget(GLenum target);
+	int CubeFaceIndex(GLenum cubeTarget);
+	bool IsTextureTarget(GLenum target);
+	bool CheckTextureFormatType(GLenum format, GLenum type);
+
+	bool IsColorRenderable(GLenum internalformat);
+	bool IsDepthRenderable(GLenum internalformat);
+	bool IsStencilRenderable(GLenum internalformat);
+}
+
+namespace es2sw
+{
+	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);
+	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);
+	sw::Color<float> ConvertColor(gl::Color color);
+	sw::BlendFactor ConvertBlendFunc(GLenum blend);
+	sw::BlendOperation ConvertBlendOp(GLenum blendOp);
+	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
+	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap);
+	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
+	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);
+	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
+	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
+	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  gl::PrimitiveType &swPrimitiveType, int &primitiveCount);
+	sw::Format ConvertRenderbufferFormat(GLenum format);
+}
+
+namespace sw2es
+{
+	GLuint GetAlphaSize(sw::Format colorFormat);
+	GLuint GetRedSize(sw::Format colorFormat);
+	GLuint GetGreenSize(sw::Format colorFormat);
+	GLuint GetBlueSize(sw::Format colorFormat);
+	GLuint GetDepthSize(sw::Format depthFormat);
+	GLuint GetStencilSize(sw::Format stencilFormat);
+
+	GLenum ConvertBackBufferFormat(sw::Format format);
+	GLenum ConvertDepthStencilFormat(sw::Format format);
+}
+
+#endif  // LIBGL_UTILITIES_H
diff --git a/src/OpenGL/libGLES_CM/Buffer.cpp b/src/OpenGL/libGLES_CM/Buffer.cpp
index 7377d03..2947284 100644
--- a/src/OpenGL/libGLES_CM/Buffer.cpp
+++ b/src/OpenGL/libGLES_CM/Buffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Buffer.cpp: Implements the Buffer class, representing storage of vertex and/or
 // index data. Implements GL buffer objects and related functionality.
diff --git a/src/OpenGL/libGLES_CM/Buffer.h b/src/OpenGL/libGLES_CM/Buffer.h
index 0310d1c..0ad1069 100644
--- a/src/OpenGL/libGLES_CM/Buffer.h
+++ b/src/OpenGL/libGLES_CM/Buffer.h
@@ -1,53 +1,56 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Buffer.h: Defines the Buffer class, representing storage of vertex and/or

-// index data. Implements GL buffer objects and related functionality.

-// [OpenGL ES 2.0.24] section 2.9 page 21.

-

-#ifndef LIBGLES_CM_BUFFER_H_

-#define LIBGLES_CM_BUFFER_H_

-

-#include "common/Object.hpp"

-#include "Common/Resource.hpp"

-

-#include <GLES/gl.h>

-

-#include <cstddef>

-#include <vector>

-

-namespace es1

-{

-class Buffer : public gl::NamedObject

-{

-  public:

-    explicit Buffer(GLuint name);

-

-    virtual ~Buffer();

-

-    void bufferData(const void *data, GLsizeiptr size, GLenum usage);

-    void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);

-

-	const void *data() { return mContents ? mContents->data() : 0; }

-    size_t size() const { return mSize; }

-    GLenum usage() const { return mUsage; }

-

-	sw::Resource *getResource();

-

-  private:

-    sw::Resource *mContents;

-    size_t mSize;

-    GLenum mUsage;

-};

-

-}

-

-#endif   // LIBGLES_CM_BUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Buffer.h: Defines the Buffer class, representing storage of vertex and/or
+// index data. Implements GL buffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 2.9 page 21.
+
+#ifndef LIBGLES_CM_BUFFER_H_
+#define LIBGLES_CM_BUFFER_H_
+
+#include "common/Object.hpp"
+#include "Common/Resource.hpp"
+
+#include <GLES/gl.h>
+
+#include <cstddef>
+#include <vector>
+
+namespace es1
+{
+class Buffer : public gl::NamedObject
+{
+public:
+	explicit Buffer(GLuint name);
+
+	virtual ~Buffer();
+
+	void bufferData(const void *data, GLsizeiptr size, GLenum usage);
+	void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
+
+	const void *data() { return mContents ? mContents->data() : 0; }
+	size_t size() const { return mSize; }
+	GLenum usage() const { return mUsage; }
+
+	sw::Resource *getResource();
+
+private:
+	sw::Resource *mContents;
+	size_t mSize;
+	GLenum mUsage;
+};
+
+}
+
+#endif   // LIBGLES_CM_BUFFER_H_
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index 0b1ce44..b659bd9 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -1,3456 +1,3458 @@
-// 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.

-//

-

-// Context.cpp: Implements the es1::Context class, managing all GL state and performing

-// rendering operations. It is the GLES2 specific implementation of EGLContext.

-

-#include "Context.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "ResourceManager.h"

-#include "Buffer.h"

-#include "Framebuffer.h"

-#include "Renderbuffer.h"

-#include "Texture.h"

-#include "VertexDataManager.h"

-#include "IndexDataManager.h"

-#include "libEGL/Display.h"

-#include "libEGL/Surface.h"

-#include "Common/Half.hpp"

-

-#include <EGL/eglext.h>

-

-using std::abs;

-

-namespace es1

-{

-Context::Context(const egl::Config *config, const Context *shareContext)

-    : modelViewStack(MAX_MODELVIEW_STACK_DEPTH),

-      projectionStack(MAX_PROJECTION_STACK_DEPTH),

-	  textureStack0(MAX_TEXTURE_STACK_DEPTH),

-	  textureStack1(MAX_TEXTURE_STACK_DEPTH)

-{

-	sw::Context *context = new sw::Context();

-	device = new es1::Device(context);

-

-	mVertexDataManager = new VertexDataManager(this);

-    mIndexDataManager = new IndexDataManager();

-

-    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);

-

-    mState.depthClearValue = 1.0f;

-    mState.stencilClearValue = 0;

-

-    mState.cullFaceEnabled = false;

-    mState.cullMode = GL_BACK;

-    mState.frontFace = GL_CCW;

-    mState.depthTestEnabled = false;

-    mState.depthFunc = GL_LESS;

-    mState.blendEnabled = false;

-    mState.sourceBlendRGB = GL_ONE;

-    mState.sourceBlendAlpha = GL_ONE;

-    mState.destBlendRGB = GL_ZERO;

-    mState.destBlendAlpha = GL_ZERO;

-    mState.blendEquationRGB = GL_FUNC_ADD_OES;

-    mState.blendEquationAlpha = GL_FUNC_ADD_OES;

-    mState.stencilTestEnabled = false;

-    mState.stencilFunc = GL_ALWAYS;

-    mState.stencilRef = 0;

-    mState.stencilMask = -1;

-    mState.stencilWritemask = -1;

-    mState.stencilFail = GL_KEEP;

-    mState.stencilPassDepthFail = GL_KEEP;

-    mState.stencilPassDepthPass = GL_KEEP;

-    mState.polygonOffsetFillEnabled = false;

-    mState.polygonOffsetFactor = 0.0f;

-    mState.polygonOffsetUnits = 0.0f;

-    mState.sampleAlphaToCoverageEnabled = false;

-    mState.sampleCoverageEnabled = false;

-    mState.sampleCoverageValue = 1.0f;

-    mState.sampleCoverageInvert = false;

-    mState.scissorTestEnabled = false;

-    mState.ditherEnabled = true;

-	mState.shadeModel = GL_SMOOTH;

-    mState.generateMipmapHint = GL_DONT_CARE;

-	mState.perspectiveCorrectionHint = GL_DONT_CARE;

-	mState.fogHint = GL_DONT_CARE;

-

-    mState.lineWidth = 1.0f;

-

-    mState.viewportX = 0;

-    mState.viewportY = 0;

-    mState.viewportWidth = 0;

-    mState.viewportHeight = 0;

-    mState.zNear = 0.0f;

-    mState.zFar = 1.0f;

-

-    mState.scissorX = 0;

-    mState.scissorY = 0;

-    mState.scissorWidth = 0;

-    mState.scissorHeight = 0;

-

-    mState.colorMaskRed = true;

-    mState.colorMaskGreen = true;

-    mState.colorMaskBlue = true;

-    mState.colorMaskAlpha = true;

-    mState.depthMask = true;

-

-	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)

-	{

-		mState.textureUnit[i].color = {0, 0, 0, 0};

-		mState.textureUnit[i].environmentMode = GL_MODULATE;

-		mState.textureUnit[i].combineRGB = GL_MODULATE;

-		mState.textureUnit[i].combineAlpha = GL_MODULATE;

-		mState.textureUnit[i].src0RGB = GL_TEXTURE;

-		mState.textureUnit[i].src1RGB = GL_PREVIOUS;

-		mState.textureUnit[i].src2RGB = GL_CONSTANT;

-		mState.textureUnit[i].src0Alpha = GL_TEXTURE;

-		mState.textureUnit[i].src1Alpha = GL_PREVIOUS;

-		mState.textureUnit[i].src2Alpha = GL_CONSTANT;

-		mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;

-		mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;

-		mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;

-		mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;

-		mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;

-		mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;

-	}

-

-    if(shareContext)

-    {

-        mResourceManager = shareContext->mResourceManager;

-        mResourceManager->addRef();

-    }

-    else

-    {

-        mResourceManager = new ResourceManager();

-    }

-

-    // [OpenGL ES 2.0.24] section 3.7 page 83:

-    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional

-    // and cube map texture state vectors respectively associated with them.

-    // In order that access to these initial textures not be lost, they are treated as texture

-    // objects all of whose names are 0.

-

-    mTexture2DZero = new Texture2D(0);

-    mTextureExternalZero = new TextureExternal(0);

-

-    mState.activeSampler = 0;

-    bindArrayBuffer(0);

-    bindElementArrayBuffer(0);

-    bindTexture2D(0);

-    bindFramebuffer(0);

-    bindRenderbuffer(0);

-

-    mState.packAlignment = 4;

-    mState.unpackAlignment = 4;

-

-    mInvalidEnum = false;

-    mInvalidValue = false;

-    mInvalidOperation = false;

-    mOutOfMemory = false;

-    mInvalidFramebufferOperation = false;

-	mMatrixStackOverflow = false;

-	mMatrixStackUnderflow = false;

-

-	lightingEnabled = false;

-

-	for(int i = 0; i < MAX_LIGHTS; i++)

-	{

-		light[i].enabled = false;

-		light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};

-		light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};

-		light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};

-		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};

-		light[i].direction = {0.0f, 0.0f, -1.0f};

-		light[i].attenuation = {1.0f, 0.0f, 0.0f};

-		light[i].spotExponent = 0.0f;

-		light[i].spotCutoffAngle = 180.0f;

-	}

-

-	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};

-	light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};

-

-	globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};

-	materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};

-	materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};

-	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};

-	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};

-	materialShininess = 0.0f;

-	lightModelTwoSide = false;

-

-	matrixMode = GL_MODELVIEW;

-

-	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)

-	{

-		texture2Denabled[i] = false;

-		textureExternalEnabled[i] = false;

-	}

-

-	clientTexture = GL_TEXTURE0;

-

-	setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);

-

-	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)

-	{

-		setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);

-	}

-

-	setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);

-	setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);

-

-	clipFlags = 0;

-

-	alphaTestEnabled = false;

-	alphaTestFunc = GL_ALWAYS;

-	alphaTestRef = 0;

-

-	fogEnabled = false;

-	fogMode = GL_EXP;

-	fogDensity = 1.0f;

-	fogStart = 0.0f;

-	fogEnd = 1.0f;

-	fogColor = {0, 0, 0, 0};

-

-	lineSmoothEnabled = false;

-	colorMaterialEnabled = false;

-	normalizeEnabled = false;

-	rescaleNormalEnabled = false;

-	multisampleEnabled = true;

-	sampleAlphaToOneEnabled = false;

-

-	colorLogicOpEnabled = false;

-	logicalOperation = GL_COPY;

-

-	pointSpriteEnabled = false;

-	pointSmoothEnabled = false;

-	pointSizeMin = 0.0f;

-	pointSizeMax = 1.0f;

-	pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};

-	pointFadeThresholdSize = 1.0f;

-

-    mHasBeenCurrent = false;

-

-    markAllStateDirty();

-}

-

-Context::~Context()

-{

-    while(!mFramebufferNameSpace.empty())

-    {

-        deleteFramebuffer(mFramebufferNameSpace.firstName());

-    }

-

-    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-    {

-        for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)

-        {

-            mState.samplerTexture[type][sampler] = nullptr;

-        }

-    }

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        mState.vertexAttribute[i].mBoundBuffer = nullptr;

-    }

-

-    mState.arrayBuffer = nullptr;

-    mState.elementArrayBuffer = nullptr;

-    mState.renderbuffer = nullptr;

-

-    mTexture2DZero = nullptr;

-    mTextureExternalZero = nullptr;

-

-    delete mVertexDataManager;

-    delete mIndexDataManager;

-

-    mResourceManager->release();

-	delete device;

-}

-

-void Context::makeCurrent(egl::Surface *surface)

-{

-    if(!mHasBeenCurrent)

-    {

-        mState.viewportX = 0;

-        mState.viewportY = 0;

-        mState.viewportWidth = surface->getWidth();

-        mState.viewportHeight = surface->getHeight();

-

-        mState.scissorX = 0;

-        mState.scissorY = 0;

-        mState.scissorWidth = surface->getWidth();

-        mState.scissorHeight = surface->getHeight();

-

-        mHasBeenCurrent = true;

-    }

-

-    // Wrap the existing resources into GL objects and assign them to the '0' names

-    egl::Image *defaultRenderTarget = surface->getRenderTarget();

-    egl::Image *depthStencil = surface->getDepthStencil();

-

-    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);

-    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);

-    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);

-

-    setFramebufferZero(framebufferZero);

-

-    if(defaultRenderTarget)

-    {

-        defaultRenderTarget->release();

-    }

-

-    if(depthStencil)

-    {

-        depthStencil->release();

-    }

-

-    markAllStateDirty();

-}

-

-int Context::getClientVersion() const

-{

-	return 1;

-}

-

-// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.

-void Context::markAllStateDirty()

-{

-    mDepthStateDirty = true;

-    mMaskStateDirty = true;

-    mBlendStateDirty = true;

-    mStencilStateDirty = true;

-    mPolygonOffsetStateDirty = true;

-    mSampleStateDirty = true;

-    mDitherStateDirty = true;

-    mFrontFaceDirty = true;

-}

-

-void Context::setClearColor(float red, float green, float blue, float alpha)

-{

-    mState.colorClearValue.red = red;

-    mState.colorClearValue.green = green;

-    mState.colorClearValue.blue = blue;

-    mState.colorClearValue.alpha = alpha;

-}

-

-void Context::setClearDepth(float depth)

-{

-    mState.depthClearValue = depth;

-}

-

-void Context::setClearStencil(int stencil)

-{

-    mState.stencilClearValue = stencil;

-}

-

-void Context::setCullFaceEnabled(bool enabled)

-{

-    mState.cullFaceEnabled = enabled;

-}

-

-bool Context::isCullFaceEnabled() const

-{

-    return mState.cullFaceEnabled;

-}

-

-void Context::setCullMode(GLenum mode)

-{

-   mState.cullMode = mode;

-}

-

-void Context::setFrontFace(GLenum front)

-{

-    if(mState.frontFace != front)

-    {

-        mState.frontFace = front;

-        mFrontFaceDirty = true;

-    }

-}

-

-void Context::setDepthTestEnabled(bool enabled)

-{

-    if(mState.depthTestEnabled != enabled)

-    {

-        mState.depthTestEnabled = enabled;

-        mDepthStateDirty = true;

-    }

-}

-

-bool Context::isDepthTestEnabled() const

-{

-    return mState.depthTestEnabled;

-}

-

-void Context::setDepthFunc(GLenum depthFunc)

-{

-    if(mState.depthFunc != depthFunc)

-    {

-        mState.depthFunc = depthFunc;

-        mDepthStateDirty = true;

-    }

-}

-

-void Context::setDepthRange(float zNear, float zFar)

-{

-    mState.zNear = zNear;

-    mState.zFar = zFar;

-}

-

-void Context::setAlphaTestEnabled(bool enabled)

-{

-	alphaTestEnabled = enabled;

-}

-

-bool Context::isAlphaTestEnabled() const

-{

-	return alphaTestEnabled;

-}

-

-void Context::setAlphaFunc(GLenum alphaFunc, GLclampf reference)

-{

-	alphaTestFunc = alphaFunc;

-	alphaTestRef = reference;

-}

-

-void Context::setBlendEnabled(bool enabled)

-{

-    if(mState.blendEnabled != enabled)

-    {

-        mState.blendEnabled = enabled;

-        mBlendStateDirty = true;

-    }

-}

-

-bool Context::isBlendEnabled() const

-{

-    return mState.blendEnabled;

-}

-

-void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)

-{

-    if(mState.sourceBlendRGB != sourceRGB ||

-       mState.sourceBlendAlpha != sourceAlpha ||

-       mState.destBlendRGB != destRGB ||

-       mState.destBlendAlpha != destAlpha)

-    {

-        mState.sourceBlendRGB = sourceRGB;

-        mState.destBlendRGB = destRGB;

-        mState.sourceBlendAlpha = sourceAlpha;

-        mState.destBlendAlpha = destAlpha;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)

-{

-    if(mState.blendEquationRGB != rgbEquation ||

-       mState.blendEquationAlpha != alphaEquation)

-    {

-        mState.blendEquationRGB = rgbEquation;

-        mState.blendEquationAlpha = alphaEquation;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setStencilTestEnabled(bool enabled)

-{

-    if(mState.stencilTestEnabled != enabled)

-    {

-        mState.stencilTestEnabled = enabled;

-        mStencilStateDirty = true;

-    }

-}

-

-bool Context::isStencilTestEnabled() const

-{

-    return mState.stencilTestEnabled;

-}

-

-void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)

-{

-    if(mState.stencilFunc != stencilFunc ||

-       mState.stencilRef != stencilRef ||

-       mState.stencilMask != stencilMask)

-    {

-        mState.stencilFunc = stencilFunc;

-        mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;

-        mState.stencilMask = stencilMask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilWritemask(GLuint stencilWritemask)

-{

-    if(mState.stencilWritemask != stencilWritemask)

-    {

-        mState.stencilWritemask = stencilWritemask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)

-{

-    if(mState.stencilFail != stencilFail ||

-       mState.stencilPassDepthFail != stencilPassDepthFail ||

-       mState.stencilPassDepthPass != stencilPassDepthPass)

-    {

-        mState.stencilFail = stencilFail;

-        mState.stencilPassDepthFail = stencilPassDepthFail;

-        mState.stencilPassDepthPass = stencilPassDepthPass;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setPolygonOffsetFillEnabled(bool enabled)

-{

-    if(mState.polygonOffsetFillEnabled != enabled)

-    {

-        mState.polygonOffsetFillEnabled = enabled;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-bool Context::isPolygonOffsetFillEnabled() const

-{

-    return mState.polygonOffsetFillEnabled;

-}

-

-void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)

-{

-    if(mState.polygonOffsetFactor != factor ||

-       mState.polygonOffsetUnits != units)

-    {

-        mState.polygonOffsetFactor = factor;

-        mState.polygonOffsetUnits = units;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-void Context::setSampleAlphaToCoverageEnabled(bool enabled)

-{

-    if(mState.sampleAlphaToCoverageEnabled != enabled)

-    {

-        mState.sampleAlphaToCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleAlphaToCoverageEnabled() const

-{

-    return mState.sampleAlphaToCoverageEnabled;

-}

-

-void Context::setSampleCoverageEnabled(bool enabled)

-{

-    if(mState.sampleCoverageEnabled != enabled)

-    {

-        mState.sampleCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleCoverageEnabled() const

-{

-    return mState.sampleCoverageEnabled;

-}

-

-void Context::setSampleCoverageParams(GLclampf value, bool invert)

-{

-    if(mState.sampleCoverageValue != value ||

-       mState.sampleCoverageInvert != invert)

-    {

-        mState.sampleCoverageValue = value;

-        mState.sampleCoverageInvert = invert;

-        mSampleStateDirty = true;

-    }

-}

-

-void Context::setScissorTestEnabled(bool enabled)

-{

-    mState.scissorTestEnabled = enabled;

-}

-

-bool Context::isScissorTestEnabled() const

-{

-    return mState.scissorTestEnabled;

-}

-

-void Context::setShadeModel(GLenum mode)

-{

-    mState.shadeModel = mode;

-}

-

-void Context::setDitherEnabled(bool enabled)

-{

-    if(mState.ditherEnabled != enabled)

-    {

-        mState.ditherEnabled = enabled;

-        mDitherStateDirty = true;

-    }

-}

-

-bool Context::isDitherEnabled() const

-{

-    return mState.ditherEnabled;

-}

-

-void Context::setLightingEnabled(bool enable)

-{

-    lightingEnabled = enable;

-}

-

-bool Context::isLightingEnabled() const

-{

-	return lightingEnabled;

-}

-

-void Context::setLightEnabled(int index, bool enable)

-{

-    light[index].enabled = enable;

-}

-

-bool Context::isLightEnabled(int index) const

-{

-	return light[index].enabled;

-}

-

-void Context::setLightAmbient(int index, float r, float g, float b, float a)

-{

-	light[index].ambient = {r, g, b, a};

-}

-

-void Context::setLightDiffuse(int index, float r, float g, float b, float a)

-{

-	light[index].diffuse = {r, g, b, a};

-}

-

-void Context::setLightSpecular(int index, float r, float g, float b, float a)

-{

-	light[index].specular = {r, g, b, a};

-}

-

-void Context::setLightPosition(int index, float x, float y, float z, float w)

-{

-	sw::float4 v = {x, y, z, w};

-

-	// Transform from object coordinates to eye coordinates

-	v = modelViewStack.current() * v;

-

-	light[index].position = {v.x, v.y, v.z, v.w};

-}

-

-void Context::setLightDirection(int index, float x, float y, float z)

-{

-	// FIXME: Transform by inverse of 3x3 model-view matrix

-	light[index].direction = {x, y, z};

-}

-

-void Context::setLightAttenuationConstant(int index, float constant)

-{

-	light[index].attenuation.constant = constant;

-}

-

-void Context::setLightAttenuationLinear(int index, float linear)

-{

-	light[index].attenuation.linear = linear;

-}

-

-void Context::setLightAttenuationQuadratic(int index, float quadratic)

-{

-	light[index].attenuation.quadratic = quadratic;

-}

-

-void Context::setSpotLightExponent(int index, float exponent)

-{

-	light[index].spotExponent = exponent;

-}

-

-void Context::setSpotLightCutoff(int index, float cutoff)

-{

-	light[index].spotCutoffAngle = cutoff;

-}

-

-void Context::setGlobalAmbient(float red, float green, float blue, float alpha)

-{

-	globalAmbient.red = red;

-	globalAmbient.green = green;

-	globalAmbient.blue = blue;

-	globalAmbient.alpha = alpha;

-}

-

-void Context::setMaterialAmbient(float red, float green, float blue, float alpha)

-{

-	materialAmbient.red = red;

-	materialAmbient.green = green;

-	materialAmbient.blue = blue;

-	materialAmbient.alpha = alpha;

-}

-

-void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)

-{

-	materialDiffuse.red = red;

-	materialDiffuse.green = green;

-	materialDiffuse.blue = blue;

-	materialDiffuse.alpha = alpha;

-}

-

-void Context::setMaterialSpecular(float red, float green, float blue, float alpha)

-{

-	materialSpecular.red = red;

-	materialSpecular.green = green;

-	materialSpecular.blue = blue;

-	materialSpecular.alpha = alpha;

-}

-

-void Context::setMaterialEmission(float red, float green, float blue, float alpha)

-{

-	materialEmission.red = red;

-	materialEmission.green = green;

-	materialEmission.blue = blue;

-	materialEmission.alpha = alpha;

-}

-

-void Context::setMaterialShininess(float shininess)

-{

-	materialShininess = shininess;

-}

-

-void Context::setLightModelTwoSide(bool enable)

-{

-	lightModelTwoSide = enable;

-}

-

-void Context::setFogEnabled(bool enable)

-{

-	fogEnabled = enable;

-}

-

-bool Context::isFogEnabled() const

-{

-	return fogEnabled;

-}

-

-void Context::setFogMode(GLenum mode)

-{

-	fogMode = mode;

-}

-

-void Context::setFogDensity(float fogDensity)

-{

-	this->fogDensity = fogDensity;

-}

-

-void Context::setFogStart(float fogStart)

-{

-	this->fogStart = fogStart;

-}

-

-void Context::setFogEnd(float fogEnd)

-{

-	this->fogEnd = fogEnd;

-}

-

-void Context::setFogColor(float r, float g, float b, float a)

-{

-	this->fogColor = {r, g, b, a};

-}

-

-void Context::setTexture2Denabled(bool enable)

-{

-    texture2Denabled[mState.activeSampler] = enable;

-}

-

-bool Context::isTexture2Denabled() const

-{

-	return texture2Denabled[mState.activeSampler];

-}

-

-void Context::setTextureExternalEnabled(bool enable)

-{

-    textureExternalEnabled[mState.activeSampler] = enable;

-}

-

-bool Context::isTextureExternalEnabled() const

-{

-    return textureExternalEnabled[mState.activeSampler];

-}

-

-void Context::setLineWidth(GLfloat width)

-{

-    mState.lineWidth = width;

-	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

-}

-

-void Context::setGenerateMipmapHint(GLenum hint)

-{

-    mState.generateMipmapHint = hint;

-}

-

-void Context::setPerspectiveCorrectionHint(GLenum hint)

-{

-    mState.perspectiveCorrectionHint = hint;

-}

-

-void Context::setFogHint(GLenum hint)

-{

-    mState.fogHint = hint;

-}

-

-void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.viewportX = x;

-    mState.viewportY = y;

-    mState.viewportWidth = width;

-    mState.viewportHeight = height;

-}

-

-void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.scissorX = x;

-    mState.scissorY = y;

-    mState.scissorWidth = width;

-    mState.scissorHeight = height;

-}

-

-void Context::setColorMask(bool red, bool green, bool blue, bool alpha)

-{

-    if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||

-       mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)

-    {

-        mState.colorMaskRed = red;

-        mState.colorMaskGreen = green;

-        mState.colorMaskBlue = blue;

-        mState.colorMaskAlpha = alpha;

-        mMaskStateDirty = true;

-    }

-}

-

-void Context::setDepthMask(bool mask)

-{

-    if(mState.depthMask != mask)

-    {

-        mState.depthMask = mask;

-        mMaskStateDirty = true;

-    }

-}

-

-void Context::setActiveSampler(unsigned int active)

-{

-    mState.activeSampler = active;

-}

-

-GLuint Context::getFramebufferName() const

-{

-    return mState.framebuffer;

-}

-

-GLuint Context::getRenderbufferName() const

-{

-    return mState.renderbuffer.name();

-}

-

-GLuint Context::getArrayBufferName() const

-{

-    return mState.arrayBuffer.name();

-}

-

-void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)

-{

-    mState.vertexAttribute[attribNum].mArrayEnabled = enabled;

-}

-

-const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)

-{

-    return mState.vertexAttribute[attribNum];

-}

-

-void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,

-                                   GLsizei stride, const void *pointer)

-{

-    mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;

-    mState.vertexAttribute[attribNum].mSize = size;

-    mState.vertexAttribute[attribNum].mType = type;

-    mState.vertexAttribute[attribNum].mNormalized = normalized;

-    mState.vertexAttribute[attribNum].mStride = stride;

-    mState.vertexAttribute[attribNum].mPointer = pointer;

-}

-

-const void *Context::getVertexAttribPointer(unsigned int attribNum) const

-{

-    return mState.vertexAttribute[attribNum].mPointer;

-}

-

-const VertexAttributeArray &Context::getVertexAttributes()

-{

-    return mState.vertexAttribute;

-}

-

-void Context::setPackAlignment(GLint alignment)

-{

-    mState.packAlignment = alignment;

-}

-

-GLint Context::getPackAlignment() const

-{

-    return mState.packAlignment;

-}

-

-void Context::setUnpackAlignment(GLint alignment)

-{

-    mState.unpackAlignment = alignment;

-}

-

-GLint Context::getUnpackAlignment() const

-{

-    return mState.unpackAlignment;

-}

-

-GLuint Context::createBuffer()

-{

-    return mResourceManager->createBuffer();

-}

-

-GLuint Context::createTexture()

-{

-    return mResourceManager->createTexture();

-}

-

-GLuint Context::createRenderbuffer()

-{

-    return mResourceManager->createRenderbuffer();

-}

-

-// Returns an unused framebuffer name

-GLuint Context::createFramebuffer()

-{

-	return mFramebufferNameSpace.allocate();

-}

-

-void Context::deleteBuffer(GLuint buffer)

-{

-	detachBuffer(buffer);

-

-    mResourceManager->deleteBuffer(buffer);

-}

-

-void Context::deleteTexture(GLuint texture)

-{

-	detachTexture(texture);

-

-    mResourceManager->deleteTexture(texture);

-}

-

-void Context::deleteRenderbuffer(GLuint renderbuffer)

-{

-	detachRenderbuffer(renderbuffer);

-

-    mResourceManager->deleteRenderbuffer(renderbuffer);

-}

-

-void Context::deleteFramebuffer(GLuint framebuffer)

-{

-	detachFramebuffer(framebuffer);

-

-    Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);

-

-    if(framebufferObject)

-    {

-		delete framebufferObject;

-    }

-}

-

-Buffer *Context::getBuffer(GLuint handle)

-{

-    return mResourceManager->getBuffer(handle);

-}

-

-Texture *Context::getTexture(GLuint handle)

-{

-    return mResourceManager->getTexture(handle);

-}

-

-Renderbuffer *Context::getRenderbuffer(GLuint handle)

-{

-    return mResourceManager->getRenderbuffer(handle);

-}

-

-Framebuffer *Context::getFramebuffer()

-{

-    return getFramebuffer(mState.framebuffer);

-}

-

-void Context::bindArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-    mState.arrayBuffer = getBuffer(buffer);

-}

-

-void Context::bindElementArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-    mState.elementArrayBuffer = getBuffer(buffer);

-}

-

-void Context::bindTexture2D(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);

-

-    mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindTextureExternal(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);

-

-    mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindFramebuffer(GLuint framebuffer)

-{

-    if(!getFramebuffer(framebuffer))

-    {

-		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());

-    }

-

-    mState.framebuffer = framebuffer;

-}

-

-void Context::bindRenderbuffer(GLuint renderbuffer)

-{

-	mResourceManager->checkRenderbufferAllocation(renderbuffer);

-

-    mState.renderbuffer = getRenderbuffer(renderbuffer);

-}

-

-void Context::setFramebufferZero(Framebuffer *buffer)

-{

-	delete mFramebufferNameSpace.remove(0);

-    mFramebufferNameSpace.insert(0, buffer);

-}

-

-void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)

-{

-    Renderbuffer *renderbufferObject = mState.renderbuffer;

-    renderbufferObject->setStorage(renderbuffer);

-}

-

-Framebuffer *Context::getFramebuffer(unsigned int handle)

-{

-	return mFramebufferNameSpace.find(handle);

-}

-

-Buffer *Context::getArrayBuffer()

-{

-    return mState.arrayBuffer;

-}

-

-Buffer *Context::getElementArrayBuffer()

-{

-    return mState.elementArrayBuffer;

-}

-

-Texture2D *Context::getTexture2D()

-{

-    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));

-}

-

-TextureExternal *Context::getTextureExternal()

-{

-    return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));

-}

-

-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)

-{

-    GLuint texid = mState.samplerTexture[type][sampler].name();

-

-    if(texid == 0)   // Special case: 0 refers to different initial textures based on the target

-    {

-        switch(type)

-        {

-        case TEXTURE_2D: return mTexture2DZero;

-        case TEXTURE_EXTERNAL: return mTextureExternalZero;

-        default: UNREACHABLE(type);

-        }

-    }

-

-    return mState.samplerTexture[type][sampler];

-}

-

-bool Context::getBooleanv(GLenum pname, GLboolean *params)

-{

-    switch(pname)

-    {

-    case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;

-    case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;

-    case GL_COLOR_WRITEMASK:

-        params[0] = mState.colorMaskRed;

-        params[1] = mState.colorMaskGreen;

-        params[2] = mState.colorMaskBlue;

-        params[3] = mState.colorMaskAlpha;

-        break;

-    case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;

-    case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;

-    case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;

-    case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;

-    case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;

-    case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;

-    case GL_BLEND:                    *params = mState.blendEnabled;                 break;

-    case GL_DITHER:                   *params = mState.ditherEnabled;                break;

-	case GL_LIGHT_MODEL_TWO_SIDE:     *params = lightModelTwoSide;                   break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getFloatv(GLenum pname, GLfloat *params)

-{

-    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application.

-    switch(pname)

-    {

-    case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;

-    case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;

-    case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;

-    case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;

-    case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-        params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;

-        params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;

-        break;

-    case GL_ALIASED_POINT_SIZE_RANGE:

-        params[0] = ALIASED_POINT_SIZE_RANGE_MIN;

-        params[1] = ALIASED_POINT_SIZE_RANGE_MAX;

-        break;

-	case GL_SMOOTH_LINE_WIDTH_RANGE:

-        params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;

-        params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;

-        break;

-    case GL_SMOOTH_POINT_SIZE_RANGE:

-        params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;

-        params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;

-        break;

-    case GL_DEPTH_RANGE:

-        params[0] = mState.zNear;

-        params[1] = mState.zFar;

-        break;

-    case GL_COLOR_CLEAR_VALUE:

-        params[0] = mState.colorClearValue.red;

-        params[1] = mState.colorClearValue.green;

-        params[2] = mState.colorClearValue.blue;

-        params[3] = mState.colorClearValue.alpha;

-        break;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-        *params = MAX_TEXTURE_MAX_ANISOTROPY;

-		break;

-	case GL_MODELVIEW_MATRIX:

-		for(int i = 0; i < 16; i++)

-		{

-			params[i] = modelViewStack.current()[i % 4][i / 4];

-		}

-		break;

-	case GL_PROJECTION_MATRIX:

-		for(int i = 0; i < 16; i++)

-		{

-			params[i] = projectionStack.current()[i % 4][i / 4];

-		}

-		break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getIntegerv(GLenum pname, GLint *params)

-{

-    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application. You may find it in

-    // Context::getFloatv.

-    switch(pname)

-    {

-    case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;

-	case GL_FRAMEBUFFER_BINDING_OES:          *params = mState.framebuffer;                   break;

-    case GL_RENDERBUFFER_BINDING_OES:         *params = mState.renderbuffer.name();           break;

-    case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;

-    case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;

-    case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;

-	case GL_PERSPECTIVE_CORRECTION_HINT:      *params = mState.perspectiveCorrectionHint;     break;

-    case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;

-    case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;

-    case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;

-    case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;

-    case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;

-    case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;

-    case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;

-    case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;

-    case GL_BLEND_SRC_RGB_OES:                *params = mState.sourceBlendRGB;                break;

-    case GL_BLEND_SRC_ALPHA_OES:              *params = mState.sourceBlendAlpha;              break;

-    case GL_BLEND_DST_RGB_OES:                *params = mState.destBlendRGB;                  break;

-    case GL_BLEND_DST_ALPHA_OES:              *params = mState.destBlendAlpha;                break;

-    case GL_BLEND_EQUATION_RGB_OES:           *params = mState.blendEquationRGB;              break;

-    case GL_BLEND_EQUATION_ALPHA_OES:         *params = mState.blendEquationAlpha;            break;

-    case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;

-    case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;

-    case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;

-	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;

-	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;

-	case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-			int width, height, samples;

-

-            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES)

-            {

-                switch(pname)

-                {

-                case GL_SAMPLE_BUFFERS:

-                    if(samples > 1)

-                    {

-                        *params = 1;

-                    }

-                    else

-                    {

-                        *params = 0;

-                    }

-                    break;

-                case GL_SAMPLES:

-                    *params = samples;

-                    break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:

-		{

-			Framebuffer *framebuffer = getFramebuffer();

-			*params = framebuffer->getImplementationColorReadType();

-		}

-		break;

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:

-		{

-			Framebuffer *framebuffer = getFramebuffer();

-			*params = framebuffer->getImplementationColorReadFormat();

-		}

-		break;

-    case GL_MAX_VIEWPORT_DIMS:

-        {

-			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;

-            params[0] = maxDimension;

-            params[1] = maxDimension;

-        }

-        break;

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-        {

-			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)

-			{

-				params[i] = compressedTextureFormats[i];

-			}

-        }

-        break;

-    case GL_VIEWPORT:

-        params[0] = mState.viewportX;

-        params[1] = mState.viewportY;

-        params[2] = mState.viewportWidth;

-        params[3] = mState.viewportHeight;

-        break;

-    case GL_SCISSOR_BOX:

-        params[0] = mState.scissorX;

-        params[1] = mState.scissorY;

-        params[2] = mState.scissorWidth;

-        params[3] = mState.scissorHeight;

-        break;

-    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;

-    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-            Renderbuffer *colorbuffer = framebuffer->getColorbuffer();

-

-            if(colorbuffer)

-            {

-                switch(pname)

-                {

-                case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;

-                case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;

-                case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;

-                case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_DEPTH_BITS:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-

-            if(depthbuffer)

-            {

-                *params = depthbuffer->getDepthSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_STENCIL_BITS:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-

-            if(stencilbuffer)

-            {

-                *params = stencilbuffer->getStencilSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_TEXTURE_BINDING_2D:                  *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();                   break;

-    case GL_TEXTURE_BINDING_CUBE_MAP_OES:        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();                 break;

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:        *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();             break;

-	case GL_MAX_LIGHTS:                          *params = MAX_LIGHTS;                                                                       break;

-    case GL_MAX_MODELVIEW_STACK_DEPTH:           *params = MAX_MODELVIEW_STACK_DEPTH;                                                        break;

-	case GL_MAX_PROJECTION_STACK_DEPTH:          *params = MAX_PROJECTION_STACK_DEPTH;                                                       break;

-	case GL_MAX_TEXTURE_STACK_DEPTH:             *params = MAX_TEXTURE_STACK_DEPTH;                                                          break;

-	case GL_MAX_TEXTURE_UNITS:                   *params = MAX_TEXTURE_UNITS;                                                                break;

-	case GL_MAX_CLIP_PLANES:                     *params = MAX_CLIP_PLANES;                                                                  break;

-	case GL_POINT_SIZE_ARRAY_TYPE_OES:           *params = mState.vertexAttribute[sw::PointSize].mType;                                      break;

-	case GL_POINT_SIZE_ARRAY_STRIDE_OES:         *params = mState.vertexAttribute[sw::PointSize].mStride;                                    break;

-	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name();                        break;

-	case GL_VERTEX_ARRAY_SIZE:                   *params = mState.vertexAttribute[sw::Position].mSize;                                       break;

-	case GL_VERTEX_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Position].mType;                                       break;

-	case GL_VERTEX_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Position].mStride;                                     break;

-	case GL_VERTEX_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name();                         break;

-	case GL_NORMAL_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Normal].mType;                                         break;

-	case GL_NORMAL_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Normal].mStride;                                       break;

-	case GL_NORMAL_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name();                           break;

-	case GL_COLOR_ARRAY_SIZE:                    *params = mState.vertexAttribute[sw::Color0].mSize;                                         break;

-	case GL_COLOR_ARRAY_TYPE:                    *params = mState.vertexAttribute[sw::Color0].mType;                                         break;

-	case GL_COLOR_ARRAY_STRIDE:                  *params = mState.vertexAttribute[sw::Color0].mStride;                                       break;

-	case GL_COLOR_ARRAY_BUFFER_BINDING:          *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name();                           break;

-	case GL_TEXTURE_COORD_ARRAY_SIZE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mSize;               break;

-	case GL_TEXTURE_COORD_ARRAY_TYPE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType;               break;

-	case GL_TEXTURE_COORD_ARRAY_STRIDE:          *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride;             break;

-	case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getPointerv(GLenum pname, const GLvoid **params)

-{

-	switch(pname)

-	{

-	case GL_VERTEX_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Position].mPointer;                         break;

-	case GL_NORMAL_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Normal].mPointer;                           break;

-	case GL_COLOR_ARRAY_POINTER:          *params = mState.vertexAttribute[sw::Color0].mPointer;                           break;

-	case GL_POINT_SIZE_ARRAY_POINTER_OES: *params = mState.vertexAttribute[sw::PointSize].mPointer;                        break;

-	case GL_TEXTURE_COORD_ARRAY_POINTER:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mPointer; break;

-	default:

-		return false;

-	}

-

-	return true;

-}

-

-int Context::getQueryParameterNum(GLenum pname)

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-		return NUM_COMPRESSED_TEXTURE_FORMATS;

-    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:

-    case GL_ARRAY_BUFFER_BINDING:

-    case GL_FRAMEBUFFER_BINDING_OES:

-    case GL_RENDERBUFFER_BINDING_OES:

-    case GL_PACK_ALIGNMENT:

-    case GL_UNPACK_ALIGNMENT:

-    case GL_GENERATE_MIPMAP_HINT:

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-    case GL_DEPTH_BITS:

-    case GL_STENCIL_BITS:

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:

-    case GL_CULL_FACE_MODE:

-    case GL_FRONT_FACE:

-    case GL_ACTIVE_TEXTURE:

-    case GL_STENCIL_FUNC:

-    case GL_STENCIL_VALUE_MASK:

-    case GL_STENCIL_REF:

-    case GL_STENCIL_FAIL:

-    case GL_STENCIL_PASS_DEPTH_FAIL:

-    case GL_STENCIL_PASS_DEPTH_PASS:

-    case GL_DEPTH_FUNC:

-    case GL_BLEND_SRC_RGB_OES:

-    case GL_BLEND_SRC_ALPHA_OES:

-    case GL_BLEND_DST_RGB_OES:

-    case GL_BLEND_DST_ALPHA_OES:

-    case GL_BLEND_EQUATION_RGB_OES:

-    case GL_BLEND_EQUATION_ALPHA_OES:

-    case GL_STENCIL_WRITEMASK:

-    case GL_STENCIL_CLEAR_VALUE:

-    case GL_SUBPIXEL_BITS:

-    case GL_MAX_TEXTURE_SIZE:

-    case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:

-    case GL_TEXTURE_BINDING_2D:

-    case GL_TEXTURE_BINDING_CUBE_MAP_OES:

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:

-        return 1;

-    case GL_MAX_VIEWPORT_DIMS:

-        return 2;

-    case GL_VIEWPORT:

-    case GL_SCISSOR_BOX:

-        return 4;

-    case GL_SAMPLE_COVERAGE_INVERT:

-    case GL_DEPTH_WRITEMASK:

-    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,

-    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural

-    case GL_SAMPLE_COVERAGE:

-    case GL_SCISSOR_TEST:

-    case GL_STENCIL_TEST:

-    case GL_DEPTH_TEST:

-    case GL_BLEND:

-    case GL_DITHER:

-        return 1;

-    case GL_COLOR_WRITEMASK:

-        return 4;

-    case GL_POLYGON_OFFSET_FACTOR:

-    case GL_POLYGON_OFFSET_UNITS:

-    case GL_SAMPLE_COVERAGE_VALUE:

-    case GL_DEPTH_CLEAR_VALUE:

-    case GL_LINE_WIDTH:

-        return 1;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-    case GL_ALIASED_POINT_SIZE_RANGE:

-    case GL_DEPTH_RANGE:

-        return 2;

-    case GL_COLOR_CLEAR_VALUE:

-        return 4;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-	case GL_MAX_LIGHTS:

-	case GL_MAX_MODELVIEW_STACK_DEPTH:

-	case GL_MAX_PROJECTION_STACK_DEPTH:

-	case GL_MAX_TEXTURE_STACK_DEPTH:

-	case GL_MAX_TEXTURE_UNITS:

-	case GL_MAX_CLIP_PLANES:

-	case GL_POINT_SIZE_ARRAY_TYPE_OES:

-	case GL_POINT_SIZE_ARRAY_STRIDE_OES:

-	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:

-        return 1;

-	case GL_CURRENT_COLOR:

-		return 4;

-	case GL_CURRENT_NORMAL:

-		return 3;

-	case GL_CURRENT_TEXTURE_COORDS:

-		return 4;

-	case GL_POINT_SIZE:

-	case GL_POINT_SIZE_MIN:

-	case GL_POINT_SIZE_MAX:

-	case GL_POINT_FADE_THRESHOLD_SIZE:

-		return 1;

-	case GL_POINT_DISTANCE_ATTENUATION:

-		return 3;

-	case GL_SMOOTH_POINT_SIZE_RANGE:

-	case GL_SMOOTH_LINE_WIDTH_RANGE:

-		return 2;

-	case GL_SHADE_MODEL:

-	case GL_MATRIX_MODE:

-	case GL_MODELVIEW_STACK_DEPTH:

-	case GL_PROJECTION_STACK_DEPTH:

-	case GL_TEXTURE_STACK_DEPTH:

-		return 1;

-	case GL_MODELVIEW_MATRIX:

-	case GL_PROJECTION_MATRIX:

-	case GL_TEXTURE_MATRIX:

-		return 16;

-	case GL_ALPHA_TEST_FUNC:

-	case GL_ALPHA_TEST_REF:

-	case GL_BLEND_DST:

-	case GL_BLEND_SRC:

-	case GL_LOGIC_OP_MODE:

-	case GL_VERTEX_ARRAY_SIZE:

-	case GL_VERTEX_ARRAY_TYPE:

-	case GL_VERTEX_ARRAY_STRIDE:

-	case GL_NORMAL_ARRAY_TYPE:

-	case GL_NORMAL_ARRAY_STRIDE:

-	case GL_COLOR_ARRAY_SIZE:

-	case GL_COLOR_ARRAY_TYPE:

-	case GL_COLOR_ARRAY_STRIDE:

-	case GL_TEXTURE_COORD_ARRAY_SIZE:

-	case GL_TEXTURE_COORD_ARRAY_TYPE:

-	case GL_TEXTURE_COORD_ARRAY_STRIDE:

-	case GL_VERTEX_ARRAY_POINTER:

-	case GL_NORMAL_ARRAY_POINTER:

-	case GL_COLOR_ARRAY_POINTER:

-	case GL_TEXTURE_COORD_ARRAY_POINTER:

-	case GL_LIGHT_MODEL_TWO_SIDE:

-		return 1;

-	default:

-		UNREACHABLE(pname);

-    }

-

-    return -1;

-}

-

-bool Context::isQueryParameterInt(GLenum pname)

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:

-    case GL_ARRAY_BUFFER_BINDING:

-    case GL_FRAMEBUFFER_BINDING_OES:

-    case GL_RENDERBUFFER_BINDING_OES:

-    case GL_PACK_ALIGNMENT:

-    case GL_UNPACK_ALIGNMENT:

-    case GL_GENERATE_MIPMAP_HINT:

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-    case GL_DEPTH_BITS:

-    case GL_STENCIL_BITS:

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:

-    case GL_CULL_FACE_MODE:

-    case GL_FRONT_FACE:

-    case GL_ACTIVE_TEXTURE:

-    case GL_STENCIL_FUNC:

-    case GL_STENCIL_VALUE_MASK:

-    case GL_STENCIL_REF:

-    case GL_STENCIL_FAIL:

-    case GL_STENCIL_PASS_DEPTH_FAIL:

-    case GL_STENCIL_PASS_DEPTH_PASS:

-    case GL_DEPTH_FUNC:

-    case GL_BLEND_SRC_RGB_OES:

-    case GL_BLEND_SRC_ALPHA_OES:

-    case GL_BLEND_DST_RGB_OES:

-    case GL_BLEND_DST_ALPHA_OES:

-    case GL_BLEND_EQUATION_RGB_OES:

-    case GL_BLEND_EQUATION_ALPHA_OES:

-    case GL_STENCIL_WRITEMASK:

-    case GL_STENCIL_CLEAR_VALUE:

-    case GL_SUBPIXEL_BITS:

-    case GL_MAX_TEXTURE_SIZE:

-    case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:

-    case GL_TEXTURE_BINDING_2D:

-    case GL_TEXTURE_BINDING_CUBE_MAP_OES:

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:

-    case GL_MAX_VIEWPORT_DIMS:

-    case GL_VIEWPORT:

-    case GL_SCISSOR_BOX:

-	case GL_MAX_LIGHTS:

-	case GL_MAX_MODELVIEW_STACK_DEPTH:

-	case GL_MAX_PROJECTION_STACK_DEPTH:

-	case GL_MAX_TEXTURE_STACK_DEPTH:

-	case GL_MAX_TEXTURE_UNITS:

-	case GL_MAX_CLIP_PLANES:

-	case GL_POINT_SIZE_ARRAY_TYPE_OES:

-	case GL_POINT_SIZE_ARRAY_STRIDE_OES:

-	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:

-        return true;

-    }

-

-    return false;

-}

-

-bool Context::isQueryParameterFloat(GLenum pname)

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_POLYGON_OFFSET_FACTOR:

-    case GL_POLYGON_OFFSET_UNITS:

-    case GL_SAMPLE_COVERAGE_VALUE:

-    case GL_DEPTH_CLEAR_VALUE:

-    case GL_LINE_WIDTH:

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-    case GL_ALIASED_POINT_SIZE_RANGE:

-    case GL_SMOOTH_LINE_WIDTH_RANGE:

-    case GL_SMOOTH_POINT_SIZE_RANGE:

-    case GL_DEPTH_RANGE:

-    case GL_COLOR_CLEAR_VALUE:

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-	case GL_LIGHT_MODEL_AMBIENT:

-	case GL_POINT_SIZE_MIN:

-	case GL_POINT_SIZE_MAX:

-	case GL_POINT_DISTANCE_ATTENUATION:

-	case GL_POINT_FADE_THRESHOLD_SIZE:

-        return true;

-    }

-

-    return false;

-}

-

-bool Context::isQueryParameterBool(GLenum pname)

-{

-    switch(pname)

-    {

-    case GL_SAMPLE_COVERAGE_INVERT:

-    case GL_DEPTH_WRITEMASK:

-    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,

-    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural

-    case GL_SAMPLE_COVERAGE:

-    case GL_SCISSOR_TEST:

-    case GL_STENCIL_TEST:

-    case GL_DEPTH_TEST:

-    case GL_BLEND:

-    case GL_DITHER:

-    case GL_COLOR_WRITEMASK:

-	case GL_LIGHT_MODEL_TWO_SIDE:

-        return true;

-    }

-

-    return false;

-}

-

-bool Context::isQueryParameterPointer(GLenum pname)

-{

-    switch(pname)

-    {

-	case GL_VERTEX_ARRAY_POINTER:

-	case GL_NORMAL_ARRAY_POINTER:

-	case GL_COLOR_ARRAY_POINTER:

-	case GL_TEXTURE_COORD_ARRAY_POINTER:

-	case GL_POINT_SIZE_ARRAY_POINTER_OES:

-        return true;

-    }

-

-    return false;

-}

-

-// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle

-bool Context::applyRenderTarget()

-{

-    Framebuffer *framebuffer = getFramebuffer();

-	int width, height, samples;

-

-    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);

-    }

-

-    egl::Image *renderTarget = framebuffer->getRenderTarget();

-	device->setRenderTarget(0, renderTarget);

-	if(renderTarget) renderTarget->release();

-

-    egl::Image *depthBuffer = framebuffer->getDepthBuffer();

-    device->setDepthBuffer(depthBuffer);

-	if(depthBuffer) depthBuffer->release();

-

-	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();

-	device->setStencilBuffer(stencilBuffer);

-	if(stencilBuffer) stencilBuffer->release();

-

-    Viewport viewport;

-    float zNear = clamp01(mState.zNear);

-    float zFar = clamp01(mState.zFar);

-

-    viewport.x0 = mState.viewportX;

-    viewport.y0 = mState.viewportY;

-    viewport.width = mState.viewportWidth;

-    viewport.height = mState.viewportHeight;

-    viewport.minZ = zNear;

-    viewport.maxZ = zFar;

-

-    device->setViewport(viewport);

-

-    if(mState.scissorTestEnabled)

-    {

-		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};

-		scissor.clip(0, 0, width, height);

-

-		device->setScissorRect(scissor);

-        device->setScissorEnable(true);

-    }

-    else

-    {

-        device->setScissorEnable(false);

-    }

-

-    return true;

-}

-

-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)

-void Context::applyState(GLenum drawMode)

-{

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(mState.cullFaceEnabled)

-    {

-        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));

-    }

-    else

-    {

-		device->setCullMode(sw::CULL_NONE);

-    }

-

-    if(mDepthStateDirty)

-    {

-        if(mState.depthTestEnabled)

-        {

-			device->setDepthBufferEnable(true);

-			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));

-        }

-        else

-        {

-            device->setDepthBufferEnable(false);

-        }

-

-        mDepthStateDirty = false;

-    }

-

-    if(mBlendStateDirty)

-    {

-        if(mState.blendEnabled)

-        {

-			device->setAlphaBlendEnable(true);

-			device->setSeparateAlphaBlendEnable(true);

-

-			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));

-			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));

-			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));

-

-            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));

-			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));

-			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));

-        }

-        else

-        {

-			device->setAlphaBlendEnable(false);

-        }

-

-        mBlendStateDirty = false;

-    }

-

-    if(mStencilStateDirty || mFrontFaceDirty)

-    {

-        if(mState.stencilTestEnabled && framebuffer->hasStencil())

-        {

-			device->setStencilEnable(true);

-			device->setTwoSidedStencil(true);

-

-            // get the maximum size of the stencil ref

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;

-

-			device->setStencilWriteMask(mState.stencilWritemask);

-			device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-			device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-			device->setStencilMask(mState.stencilMask);

-

-			device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));

-			device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-			device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-

-			device->setStencilWriteMaskCCW(mState.stencilWritemask);

-			device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-			device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-			device->setStencilMaskCCW(mState.stencilMask);

-

-			device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));

-			device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-			device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-        }

-        else

-        {

-			device->setStencilEnable(false);

-        }

-

-        mStencilStateDirty = false;

-        mFrontFaceDirty = false;

-    }

-

-    if(mMaskStateDirty)

-    {

-		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));

-		device->setDepthWriteEnable(mState.depthMask);

-

-        mMaskStateDirty = false;

-    }

-

-    if(mPolygonOffsetStateDirty)

-    {

-        if(mState.polygonOffsetFillEnabled)

-        {

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-            if(depthbuffer)

-            {

-				device->setSlopeDepthBias(mState.polygonOffsetFactor);

-                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));

-				device->setDepthBias(depthBias);

-            }

-        }

-        else

-        {

-            device->setSlopeDepthBias(0);

-            device->setDepthBias(0);

-        }

-

-        mPolygonOffsetStateDirty = false;

-    }

-

-    if(mSampleStateDirty)

-    {

-        if(mState.sampleAlphaToCoverageEnabled)

-        {

-            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);

-        }

-		else

-		{

-			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);

-		}

-

-        if(mState.sampleCoverageEnabled)

-        {

-            unsigned int mask = 0;

-            if(mState.sampleCoverageValue != 0)

-            {

-				int width, height, samples;

-				framebuffer->completeness(width, height, samples);

-

-                float threshold = 0.5f;

-

-                for(int i = 0; i < samples; i++)

-                {

-                    mask <<= 1;

-

-                    if((i + 1) * mState.sampleCoverageValue >= threshold)

-                    {

-                        threshold += 1.0f;

-                        mask |= 1;

-                    }

-                }

-            }

-

-            if(mState.sampleCoverageInvert)

-            {

-                mask = ~mask;

-            }

-

-			device->setMultiSampleMask(mask);

-        }

-        else

-        {

-			device->setMultiSampleMask(0xFFFFFFFF);

-        }

-

-        mSampleStateDirty = false;

-    }

-

-    if(mDitherStateDirty)

-    {

-    //	UNIMPLEMENTED();   // FIXME

-

-        mDitherStateDirty = false;

-    }

-

-	switch(mState.shadeModel)

-	{

-	default: UNREACHABLE(mState.shadeModel);

-	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;

-	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;

-	}

-

-	device->setLightingEnable(lightingEnabled);

-	device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));

-

-	for(int i = 0; i < MAX_LIGHTS; i++)

-	{

-		device->setLightEnable(i, light[i].enabled);

-		device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));

-		device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));

-		device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));

-		device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);

-

-		if(light[i].position.w != 0.0f)

-		{

-			device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));

-		}

-		else   // Directional light

-		{

-			// Hack: set the position far way

-			float max = sw::max(abs(light[i].position.x), abs(light[i].position.y), abs(light[i].position.z));

-			device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));

-		}

-	}

-

-	device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));

-	device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));

-	device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));

-	device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));

-	device->setMaterialShininess(materialShininess);

-

-    device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);

-	device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-	device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);

-	device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-

-	const sw::Matrix Z(1, 0, 0, 0,

-	                   0, 1, 0, 0,

-	                   0, 0, 0.5, 0.5,

-	                   0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]

-

-    device->setProjectionMatrix(Z * projectionStack.current());

-    device->setModelMatrix(modelViewStack.current());

-    device->setTextureMatrix(0, textureStack0.current());

-	device->setTextureMatrix(1, textureStack1.current());

-	device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);

-	device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);

-	device->setTexGen(0, sw::TEXGEN_NONE);

-	device->setTexGen(1, sw::TEXGEN_NONE);

-

-	device->setAlphaTestEnable(alphaTestEnabled);

-	device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));

-	device->setAlphaReference(alphaTestRef * 0xFF);

-

-	device->setFogEnable(fogEnabled);

-	device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));

-	device->setFogDensity(fogDensity);

-	device->setFogStart(fogStart);

-	device->setFogEnd(fogEnd);

-

-	switch(fogMode)

-	{

-	case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;

-	case GL_EXP:    device->setVertexFogMode(sw::FOG_EXP);    break;

-	case GL_EXP2:   device->setVertexFogMode(sw::FOG_EXP2);   break;

-	default: UNREACHABLE(fogMode);

-	}

-

-	device->setColorLogicOpEnabled(colorLogicOpEnabled);

-	device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));

-

-	device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);

-}

-

-GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)

-{

-    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];

-

-    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);

-    if(err != GL_NO_ERROR)

-    {

-        return err;

-    }

-

-	device->resetInputStreams(false);

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-	{

-		sw::Resource *resource = attributes[i].vertexBuffer;

-		const void *buffer = (char*)resource->data() + attributes[i].offset;

-

-		int stride = attributes[i].stride;

-

-		buffer = (char*)buffer + stride * base;

-

-		sw::Stream attribute(resource, buffer, stride);

-

-		attribute.type = attributes[i].type;

-		attribute.count = attributes[i].count;

-		attribute.normalized = attributes[i].normalized;

-

-		device->setInputStream(i, attribute);

-	}

-

-	return GL_NO_ERROR;

-}

-

-// Applies the indices and element array bindings

-GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)

-{

-    GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);

-

-    if(err == GL_NO_ERROR)

-    {

-        device->setIndexBuffer(indexInfo->indexBuffer);

-    }

-

-    return err;

-}

-

-void Context::applyTextures()

-{

-	for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)

-    {

-        Texture *texture = nullptr;

-

-		if(textureExternalEnabled[unit])

-		{

-			texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);

-		}

-		else if(texture2Denabled[unit])

-		{

-			texture = getSamplerTexture(unit, TEXTURE_2D);

-		}

-

-		if(texture && texture->isSamplerComplete())

-        {

-			texture->autoGenerateMipmaps();

-

-            GLenum wrapS = texture->getWrapS();

-            GLenum wrapT = texture->getWrapT();

-            GLenum minFilter = texture->getMinFilter();

-            GLenum magFilter = texture->getMagFilter();

-			GLfloat maxAnisotropy = texture->getMaxAnisotropy();

-

-			device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));

-            device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));

-

-			device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));

-			device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMipMapFilter(minFilter));

-			device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);

-

-			applyTexture(unit, texture);

-

-			device->setConstantColor(unit, sw::Color<float>(mState.textureUnit[unit].color.red, mState.textureUnit[unit].color.green, mState.textureUnit[unit].color.blue, mState.textureUnit[unit].color.alpha));

-

-			if(mState.textureUnit[unit].environmentMode != GL_COMBINE)

-			{

-				device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE);    // Cs

-				device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-				device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT);   // Cp

-				device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-				device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT);   // Cc

-				device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-

-				device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE);    // As

-				device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-				device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);   // Ap

-				device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-				device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT);   // Ac

-				device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-

-				GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);

-

-				switch(mState.textureUnit[unit].environmentMode)

-				{

-				case GL_REPLACE:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = As

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cs, Av = As

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_MODULATE:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = CpCs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = CpCs, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_DECAL:

-					if(texFormat == GL_ALPHA ||

-					   texFormat == GL_LUMINANCE ||

-					   texFormat == GL_LUMINANCE_ALPHA)

-					{

-						// undefined   // FIXME: Log

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cp(1 - As) + CsAs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);   // Alpha * (Arg1 - Arg2) + Arg2

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_BLEND:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cp(1 - Cs) + CcCs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cp(1 - Cs) + CcCs, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_ADD:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cp + Cs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cp + Cs, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				default:

-					UNREACHABLE(mState.textureUnit[unit].environmentMode);

-				}

-			}

-			else   // GL_COMBINE

-			{

-				device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));

-				device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));

-				device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));

-				device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));

-				device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));

-				device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));

-

-				device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));

-

-				device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));

-				device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));

-				device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));

-				device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));

-				device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));

-				device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));

-

-				device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));

-			}

-        }

-        else

-        {

-            applyTexture(unit, nullptr);

-

-			device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);

-			device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-			device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-

-			device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);

-			device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-			device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);

-        }

-    }

-}

-

-void Context::setTextureEnvMode(GLenum texEnvMode)

-{

-	mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;

-}

-

-void Context::setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	mState.textureUnit[mState.activeSampler].color = {red, green, blue, alpha};

-}

-

-void Context::setCombineRGB(GLenum combineRGB)

-{

-	mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;

-}

-

-void Context::setCombineAlpha(GLenum combineAlpha)

-{

-	mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;

-}

-

-void Context::setOperand0RGB(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand0RGB = operand;

-}

-

-void Context::setOperand1RGB(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand1RGB = operand;

-}

-

-void Context::setOperand2RGB(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand2RGB = operand;

-}

-

-void Context::setOperand0Alpha(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand0Alpha = operand;

-}

-

-void Context::setOperand1Alpha(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand1Alpha = operand;

-}

-

-void Context::setOperand2Alpha(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand2Alpha = operand;

-}

-

-void Context::setSrc0RGB(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src0RGB = src;

-}

-

-void Context::setSrc1RGB(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src1RGB = src;

-}

-

-void Context::setSrc2RGB(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src2RGB = src;

-}

-

-void Context::setSrc0Alpha(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src0Alpha = src;

-}

-

-void Context::setSrc1Alpha(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src1Alpha = src;

-}

-

-void Context::setSrc2Alpha(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src2Alpha = src;

-}

-

-void Context::applyTexture(int index, Texture *baseTexture)

-{

-	sw::Resource *resource = 0;

-

-	if(baseTexture)

-	{

-		resource = baseTexture->getResource();

-	}

-

-	device->setTextureResource(index, resource);

-

-	if(baseTexture)

-	{

-		int levelCount = baseTexture->getLevelCount();

-

-		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)

-		{

-			Texture2D *texture = static_cast<Texture2D*>(baseTexture);

-

-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-			{

-				int surfaceLevel = mipmapLevel;

-

-				if(surfaceLevel < 0)

-				{

-					surfaceLevel = 0;

-				}

-				else if(surfaceLevel >= levelCount)

-				{

-					surfaceLevel = levelCount - 1;

-				}

-

-				egl::Image *surface = texture->getImage(surfaceLevel);

-				device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);

-			}

-		}

-		else UNIMPLEMENTED();

-	}

-	else

-	{

-		device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);

-	}

-}

-

-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,

-                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)

-{

-    Framebuffer *framebuffer = getFramebuffer();

-	int framebufferWidth, framebufferHeight, framebufferSamples;

-

-    if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-    }

-

-    if(getFramebufferName() != 0 && framebufferSamples != 0)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)

-	{

-		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-

-	GLsizei outputPitch = egl::ComputePitch(width, format, type, mState.packAlignment);

-

-	// Sized query sanity check

-    if(bufSize)

-    {

-        int requiredSize = outputPitch * height;

-        if(requiredSize > *bufSize)

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-    }

-

-    egl::Image *renderTarget = framebuffer->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	sw::Rect rect = {x, y, x + width, y + height};

-	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

-

-    unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);

-    unsigned char *dest = (unsigned char*)pixels;

-    int inputPitch = (int)renderTarget->getPitch();

-

-    for(int j = 0; j < rect.y1 - rect.y0; j++)

-    {

-		unsigned short *dest16 = (unsigned short*)dest;

-		unsigned int *dest32 = (unsigned int*)dest;

-

-		if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&

-           format == GL_RGBA && type == GL_UNSIGNED_BYTE)

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 4);

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&

-                format == GL_RGBA && type == GL_UNSIGNED_BYTE)

-        {

-            for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				unsigned int argb = *(unsigned int*)(source + 4 * i);

-

-				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);

-			}

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&

-                format == GL_RGBA && type == GL_UNSIGNED_BYTE)

-        {

-            for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				unsigned int xrgb = *(unsigned int*)(source + 4 * i);

-

-				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;

-			}

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&

-                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)

-        {

-            for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				unsigned int xrgb = *(unsigned int*)(source + 4 * i);

-

-				dest32[i] = xrgb | 0xFF000000;

-			}

-        }

-        else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&

-                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 4);

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&

-                format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 2);

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&

-                format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 2);

-        }

-		else

-		{

-			for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				float r;

-				float g;

-				float b;

-				float a;

-

-				switch(renderTarget->getInternalFormat())

-				{

-				case sw::FORMAT_R5G6B5:

-					{

-						unsigned short rgb = *(unsigned short*)(source + 2 * i);

-

-						a = 1.0f;

-						b = (rgb & 0x001F) * (1.0f / 0x001F);

-						g = (rgb & 0x07E0) * (1.0f / 0x07E0);

-						r = (rgb & 0xF800) * (1.0f / 0xF800);

-					}

-					break;

-				case sw::FORMAT_A1R5G5B5:

-					{

-						unsigned short argb = *(unsigned short*)(source + 2 * i);

-

-						a = (argb & 0x8000) ? 1.0f : 0.0f;

-						b = (argb & 0x001F) * (1.0f / 0x001F);

-						g = (argb & 0x03E0) * (1.0f / 0x03E0);

-						r = (argb & 0x7C00) * (1.0f / 0x7C00);

-					}

-					break;

-				case sw::FORMAT_A8R8G8B8:

-					{

-						unsigned int argb = *(unsigned int*)(source + 4 * i);

-

-						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);

-						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);

-						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);

-					}

-					break;

-				case sw::FORMAT_A8B8G8R8:

-					{

-						unsigned int abgr = *(unsigned int*)(source + 4 * i);

-

-						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);

-						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);

-						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);

-					}

-					break;

-				case sw::FORMAT_X8R8G8B8:

-					{

-						unsigned int xrgb = *(unsigned int*)(source + 4 * i);

-

-						a = 1.0f;

-						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);

-						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);

-					}

-					break;

-				case sw::FORMAT_X8B8G8R8:

-					{

-						unsigned int xbgr = *(unsigned int*)(source + 4 * i);

-

-						a = 1.0f;

-						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);

-						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);

-					}

-					break;

-				case sw::FORMAT_A2R10G10B10:

-					{

-						unsigned int argb = *(unsigned int*)(source + 4 * i);

-

-						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);

-						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);

-						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);

-						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);

-					}

-					break;

-				default:

-					UNIMPLEMENTED();   // FIXME

-					UNREACHABLE(renderTarget->getInternalFormat());

-				}

-

-				switch(format)

-				{

-				case GL_RGBA:

-					switch(type)

-					{

-					case GL_UNSIGNED_BYTE:

-						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);

-						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);

-						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);

-						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				case GL_BGRA_EXT:

-					switch(type)

-					{

-					case GL_UNSIGNED_BYTE:

-						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);

-						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);

-						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);

-						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);

-						break;

-					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:

-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section

-						// this type is packed as follows:

-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0

-						//  --------------------------------------------------------------------------------

-						// |       4th         |        3rd         |        2nd        |   1st component   |

-						//  --------------------------------------------------------------------------------

-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.

-						dest16[i] =

-							((unsigned short)(15 * a + 0.5f) << 12)|

-							((unsigned short)(15 * r + 0.5f) << 8) |

-							((unsigned short)(15 * g + 0.5f) << 4) |

-							((unsigned short)(15 * b + 0.5f) << 0);

-						break;

-					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:

-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section

-						// this type is packed as follows:

-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0

-						//  --------------------------------------------------------------------------------

-						// | 4th |          3rd           |           2nd          |      1st component     |

-						//  --------------------------------------------------------------------------------

-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.

-						dest16[i] =

-							((unsigned short)(     a + 0.5f) << 15) |

-							((unsigned short)(31 * r + 0.5f) << 10) |

-							((unsigned short)(31 * g + 0.5f) << 5) |

-							((unsigned short)(31 * b + 0.5f) << 0);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				case GL_RGB:

-					switch(type)

-					{

-					case GL_UNSIGNED_SHORT_5_6_5:

-						dest16[i] =

-							((unsigned short)(31 * b + 0.5f) << 0) |

-							((unsigned short)(63 * g + 0.5f) << 5) |

-							((unsigned short)(31 * r + 0.5f) << 11);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				default: UNREACHABLE(format);

-				}

-			}

-        }

-

-		source += inputPitch;

-		dest += outputPitch;

-    }

-

-	renderTarget->unlock();

-	renderTarget->release();

-}

-

-void Context::clear(GLbitfield mask)

-{

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    float depth = clamp01(mState.depthClearValue);

-    int stencil = mState.stencilClearValue & 0x000000FF;

-

-	if(mask & GL_COLOR_BUFFER_BIT)

-	{

-		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |

-		                        (mState.colorMaskGreen ? 0x2 : 0) |

-		                        (mState.colorMaskBlue ? 0x4 : 0) |

-		                        (mState.colorMaskAlpha ? 0x8 : 0);

-

-		if(rgbaMask != 0)

-		{

-			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);

-		}

-	}

-

-	if(mask & GL_DEPTH_BUFFER_BIT)

-	{

-		if(mState.depthMask != 0)

-		{

-			device->clearDepth(depth);

-		}

-	}

-

-	if(mask & GL_STENCIL_BUFFER_BIT)

-	{

-		if(mState.stencilWritemask != 0)

-		{

-			device->clearStencil(stencil, mState.stencilWritemask);

-		}

-	}

-}

-

-void Context::drawArrays(GLenum mode, GLint first, GLsizei count)

-{

-    sw::DrawType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-    GLenum err = applyVertexBuffer(0, first, count);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    applyTextures();

-

-    if(!cullSkipsDraw(mode))

-    {

-        device->drawPrimitive(primitiveType, primitiveCount);

-    }

-}

-

-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)

-{

-    if(!indices && !mState.elementArrayBuffer)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    sw::DrawType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-    TranslatedIndexData indexInfo;

-    GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;

-    err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    applyTextures();

-

-    if(!cullSkipsDraw(mode))

-    {

-		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);

-    }

-}

-

-void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)

-{

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

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

-	float targetWidth = (float)renderbuffer->getWidth();

-	float targetHeight = (float)renderbuffer->getHeight();

-	float x0 = 2.0f * x / targetWidth - 1.0f;

-	float y0 = 2.0f * y / targetHeight - 1.0f;

-	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;

-	float y1 = 2.0f * (y + height) / targetHeight - 1.0f;

-	float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);

-

-	float vertices[][3] = {{x0, y0, Zw},

-						   {x0, y1, Zw},

-						   {x1, y0, Zw},

-						   {x1, y1, Zw}};

-

-	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented

-	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);

-	float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);

-	float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);

-	int Ucr = texture->getCropRectU();

-	int Vcr = texture->getCropRectV();

-	int Wcr = texture->getCropRectW();

-	int Hcr = texture->getCropRectH();

-

-	float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},

-							{Ucr / textureWidth, (Vcr + Hcr) / textureHeight},

-							{(Ucr + Wcr) / textureWidth, Vcr / textureHeight},

-							{(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};

-

-	VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];

-	VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];

-	gl::BindingPointer<Buffer> oldArrayBuffer = mState.arrayBuffer;

-	mState.arrayBuffer = nullptr;

-

-	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);

-	glEnableClientState(GL_VERTEX_ARRAY);

-	glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);

-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

-

-	sw::Matrix P = projectionStack.current();

-	sw::Matrix M = modelViewStack.current();

-	sw::Matrix T = textureStack0.current();

-

-	projectionStack.identity();

-	modelViewStack.identity();

-	textureStack0.identity();

-

-	drawArrays(GL_TRIANGLE_STRIP, 0, 4);

-

-	// Restore state

-	mState.vertexAttribute[sw::Position] = oldPositionAttribute;

-	mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;

-	mState.arrayBuffer = oldArrayBuffer;

-	oldArrayBuffer = nullptr;

-	oldPositionAttribute.mBoundBuffer = nullptr;

-	oldTexCoord0Attribute.mBoundBuffer = nullptr;

-	textureStack0.load(T);

-	modelViewStack.load(M);

-	projectionStack.load(P);

-}

-

-void Context::finish()

-{

-	device->finish();

-}

-

-void Context::flush()

-{

-    // We don't queue anything without processing it as fast as possible

-}

-

-void Context::recordInvalidEnum()

-{

-    mInvalidEnum = true;

-}

-

-void Context::recordInvalidValue()

-{

-    mInvalidValue = true;

-}

-

-void Context::recordInvalidOperation()

-{

-    mInvalidOperation = true;

-}

-

-void Context::recordOutOfMemory()

-{

-    mOutOfMemory = true;

-}

-

-void Context::recordInvalidFramebufferOperation()

-{

-    mInvalidFramebufferOperation = true;

-}

-

-void Context::recordMatrixStackOverflow()

-{

-    mMatrixStackOverflow = true;

-}

-

-void Context::recordMatrixStackUnderflow()

-{

-    mMatrixStackUnderflow = true;

-}

-

-// Get one of the recorded errors and clear its flag, if any.

-// [OpenGL ES 2.0.24] section 2.5 page 13.

-GLenum Context::getError()

-{

-    if(mInvalidEnum)

-    {

-        mInvalidEnum = false;

-

-        return GL_INVALID_ENUM;

-    }

-

-    if(mInvalidValue)

-    {

-        mInvalidValue = false;

-

-        return GL_INVALID_VALUE;

-    }

-

-    if(mInvalidOperation)

-    {

-        mInvalidOperation = false;

-

-        return GL_INVALID_OPERATION;

-    }

-

-    if(mOutOfMemory)

-    {

-        mOutOfMemory = false;

-

-        return GL_OUT_OF_MEMORY;

-    }

-

-    if(mInvalidFramebufferOperation)

-    {

-        mInvalidFramebufferOperation = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION_OES;

-    }

-

-	if(mMatrixStackOverflow)

-    {

-        mMatrixStackOverflow = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION_OES;

-    }

-

-	if(mMatrixStackUnderflow)

-    {

-        mMatrixStackUnderflow = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION_OES;

-    }

-

-    return GL_NO_ERROR;

-}

-

-int Context::getSupportedMultisampleCount(int requested)

-{

-	int supported = 0;

-

-	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)

-	{

-		if(supported >= requested)

-		{

-			return supported;

-		}

-

-		supported = multisampleCount[i];

-	}

-

-	return supported;

-}

-

-void Context::detachBuffer(GLuint buffer)

-{

-    // [OpenGL ES 2.0.24] section 2.9 page 22:

-    // If a buffer object is deleted while it is bound, all bindings to that object in the current context

-    // (i.e. in the thread that called Delete-Buffers) are reset to zero.

-

-    if(mState.arrayBuffer.name() == buffer)

-    {

-        mState.arrayBuffer = nullptr;

-    }

-

-    if(mState.elementArrayBuffer.name() == buffer)

-    {

-        mState.elementArrayBuffer = nullptr;

-    }

-

-    for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)

-    {

-        if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)

-        {

-            mState.vertexAttribute[attribute].mBoundBuffer = nullptr;

-        }

-    }

-}

-

-void Context::detachTexture(GLuint texture)

-{

-    // [OpenGL ES 2.0.24] section 3.8 page 84:

-    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are

-    // rebound to texture object zero

-

-    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-    {

-        for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)

-        {

-            if(mState.samplerTexture[type][sampler].name() == texture)

-            {

-                mState.samplerTexture[type][sampler] = nullptr;

-            }

-        }

-    }

-

-    // [OpenGL ES 2.0.24] section 4.4 page 112:

-    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is

-    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this

-    // image was attached in the currently bound framebuffer.

-

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(framebuffer)

-    {

-        framebuffer->detachTexture(texture);

-    }

-}

-

-void Context::detachFramebuffer(GLuint framebuffer)

-{

-    // [OpenGL ES 2.0.24] section 4.4 page 107:

-    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though

-    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.

-

-    if(mState.framebuffer == framebuffer)

-    {

-        bindFramebuffer(0);

-    }

-}

-

-void Context::detachRenderbuffer(GLuint renderbuffer)

-{

-    // [OpenGL ES 2.0.24] section 4.4 page 109:

-    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer

-    // had been executed with the target RENDERBUFFER and name of zero.

-

-    if(mState.renderbuffer.name() == renderbuffer)

-    {

-        bindRenderbuffer(0);

-    }

-

-    // [OpenGL ES 2.0.24] section 4.4 page 111:

-    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,

-    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment

-    // point to which this image was attached in the currently bound framebuffer.

-

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(framebuffer)

-    {

-        framebuffer->detachRenderbuffer(renderbuffer);

-    }

-}

-

-bool Context::cullSkipsDraw(GLenum drawMode)

-{

-    return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);

-}

-

-bool Context::isTriangleMode(GLenum drawMode)

-{

-    switch(drawMode)

-    {

-    case GL_TRIANGLES:

-    case GL_TRIANGLE_FAN:

-    case GL_TRIANGLE_STRIP:

-        return true;

-    case GL_POINTS:

-    case GL_LINES:

-    case GL_LINE_LOOP:

-    case GL_LINE_STRIP:

-        return false;

-    default: UNREACHABLE(drawMode);

-    }

-

-    return false;

-}

-

-void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-    ASSERT(index < MAX_VERTEX_ATTRIBS);

-

-    mState.vertexAttribute[index].mCurrentValue[0] = x;

-    mState.vertexAttribute[index].mCurrentValue[1] = y;

-    mState.vertexAttribute[index].mCurrentValue[2] = z;

-    mState.vertexAttribute[index].mCurrentValue[3] = w;

-

-    mVertexDataManager->dirtyCurrentValue(index);

-}

-

-void Context::bindTexImage(egl::Surface *surface)

-{

-	es1::Texture2D *textureObject = getTexture2D();

-

-    if(textureObject)

-    {

-		textureObject->bindTexImage(surface);

-	}

-}

-

-EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)

-{

-    switch(target)

-    {

-    case EGL_GL_TEXTURE_2D_KHR:

-        break;

-    case EGL_GL_RENDERBUFFER_KHR:

-        break;

-    default:

-        return EGL_BAD_PARAMETER;

-    }

-

-    if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-    {

-        return EGL_BAD_MATCH;

-    }

-

-	if(target == EGL_GL_TEXTURE_2D_KHR)

-    {

-        Texture *texture = getTexture(name);

-

-        if(!texture || texture->getTarget() != GL_TEXTURE_2D)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(texture->isShared(GL_TEXTURE_2D, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling

-        {

-            return EGL_BAD_ACCESS;

-        }

-

-        if(textureLevel != 0 && !texture->isSamplerComplete())

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))

-        {

-            return EGL_BAD_PARAMETER;

-        }

-    }

-    else if(target == EGL_GL_RENDERBUFFER_KHR)

-    {

-        Renderbuffer *renderbuffer = getRenderbuffer(name);

-

-        if(!renderbuffer)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(renderbuffer->isShared())   // Already an EGLImage sibling

-        {

-            return EGL_BAD_ACCESS;

-        }

-    }

-    else UNREACHABLE(target);

-

-	return EGL_SUCCESS;

-}

-

-egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)

-{

-    if(target == EGL_GL_TEXTURE_2D_KHR)

-    {

-        es1::Texture *texture = getTexture(name);

-

-        return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);

-    }

-    else if(target == EGL_GL_RENDERBUFFER_KHR)

-    {

-        es1::Renderbuffer *renderbuffer = getRenderbuffer(name);

-

-        return renderbuffer->createSharedImage();

-    }

-    else UNREACHABLE(target);

-

-	return 0;

-}

-

-Device *Context::getDevice()

-{

-	return device;

-}

-

-void Context::setMatrixMode(GLenum mode)

-{

-    matrixMode = mode;

-}

-

-sw::MatrixStack &Context::currentMatrixStack()

-{

-	switch(matrixMode)

-	{

-	case GL_MODELVIEW:

-		return modelViewStack;

-	case GL_PROJECTION:

-		return projectionStack;

-	case GL_TEXTURE:

-		switch(mState.activeSampler)

-		{

-		case 0: return textureStack0;

-		case 1: return textureStack1;

-		}

-		break;

-	}

-

-	UNREACHABLE(matrixMode);

-	return textureStack0;

-}

-

-void Context::loadIdentity()

-{

-	currentMatrixStack().identity();

-}

-

-void Context::load(const GLfloat *m)

-{

-    currentMatrixStack().load(m);

-}

-

-void Context::pushMatrix()

-{

-	if(!currentMatrixStack().push())

-	{

-		return error(GL_STACK_OVERFLOW);

-	}

-}

-

-void Context::popMatrix()

-{

-    if(!currentMatrixStack().pop())

-	{

-		return error(GL_STACK_OVERFLOW);

-	}

-}

-

-void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-    currentMatrixStack().rotate(angle, x, y, z);

-}

-

-void Context::translate(GLfloat x, GLfloat y, GLfloat z)

-{

-    currentMatrixStack().translate(x, y, z);

-}

-

-void Context::scale(GLfloat x, GLfloat y, GLfloat z)

-{

-    currentMatrixStack().scale(x, y, z);

-}

-

-void Context::multiply(const GLfloat *m)

-{

-    currentMatrixStack().multiply(m);

-}

-

-void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);

-}

-

-void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);

-}

-

-void Context::setClipPlane(int index, const float plane[4])

-{

-	sw::Plane clipPlane = modelViewStack.current() * sw::Plane(plane);

-	device->setClipPlane(index, &clipPlane.A);

-}

-

-void Context::setClipPlaneEnabled(int index, bool enable)

-{

-	clipFlags = (clipFlags & ~((int)!enable << index)) | ((int)enable << index);

-	device->setClipFlags(clipFlags);

-}

-

-bool Context::isClipPlaneEnabled(int index) const

-{

-	return (clipFlags & (1 << index)) != 0;

-}

-

-void Context::setColorLogicOpEnabled(bool enable)

-{

-	colorLogicOpEnabled = enable;

-}

-

-bool Context::isColorLogicOpEnabled() const

-{

-	return colorLogicOpEnabled;

-}

-

-void Context::setLogicalOperation(GLenum logicOp)

-{

-	logicalOperation = logicOp;

-}

-

-void Context::setLineSmoothEnabled(bool enable)

-{

-	lineSmoothEnabled = enable;

-}

-

-bool Context::isLineSmoothEnabled() const

-{

-	return lineSmoothEnabled;

-}

-

-void Context::setColorMaterialEnabled(bool enable)

-{

-	colorMaterialEnabled = enable;

-}

-

-bool Context::isColorMaterialEnabled() const

-{

-	return colorMaterialEnabled;

-}

-

-void Context::setNormalizeEnabled(bool enable)

-{

-	normalizeEnabled = enable;

-}

-

-bool Context::isNormalizeEnabled() const

-{

-	return normalizeEnabled;

-}

-

-void Context::setRescaleNormalEnabled(bool enable)

-{

-	rescaleNormalEnabled = enable;

-}

-

-bool Context::isRescaleNormalEnabled() const

-{

-	return rescaleNormalEnabled;

-}

-

-void Context::setVertexArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::Position].mArrayEnabled = enable;

-}

-

-bool Context::isVertexArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::Position].mArrayEnabled;

-}

-

-void Context::setNormalArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;

-}

-

-bool Context::isNormalArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::Normal].mArrayEnabled;

-}

-

-void Context::setColorArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;

-}

-

-bool Context::isColorArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::Color0].mArrayEnabled;

-}

-

-void Context::setPointSizeArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;

-}

-

-bool Context::isPointSizeArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::PointSize].mArrayEnabled;

-}

-

-void Context::setTextureCoordArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;

-}

-

-bool Context::isTextureCoordArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;

-}

-

-void Context::setMultisampleEnabled(bool enable)

-{

-	multisampleEnabled = enable;

-}

-

-bool Context::isMultisampleEnabled() const

-{

-	return multisampleEnabled;

-}

-

-void Context::setSampleAlphaToOneEnabled(bool enable)

-{

-	sampleAlphaToOneEnabled = enable;

-}

-

-bool Context::isSampleAlphaToOneEnabled() const

-{

-	return sampleAlphaToOneEnabled;

-}

-

-void Context::setPointSpriteEnabled(bool enable)

-{

-	pointSpriteEnabled = enable;

-}

-

-bool Context::isPointSpriteEnabled() const

-{

-	return pointSpriteEnabled;

-}

-

-void Context::setPointSmoothEnabled(bool enable)

-{

-	pointSmoothEnabled = enable;

-}

-

-bool Context::isPointSmoothEnabled() const

-{

-	return pointSmoothEnabled;

-}

-

-

-void Context::setPointSizeMin(float min)

-{

-	pointSizeMin = min;

-}

-

-void Context::setPointSizeMax(float max)

-{

-	pointSizeMax = max;

-}

-

-void Context::setPointDistanceAttenuation(float a, float b, float c)

-{

-	pointDistanceAttenuation = {a, b, c};

-}

-

-void Context::setPointFadeThresholdSize(float threshold)

-{

-	pointFadeThresholdSize = threshold;

-}

-

-void Context::clientActiveTexture(GLenum texture)

-{

-	clientTexture = texture;

-}

-

-GLenum Context::getClientActiveTexture() const

-{

-	return clientTexture;

-}

-

-unsigned int Context::getActiveTexture() const

-{

-	return mState.activeSampler;

-}

-

-}

-

-egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext)

-{

-	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext

-	return new es1::Context(config, static_cast<const es1::Context*>(shareContext));

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Context.cpp: Implements the es1::Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#include "Context.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "ResourceManager.h"
+#include "Buffer.h"
+#include "Framebuffer.h"
+#include "Renderbuffer.h"
+#include "Texture.h"
+#include "VertexDataManager.h"
+#include "IndexDataManager.h"
+#include "libEGL/Display.h"
+#include "libEGL/Surface.h"
+#include "Common/Half.hpp"
+
+#include <EGL/eglext.h>
+
+using std::abs;
+
+namespace es1
+{
+Context::Context(const egl::Config *config, const Context *shareContext)
+	: modelViewStack(MAX_MODELVIEW_STACK_DEPTH),
+	  projectionStack(MAX_PROJECTION_STACK_DEPTH),
+	  textureStack0(MAX_TEXTURE_STACK_DEPTH),
+	  textureStack1(MAX_TEXTURE_STACK_DEPTH)
+{
+	sw::Context *context = new sw::Context();
+	device = new es1::Device(context);
+
+	mVertexDataManager = new VertexDataManager(this);
+	mIndexDataManager = new IndexDataManager();
+
+	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+	mState.depthClearValue = 1.0f;
+	mState.stencilClearValue = 0;
+
+	mState.cullFaceEnabled = false;
+	mState.cullMode = GL_BACK;
+	mState.frontFace = GL_CCW;
+	mState.depthTestEnabled = false;
+	mState.depthFunc = GL_LESS;
+	mState.blendEnabled = false;
+	mState.sourceBlendRGB = GL_ONE;
+	mState.sourceBlendAlpha = GL_ONE;
+	mState.destBlendRGB = GL_ZERO;
+	mState.destBlendAlpha = GL_ZERO;
+	mState.blendEquationRGB = GL_FUNC_ADD_OES;
+	mState.blendEquationAlpha = GL_FUNC_ADD_OES;
+	mState.stencilTestEnabled = false;
+	mState.stencilFunc = GL_ALWAYS;
+	mState.stencilRef = 0;
+	mState.stencilMask = -1;
+	mState.stencilWritemask = -1;
+	mState.stencilFail = GL_KEEP;
+	mState.stencilPassDepthFail = GL_KEEP;
+	mState.stencilPassDepthPass = GL_KEEP;
+	mState.polygonOffsetFillEnabled = false;
+	mState.polygonOffsetFactor = 0.0f;
+	mState.polygonOffsetUnits = 0.0f;
+	mState.sampleAlphaToCoverageEnabled = false;
+	mState.sampleCoverageEnabled = false;
+	mState.sampleCoverageValue = 1.0f;
+	mState.sampleCoverageInvert = false;
+	mState.scissorTestEnabled = false;
+	mState.ditherEnabled = true;
+	mState.shadeModel = GL_SMOOTH;
+	mState.generateMipmapHint = GL_DONT_CARE;
+	mState.perspectiveCorrectionHint = GL_DONT_CARE;
+	mState.fogHint = GL_DONT_CARE;
+
+	mState.lineWidth = 1.0f;
+
+	mState.viewportX = 0;
+	mState.viewportY = 0;
+	mState.viewportWidth = 0;
+	mState.viewportHeight = 0;
+	mState.zNear = 0.0f;
+	mState.zFar = 1.0f;
+
+	mState.scissorX = 0;
+	mState.scissorY = 0;
+	mState.scissorWidth = 0;
+	mState.scissorHeight = 0;
+
+	mState.colorMaskRed = true;
+	mState.colorMaskGreen = true;
+	mState.colorMaskBlue = true;
+	mState.colorMaskAlpha = true;
+	mState.depthMask = true;
+
+	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
+	{
+		mState.textureUnit[i].color = {0, 0, 0, 0};
+		mState.textureUnit[i].environmentMode = GL_MODULATE;
+		mState.textureUnit[i].combineRGB = GL_MODULATE;
+		mState.textureUnit[i].combineAlpha = GL_MODULATE;
+		mState.textureUnit[i].src0RGB = GL_TEXTURE;
+		mState.textureUnit[i].src1RGB = GL_PREVIOUS;
+		mState.textureUnit[i].src2RGB = GL_CONSTANT;
+		mState.textureUnit[i].src0Alpha = GL_TEXTURE;
+		mState.textureUnit[i].src1Alpha = GL_PREVIOUS;
+		mState.textureUnit[i].src2Alpha = GL_CONSTANT;
+		mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;
+		mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;
+		mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;
+		mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;
+		mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;
+		mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;
+	}
+
+	if(shareContext)
+	{
+		mResourceManager = shareContext->mResourceManager;
+		mResourceManager->addRef();
+	}
+	else
+	{
+		mResourceManager = new ResourceManager();
+	}
+
+	// [OpenGL ES 2.0.24] section 3.7 page 83:
+	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
+	// and cube map texture state vectors respectively associated with them.
+	// In order that access to these initial textures not be lost, they are treated as texture
+	// objects all of whose names are 0.
+
+	mTexture2DZero = new Texture2D(0);
+	mTextureExternalZero = new TextureExternal(0);
+
+	mState.activeSampler = 0;
+	bindArrayBuffer(0);
+	bindElementArrayBuffer(0);
+	bindTexture2D(0);
+	bindFramebuffer(0);
+	bindRenderbuffer(0);
+
+	mState.packAlignment = 4;
+	mState.unpackAlignment = 4;
+
+	mInvalidEnum = false;
+	mInvalidValue = false;
+	mInvalidOperation = false;
+	mOutOfMemory = false;
+	mInvalidFramebufferOperation = false;
+	mMatrixStackOverflow = false;
+	mMatrixStackUnderflow = false;
+
+	lightingEnabled = false;
+
+	for(int i = 0; i < MAX_LIGHTS; i++)
+	{
+		light[i].enabled = false;
+		light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};
+		light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
+		light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};
+		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};
+		light[i].direction = {0.0f, 0.0f, -1.0f};
+		light[i].attenuation = {1.0f, 0.0f, 0.0f};
+		light[i].spotExponent = 0.0f;
+		light[i].spotCutoffAngle = 180.0f;
+	}
+
+	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
+	light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
+
+	globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
+	materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
+	materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};
+	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};
+	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};
+	materialShininess = 0.0f;
+	lightModelTwoSide = false;
+
+	matrixMode = GL_MODELVIEW;
+
+	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
+	{
+		texture2Denabled[i] = false;
+		textureExternalEnabled[i] = false;
+	}
+
+	clientTexture = GL_TEXTURE0;
+
+	setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);
+
+	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
+	{
+		setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);
+	}
+
+	setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);
+	setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);
+
+	clipFlags = 0;
+
+	alphaTestEnabled = false;
+	alphaTestFunc = GL_ALWAYS;
+	alphaTestRef = 0;
+
+	fogEnabled = false;
+	fogMode = GL_EXP;
+	fogDensity = 1.0f;
+	fogStart = 0.0f;
+	fogEnd = 1.0f;
+	fogColor = {0, 0, 0, 0};
+
+	lineSmoothEnabled = false;
+	colorMaterialEnabled = false;
+	normalizeEnabled = false;
+	rescaleNormalEnabled = false;
+	multisampleEnabled = true;
+	sampleAlphaToOneEnabled = false;
+
+	colorLogicOpEnabled = false;
+	logicalOperation = GL_COPY;
+
+	pointSpriteEnabled = false;
+	pointSmoothEnabled = false;
+	pointSizeMin = 0.0f;
+	pointSizeMax = 1.0f;
+	pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};
+	pointFadeThresholdSize = 1.0f;
+
+	mHasBeenCurrent = false;
+
+	markAllStateDirty();
+}
+
+Context::~Context()
+{
+	while(!mFramebufferNameSpace.empty())
+	{
+		deleteFramebuffer(mFramebufferNameSpace.firstName());
+	}
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
+		{
+			mState.samplerTexture[type][sampler] = nullptr;
+		}
+	}
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mState.vertexAttribute[i].mBoundBuffer = nullptr;
+	}
+
+	mState.arrayBuffer = nullptr;
+	mState.elementArrayBuffer = nullptr;
+	mState.renderbuffer = nullptr;
+
+	mTexture2DZero = nullptr;
+	mTextureExternalZero = nullptr;
+
+	delete mVertexDataManager;
+	delete mIndexDataManager;
+
+	mResourceManager->release();
+	delete device;
+}
+
+void Context::makeCurrent(egl::Surface *surface)
+{
+	if(!mHasBeenCurrent)
+	{
+		mState.viewportX = 0;
+		mState.viewportY = 0;
+		mState.viewportWidth = surface->getWidth();
+		mState.viewportHeight = surface->getHeight();
+
+		mState.scissorX = 0;
+		mState.scissorY = 0;
+		mState.scissorWidth = surface->getWidth();
+		mState.scissorHeight = surface->getHeight();
+
+		mHasBeenCurrent = true;
+	}
+
+	// Wrap the existing resources into GL objects and assign them to the '0' names
+	egl::Image *defaultRenderTarget = surface->getRenderTarget();
+	egl::Image *depthStencil = surface->getDepthStencil();
+
+	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
+	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
+	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
+
+	setFramebufferZero(framebufferZero);
+
+	if(defaultRenderTarget)
+	{
+		defaultRenderTarget->release();
+	}
+
+	if(depthStencil)
+	{
+		depthStencil->release();
+	}
+
+	markAllStateDirty();
+}
+
+int Context::getClientVersion() const
+{
+	return 1;
+}
+
+// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
+void Context::markAllStateDirty()
+{
+	mDepthStateDirty = true;
+	mMaskStateDirty = true;
+	mBlendStateDirty = true;
+	mStencilStateDirty = true;
+	mPolygonOffsetStateDirty = true;
+	mSampleStateDirty = true;
+	mDitherStateDirty = true;
+	mFrontFaceDirty = true;
+}
+
+void Context::setClearColor(float red, float green, float blue, float alpha)
+{
+	mState.colorClearValue.red = red;
+	mState.colorClearValue.green = green;
+	mState.colorClearValue.blue = blue;
+	mState.colorClearValue.alpha = alpha;
+}
+
+void Context::setClearDepth(float depth)
+{
+	mState.depthClearValue = depth;
+}
+
+void Context::setClearStencil(int stencil)
+{
+	mState.stencilClearValue = stencil;
+}
+
+void Context::setCullFaceEnabled(bool enabled)
+{
+	mState.cullFaceEnabled = enabled;
+}
+
+bool Context::isCullFaceEnabled() const
+{
+	return mState.cullFaceEnabled;
+}
+
+void Context::setCullMode(GLenum mode)
+{
+   mState.cullMode = mode;
+}
+
+void Context::setFrontFace(GLenum front)
+{
+	if(mState.frontFace != front)
+	{
+		mState.frontFace = front;
+		mFrontFaceDirty = true;
+	}
+}
+
+void Context::setDepthTestEnabled(bool enabled)
+{
+	if(mState.depthTestEnabled != enabled)
+	{
+		mState.depthTestEnabled = enabled;
+		mDepthStateDirty = true;
+	}
+}
+
+bool Context::isDepthTestEnabled() const
+{
+	return mState.depthTestEnabled;
+}
+
+void Context::setDepthFunc(GLenum depthFunc)
+{
+	if(mState.depthFunc != depthFunc)
+	{
+		mState.depthFunc = depthFunc;
+		mDepthStateDirty = true;
+	}
+}
+
+void Context::setDepthRange(float zNear, float zFar)
+{
+	mState.zNear = zNear;
+	mState.zFar = zFar;
+}
+
+void Context::setAlphaTestEnabled(bool enabled)
+{
+	alphaTestEnabled = enabled;
+}
+
+bool Context::isAlphaTestEnabled() const
+{
+	return alphaTestEnabled;
+}
+
+void Context::setAlphaFunc(GLenum alphaFunc, GLclampf reference)
+{
+	alphaTestFunc = alphaFunc;
+	alphaTestRef = reference;
+}
+
+void Context::setBlendEnabled(bool enabled)
+{
+	if(mState.blendEnabled != enabled)
+	{
+		mState.blendEnabled = enabled;
+		mBlendStateDirty = true;
+	}
+}
+
+bool Context::isBlendEnabled() const
+{
+	return mState.blendEnabled;
+}
+
+void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
+{
+	if(mState.sourceBlendRGB != sourceRGB ||
+	   mState.sourceBlendAlpha != sourceAlpha ||
+	   mState.destBlendRGB != destRGB ||
+	   mState.destBlendAlpha != destAlpha)
+	{
+		mState.sourceBlendRGB = sourceRGB;
+		mState.destBlendRGB = destRGB;
+		mState.sourceBlendAlpha = sourceAlpha;
+		mState.destBlendAlpha = destAlpha;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
+{
+	if(mState.blendEquationRGB != rgbEquation ||
+	   mState.blendEquationAlpha != alphaEquation)
+	{
+		mState.blendEquationRGB = rgbEquation;
+		mState.blendEquationAlpha = alphaEquation;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setStencilTestEnabled(bool enabled)
+{
+	if(mState.stencilTestEnabled != enabled)
+	{
+		mState.stencilTestEnabled = enabled;
+		mStencilStateDirty = true;
+	}
+}
+
+bool Context::isStencilTestEnabled() const
+{
+	return mState.stencilTestEnabled;
+}
+
+void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
+{
+	if(mState.stencilFunc != stencilFunc ||
+	   mState.stencilRef != stencilRef ||
+	   mState.stencilMask != stencilMask)
+	{
+		mState.stencilFunc = stencilFunc;
+		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
+		mState.stencilMask = stencilMask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilWritemask(GLuint stencilWritemask)
+{
+	if(mState.stencilWritemask != stencilWritemask)
+	{
+		mState.stencilWritemask = stencilWritemask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
+{
+	if(mState.stencilFail != stencilFail ||
+	   mState.stencilPassDepthFail != stencilPassDepthFail ||
+	   mState.stencilPassDepthPass != stencilPassDepthPass)
+	{
+		mState.stencilFail = stencilFail;
+		mState.stencilPassDepthFail = stencilPassDepthFail;
+		mState.stencilPassDepthPass = stencilPassDepthPass;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setPolygonOffsetFillEnabled(bool enabled)
+{
+	if(mState.polygonOffsetFillEnabled != enabled)
+	{
+		mState.polygonOffsetFillEnabled = enabled;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+bool Context::isPolygonOffsetFillEnabled() const
+{
+	return mState.polygonOffsetFillEnabled;
+}
+
+void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
+{
+	if(mState.polygonOffsetFactor != factor ||
+	   mState.polygonOffsetUnits != units)
+	{
+		mState.polygonOffsetFactor = factor;
+		mState.polygonOffsetUnits = units;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+void Context::setSampleAlphaToCoverageEnabled(bool enabled)
+{
+	if(mState.sampleAlphaToCoverageEnabled != enabled)
+	{
+		mState.sampleAlphaToCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleAlphaToCoverageEnabled() const
+{
+	return mState.sampleAlphaToCoverageEnabled;
+}
+
+void Context::setSampleCoverageEnabled(bool enabled)
+{
+	if(mState.sampleCoverageEnabled != enabled)
+	{
+		mState.sampleCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleCoverageEnabled() const
+{
+	return mState.sampleCoverageEnabled;
+}
+
+void Context::setSampleCoverageParams(GLclampf value, bool invert)
+{
+	if(mState.sampleCoverageValue != value ||
+	   mState.sampleCoverageInvert != invert)
+	{
+		mState.sampleCoverageValue = value;
+		mState.sampleCoverageInvert = invert;
+		mSampleStateDirty = true;
+	}
+}
+
+void Context::setScissorTestEnabled(bool enabled)
+{
+	mState.scissorTestEnabled = enabled;
+}
+
+bool Context::isScissorTestEnabled() const
+{
+	return mState.scissorTestEnabled;
+}
+
+void Context::setShadeModel(GLenum mode)
+{
+	mState.shadeModel = mode;
+}
+
+void Context::setDitherEnabled(bool enabled)
+{
+	if(mState.ditherEnabled != enabled)
+	{
+		mState.ditherEnabled = enabled;
+		mDitherStateDirty = true;
+	}
+}
+
+bool Context::isDitherEnabled() const
+{
+	return mState.ditherEnabled;
+}
+
+void Context::setLightingEnabled(bool enable)
+{
+	lightingEnabled = enable;
+}
+
+bool Context::isLightingEnabled() const
+{
+	return lightingEnabled;
+}
+
+void Context::setLightEnabled(int index, bool enable)
+{
+	light[index].enabled = enable;
+}
+
+bool Context::isLightEnabled(int index) const
+{
+	return light[index].enabled;
+}
+
+void Context::setLightAmbient(int index, float r, float g, float b, float a)
+{
+	light[index].ambient = {r, g, b, a};
+}
+
+void Context::setLightDiffuse(int index, float r, float g, float b, float a)
+{
+	light[index].diffuse = {r, g, b, a};
+}
+
+void Context::setLightSpecular(int index, float r, float g, float b, float a)
+{
+	light[index].specular = {r, g, b, a};
+}
+
+void Context::setLightPosition(int index, float x, float y, float z, float w)
+{
+	sw::float4 v = {x, y, z, w};
+
+	// Transform from object coordinates to eye coordinates
+	v = modelViewStack.current() * v;
+
+	light[index].position = {v.x, v.y, v.z, v.w};
+}
+
+void Context::setLightDirection(int index, float x, float y, float z)
+{
+	// FIXME: Transform by inverse of 3x3 model-view matrix
+	light[index].direction = {x, y, z};
+}
+
+void Context::setLightAttenuationConstant(int index, float constant)
+{
+	light[index].attenuation.constant = constant;
+}
+
+void Context::setLightAttenuationLinear(int index, float linear)
+{
+	light[index].attenuation.linear = linear;
+}
+
+void Context::setLightAttenuationQuadratic(int index, float quadratic)
+{
+	light[index].attenuation.quadratic = quadratic;
+}
+
+void Context::setSpotLightExponent(int index, float exponent)
+{
+	light[index].spotExponent = exponent;
+}
+
+void Context::setSpotLightCutoff(int index, float cutoff)
+{
+	light[index].spotCutoffAngle = cutoff;
+}
+
+void Context::setGlobalAmbient(float red, float green, float blue, float alpha)
+{
+	globalAmbient.red = red;
+	globalAmbient.green = green;
+	globalAmbient.blue = blue;
+	globalAmbient.alpha = alpha;
+}
+
+void Context::setMaterialAmbient(float red, float green, float blue, float alpha)
+{
+	materialAmbient.red = red;
+	materialAmbient.green = green;
+	materialAmbient.blue = blue;
+	materialAmbient.alpha = alpha;
+}
+
+void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)
+{
+	materialDiffuse.red = red;
+	materialDiffuse.green = green;
+	materialDiffuse.blue = blue;
+	materialDiffuse.alpha = alpha;
+}
+
+void Context::setMaterialSpecular(float red, float green, float blue, float alpha)
+{
+	materialSpecular.red = red;
+	materialSpecular.green = green;
+	materialSpecular.blue = blue;
+	materialSpecular.alpha = alpha;
+}
+
+void Context::setMaterialEmission(float red, float green, float blue, float alpha)
+{
+	materialEmission.red = red;
+	materialEmission.green = green;
+	materialEmission.blue = blue;
+	materialEmission.alpha = alpha;
+}
+
+void Context::setMaterialShininess(float shininess)
+{
+	materialShininess = shininess;
+}
+
+void Context::setLightModelTwoSide(bool enable)
+{
+	lightModelTwoSide = enable;
+}
+
+void Context::setFogEnabled(bool enable)
+{
+	fogEnabled = enable;
+}
+
+bool Context::isFogEnabled() const
+{
+	return fogEnabled;
+}
+
+void Context::setFogMode(GLenum mode)
+{
+	fogMode = mode;
+}
+
+void Context::setFogDensity(float fogDensity)
+{
+	this->fogDensity = fogDensity;
+}
+
+void Context::setFogStart(float fogStart)
+{
+	this->fogStart = fogStart;
+}
+
+void Context::setFogEnd(float fogEnd)
+{
+	this->fogEnd = fogEnd;
+}
+
+void Context::setFogColor(float r, float g, float b, float a)
+{
+	this->fogColor = {r, g, b, a};
+}
+
+void Context::setTexture2Denabled(bool enable)
+{
+	texture2Denabled[mState.activeSampler] = enable;
+}
+
+bool Context::isTexture2Denabled() const
+{
+	return texture2Denabled[mState.activeSampler];
+}
+
+void Context::setTextureExternalEnabled(bool enable)
+{
+	textureExternalEnabled[mState.activeSampler] = enable;
+}
+
+bool Context::isTextureExternalEnabled() const
+{
+	return textureExternalEnabled[mState.activeSampler];
+}
+
+void Context::setLineWidth(GLfloat width)
+{
+	mState.lineWidth = width;
+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
+}
+
+void Context::setGenerateMipmapHint(GLenum hint)
+{
+	mState.generateMipmapHint = hint;
+}
+
+void Context::setPerspectiveCorrectionHint(GLenum hint)
+{
+	mState.perspectiveCorrectionHint = hint;
+}
+
+void Context::setFogHint(GLenum hint)
+{
+	mState.fogHint = hint;
+}
+
+void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.viewportX = x;
+	mState.viewportY = y;
+	mState.viewportWidth = width;
+	mState.viewportHeight = height;
+}
+
+void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.scissorX = x;
+	mState.scissorY = y;
+	mState.scissorWidth = width;
+	mState.scissorHeight = height;
+}
+
+void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
+{
+	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
+	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
+	{
+		mState.colorMaskRed = red;
+		mState.colorMaskGreen = green;
+		mState.colorMaskBlue = blue;
+		mState.colorMaskAlpha = alpha;
+		mMaskStateDirty = true;
+	}
+}
+
+void Context::setDepthMask(bool mask)
+{
+	if(mState.depthMask != mask)
+	{
+		mState.depthMask = mask;
+		mMaskStateDirty = true;
+	}
+}
+
+void Context::setActiveSampler(unsigned int active)
+{
+	mState.activeSampler = active;
+}
+
+GLuint Context::getFramebufferName() const
+{
+	return mState.framebuffer;
+}
+
+GLuint Context::getRenderbufferName() const
+{
+	return mState.renderbuffer.name();
+}
+
+GLuint Context::getArrayBufferName() const
+{
+	return mState.arrayBuffer.name();
+}
+
+void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
+{
+	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
+}
+
+const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
+{
+	return mState.vertexAttribute[attribNum];
+}
+
+void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
+                                   GLsizei stride, const void *pointer)
+{
+	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
+	mState.vertexAttribute[attribNum].mSize = size;
+	mState.vertexAttribute[attribNum].mType = type;
+	mState.vertexAttribute[attribNum].mNormalized = normalized;
+	mState.vertexAttribute[attribNum].mStride = stride;
+	mState.vertexAttribute[attribNum].mPointer = pointer;
+}
+
+const void *Context::getVertexAttribPointer(unsigned int attribNum) const
+{
+	return mState.vertexAttribute[attribNum].mPointer;
+}
+
+const VertexAttributeArray &Context::getVertexAttributes()
+{
+	return mState.vertexAttribute;
+}
+
+void Context::setPackAlignment(GLint alignment)
+{
+	mState.packAlignment = alignment;
+}
+
+GLint Context::getPackAlignment() const
+{
+	return mState.packAlignment;
+}
+
+void Context::setUnpackAlignment(GLint alignment)
+{
+	mState.unpackAlignment = alignment;
+}
+
+GLint Context::getUnpackAlignment() const
+{
+	return mState.unpackAlignment;
+}
+
+GLuint Context::createBuffer()
+{
+	return mResourceManager->createBuffer();
+}
+
+GLuint Context::createTexture()
+{
+	return mResourceManager->createTexture();
+}
+
+GLuint Context::createRenderbuffer()
+{
+	return mResourceManager->createRenderbuffer();
+}
+
+// Returns an unused framebuffer name
+GLuint Context::createFramebuffer()
+{
+	return mFramebufferNameSpace.allocate();
+}
+
+void Context::deleteBuffer(GLuint buffer)
+{
+	detachBuffer(buffer);
+
+	mResourceManager->deleteBuffer(buffer);
+}
+
+void Context::deleteTexture(GLuint texture)
+{
+	detachTexture(texture);
+
+	mResourceManager->deleteTexture(texture);
+}
+
+void Context::deleteRenderbuffer(GLuint renderbuffer)
+{
+	detachRenderbuffer(renderbuffer);
+
+	mResourceManager->deleteRenderbuffer(renderbuffer);
+}
+
+void Context::deleteFramebuffer(GLuint framebuffer)
+{
+	detachFramebuffer(framebuffer);
+
+	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
+
+	if(framebufferObject)
+	{
+		delete framebufferObject;
+	}
+}
+
+Buffer *Context::getBuffer(GLuint handle)
+{
+	return mResourceManager->getBuffer(handle);
+}
+
+Texture *Context::getTexture(GLuint handle)
+{
+	return mResourceManager->getTexture(handle);
+}
+
+Renderbuffer *Context::getRenderbuffer(GLuint handle)
+{
+	return mResourceManager->getRenderbuffer(handle);
+}
+
+Framebuffer *Context::getFramebuffer()
+{
+	return getFramebuffer(mState.framebuffer);
+}
+
+void Context::bindArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.arrayBuffer = getBuffer(buffer);
+}
+
+void Context::bindElementArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.elementArrayBuffer = getBuffer(buffer);
+}
+
+void Context::bindTexture2D(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+
+	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindTextureExternal(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
+
+	mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindFramebuffer(GLuint framebuffer)
+{
+	if(!getFramebuffer(framebuffer))
+	{
+		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
+	}
+
+	mState.framebuffer = framebuffer;
+}
+
+void Context::bindRenderbuffer(GLuint renderbuffer)
+{
+	mResourceManager->checkRenderbufferAllocation(renderbuffer);
+
+	mState.renderbuffer = getRenderbuffer(renderbuffer);
+}
+
+void Context::setFramebufferZero(Framebuffer *buffer)
+{
+	delete mFramebufferNameSpace.remove(0);
+	mFramebufferNameSpace.insert(0, buffer);
+}
+
+void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
+{
+	Renderbuffer *renderbufferObject = mState.renderbuffer;
+	renderbufferObject->setStorage(renderbuffer);
+}
+
+Framebuffer *Context::getFramebuffer(unsigned int handle)
+{
+	return mFramebufferNameSpace.find(handle);
+}
+
+Buffer *Context::getArrayBuffer()
+{
+	return mState.arrayBuffer;
+}
+
+Buffer *Context::getElementArrayBuffer()
+{
+	return mState.elementArrayBuffer;
+}
+
+Texture2D *Context::getTexture2D()
+{
+	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
+}
+
+TextureExternal *Context::getTextureExternal()
+{
+	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
+}
+
+Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
+{
+	GLuint texid = mState.samplerTexture[type][sampler].name();
+
+	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
+	{
+		switch(type)
+		{
+		case TEXTURE_2D: return mTexture2DZero;
+		case TEXTURE_EXTERNAL: return mTextureExternalZero;
+		default: UNREACHABLE(type);
+		}
+	}
+
+	return mState.samplerTexture[type][sampler];
+}
+
+bool Context::getBooleanv(GLenum pname, GLboolean *params)
+{
+	switch(pname)
+	{
+	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
+	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
+	case GL_COLOR_WRITEMASK:
+		params[0] = mState.colorMaskRed;
+		params[1] = mState.colorMaskGreen;
+		params[2] = mState.colorMaskBlue;
+		params[3] = mState.colorMaskAlpha;
+		break;
+	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
+	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
+	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
+	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
+	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
+	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
+	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
+	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
+	case GL_LIGHT_MODEL_TWO_SIDE:     *params = lightModelTwoSide;                   break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getFloatv(GLenum pname, GLfloat *params)
+{
+	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application.
+	switch(pname)
+	{
+	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
+	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
+	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
+	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
+	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
+		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
+		break;
+	case GL_ALIASED_POINT_SIZE_RANGE:
+		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
+		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
+		break;
+	case GL_SMOOTH_LINE_WIDTH_RANGE:
+		params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;
+		params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;
+		break;
+	case GL_SMOOTH_POINT_SIZE_RANGE:
+		params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;
+		params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;
+		break;
+	case GL_DEPTH_RANGE:
+		params[0] = mState.zNear;
+		params[1] = mState.zFar;
+		break;
+	case GL_COLOR_CLEAR_VALUE:
+		params[0] = mState.colorClearValue.red;
+		params[1] = mState.colorClearValue.green;
+		params[2] = mState.colorClearValue.blue;
+		params[3] = mState.colorClearValue.alpha;
+		break;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+		*params = MAX_TEXTURE_MAX_ANISOTROPY;
+		break;
+	case GL_MODELVIEW_MATRIX:
+		for(int i = 0; i < 16; i++)
+		{
+			params[i] = modelViewStack.current()[i % 4][i / 4];
+		}
+		break;
+	case GL_PROJECTION_MATRIX:
+		for(int i = 0; i < 16; i++)
+		{
+			params[i] = projectionStack.current()[i % 4][i / 4];
+		}
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getIntegerv(GLenum pname, GLint *params)
+{
+	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application. You may find it in
+	// Context::getFloatv.
+	switch(pname)
+	{
+	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
+	case GL_FRAMEBUFFER_BINDING_OES:          *params = mState.framebuffer;                   break;
+	case GL_RENDERBUFFER_BINDING_OES:         *params = mState.renderbuffer.name();           break;
+	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
+	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
+	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
+	case GL_PERSPECTIVE_CORRECTION_HINT:      *params = mState.perspectiveCorrectionHint;     break;
+	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
+	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
+	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
+	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
+	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
+	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
+	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
+	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
+	case GL_BLEND_SRC_RGB_OES:                *params = mState.sourceBlendRGB;                break;
+	case GL_BLEND_SRC_ALPHA_OES:              *params = mState.sourceBlendAlpha;              break;
+	case GL_BLEND_DST_RGB_OES:                *params = mState.destBlendRGB;                  break;
+	case GL_BLEND_DST_ALPHA_OES:              *params = mState.destBlendAlpha;                break;
+	case GL_BLEND_EQUATION_RGB_OES:           *params = mState.blendEquationRGB;              break;
+	case GL_BLEND_EQUATION_ALPHA_OES:         *params = mState.blendEquationAlpha;            break;
+	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
+	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
+	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
+	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			int width, height, samples;
+
+			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES)
+			{
+				switch(pname)
+				{
+				case GL_SAMPLE_BUFFERS:
+					if(samples > 1)
+					{
+						*params = 1;
+					}
+					else
+					{
+						*params = 0;
+					}
+					break;
+				case GL_SAMPLES:
+					*params = samples;
+					break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			*params = framebuffer->getImplementationColorReadType();
+		}
+		break;
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			*params = framebuffer->getImplementationColorReadFormat();
+		}
+		break;
+	case GL_MAX_VIEWPORT_DIMS:
+		{
+			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
+			params[0] = maxDimension;
+			params[1] = maxDimension;
+		}
+		break;
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		{
+			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
+			{
+				params[i] = compressedTextureFormats[i];
+			}
+		}
+		break;
+	case GL_VIEWPORT:
+		params[0] = mState.viewportX;
+		params[1] = mState.viewportY;
+		params[2] = mState.viewportWidth;
+		params[3] = mState.viewportHeight;
+		break;
+	case GL_SCISSOR_BOX:
+		params[0] = mState.scissorX;
+		params[1] = mState.scissorY;
+		params[2] = mState.scissorWidth;
+		params[3] = mState.scissorHeight;
+		break;
+	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
+	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
+
+			if(colorbuffer)
+			{
+				switch(pname)
+				{
+				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
+				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
+				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
+				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_DEPTH_BITS:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+
+			if(depthbuffer)
+			{
+				*params = depthbuffer->getDepthSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_STENCIL_BITS:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+
+			if(stencilbuffer)
+			{
+				*params = stencilbuffer->getStencilSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_TEXTURE_BINDING_2D:                  *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();                   break;
+	case GL_TEXTURE_BINDING_CUBE_MAP_OES:        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();                 break;
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:        *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();             break;
+	case GL_MAX_LIGHTS:                          *params = MAX_LIGHTS;                                                                       break;
+	case GL_MAX_MODELVIEW_STACK_DEPTH:           *params = MAX_MODELVIEW_STACK_DEPTH;                                                        break;
+	case GL_MAX_PROJECTION_STACK_DEPTH:          *params = MAX_PROJECTION_STACK_DEPTH;                                                       break;
+	case GL_MAX_TEXTURE_STACK_DEPTH:             *params = MAX_TEXTURE_STACK_DEPTH;                                                          break;
+	case GL_MAX_TEXTURE_UNITS:                   *params = MAX_TEXTURE_UNITS;                                                                break;
+	case GL_MAX_CLIP_PLANES:                     *params = MAX_CLIP_PLANES;                                                                  break;
+	case GL_POINT_SIZE_ARRAY_TYPE_OES:           *params = mState.vertexAttribute[sw::PointSize].mType;                                      break;
+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:         *params = mState.vertexAttribute[sw::PointSize].mStride;                                    break;
+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name();                        break;
+	case GL_VERTEX_ARRAY_SIZE:                   *params = mState.vertexAttribute[sw::Position].mSize;                                       break;
+	case GL_VERTEX_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Position].mType;                                       break;
+	case GL_VERTEX_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Position].mStride;                                     break;
+	case GL_VERTEX_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name();                         break;
+	case GL_NORMAL_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Normal].mType;                                         break;
+	case GL_NORMAL_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Normal].mStride;                                       break;
+	case GL_NORMAL_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name();                           break;
+	case GL_COLOR_ARRAY_SIZE:                    *params = mState.vertexAttribute[sw::Color0].mSize;                                         break;
+	case GL_COLOR_ARRAY_TYPE:                    *params = mState.vertexAttribute[sw::Color0].mType;                                         break;
+	case GL_COLOR_ARRAY_STRIDE:                  *params = mState.vertexAttribute[sw::Color0].mStride;                                       break;
+	case GL_COLOR_ARRAY_BUFFER_BINDING:          *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name();                           break;
+	case GL_TEXTURE_COORD_ARRAY_SIZE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mSize;               break;
+	case GL_TEXTURE_COORD_ARRAY_TYPE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType;               break;
+	case GL_TEXTURE_COORD_ARRAY_STRIDE:          *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride;             break;
+	case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getPointerv(GLenum pname, const GLvoid **params)
+{
+	switch(pname)
+	{
+	case GL_VERTEX_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Position].mPointer;                         break;
+	case GL_NORMAL_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Normal].mPointer;                           break;
+	case GL_COLOR_ARRAY_POINTER:          *params = mState.vertexAttribute[sw::Color0].mPointer;                           break;
+	case GL_POINT_SIZE_ARRAY_POINTER_OES: *params = mState.vertexAttribute[sw::PointSize].mPointer;                        break;
+	case GL_TEXTURE_COORD_ARRAY_POINTER:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mPointer; break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+int Context::getQueryParameterNum(GLenum pname)
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		return NUM_COMPRESSED_TEXTURE_FORMATS;
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+	case GL_ARRAY_BUFFER_BINDING:
+	case GL_FRAMEBUFFER_BINDING_OES:
+	case GL_RENDERBUFFER_BINDING_OES:
+	case GL_PACK_ALIGNMENT:
+	case GL_UNPACK_ALIGNMENT:
+	case GL_GENERATE_MIPMAP_HINT:
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+	case GL_DEPTH_BITS:
+	case GL_STENCIL_BITS:
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+	case GL_CULL_FACE_MODE:
+	case GL_FRONT_FACE:
+	case GL_ACTIVE_TEXTURE:
+	case GL_STENCIL_FUNC:
+	case GL_STENCIL_VALUE_MASK:
+	case GL_STENCIL_REF:
+	case GL_STENCIL_FAIL:
+	case GL_STENCIL_PASS_DEPTH_FAIL:
+	case GL_STENCIL_PASS_DEPTH_PASS:
+	case GL_DEPTH_FUNC:
+	case GL_BLEND_SRC_RGB_OES:
+	case GL_BLEND_SRC_ALPHA_OES:
+	case GL_BLEND_DST_RGB_OES:
+	case GL_BLEND_DST_ALPHA_OES:
+	case GL_BLEND_EQUATION_RGB_OES:
+	case GL_BLEND_EQUATION_ALPHA_OES:
+	case GL_STENCIL_WRITEMASK:
+	case GL_STENCIL_CLEAR_VALUE:
+	case GL_SUBPIXEL_BITS:
+	case GL_MAX_TEXTURE_SIZE:
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+	case GL_TEXTURE_BINDING_2D:
+	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:
+		return 1;
+	case GL_MAX_VIEWPORT_DIMS:
+		return 2;
+	case GL_VIEWPORT:
+	case GL_SCISSOR_BOX:
+		return 4;
+	case GL_SAMPLE_COVERAGE_INVERT:
+	case GL_DEPTH_WRITEMASK:
+	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
+	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
+	case GL_SAMPLE_COVERAGE:
+	case GL_SCISSOR_TEST:
+	case GL_STENCIL_TEST:
+	case GL_DEPTH_TEST:
+	case GL_BLEND:
+	case GL_DITHER:
+		return 1;
+	case GL_COLOR_WRITEMASK:
+		return 4;
+	case GL_POLYGON_OFFSET_FACTOR:
+	case GL_POLYGON_OFFSET_UNITS:
+	case GL_SAMPLE_COVERAGE_VALUE:
+	case GL_DEPTH_CLEAR_VALUE:
+	case GL_LINE_WIDTH:
+		return 1;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+	case GL_ALIASED_POINT_SIZE_RANGE:
+	case GL_DEPTH_RANGE:
+		return 2;
+	case GL_COLOR_CLEAR_VALUE:
+		return 4;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+	case GL_MAX_LIGHTS:
+	case GL_MAX_MODELVIEW_STACK_DEPTH:
+	case GL_MAX_PROJECTION_STACK_DEPTH:
+	case GL_MAX_TEXTURE_STACK_DEPTH:
+	case GL_MAX_TEXTURE_UNITS:
+	case GL_MAX_CLIP_PLANES:
+	case GL_POINT_SIZE_ARRAY_TYPE_OES:
+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+		return 1;
+	case GL_CURRENT_COLOR:
+		return 4;
+	case GL_CURRENT_NORMAL:
+		return 3;
+	case GL_CURRENT_TEXTURE_COORDS:
+		return 4;
+	case GL_POINT_SIZE:
+	case GL_POINT_SIZE_MIN:
+	case GL_POINT_SIZE_MAX:
+	case GL_POINT_FADE_THRESHOLD_SIZE:
+		return 1;
+	case GL_POINT_DISTANCE_ATTENUATION:
+		return 3;
+	case GL_SMOOTH_POINT_SIZE_RANGE:
+	case GL_SMOOTH_LINE_WIDTH_RANGE:
+		return 2;
+	case GL_SHADE_MODEL:
+	case GL_MATRIX_MODE:
+	case GL_MODELVIEW_STACK_DEPTH:
+	case GL_PROJECTION_STACK_DEPTH:
+	case GL_TEXTURE_STACK_DEPTH:
+		return 1;
+	case GL_MODELVIEW_MATRIX:
+	case GL_PROJECTION_MATRIX:
+	case GL_TEXTURE_MATRIX:
+		return 16;
+	case GL_ALPHA_TEST_FUNC:
+	case GL_ALPHA_TEST_REF:
+	case GL_BLEND_DST:
+	case GL_BLEND_SRC:
+	case GL_LOGIC_OP_MODE:
+	case GL_VERTEX_ARRAY_SIZE:
+	case GL_VERTEX_ARRAY_TYPE:
+	case GL_VERTEX_ARRAY_STRIDE:
+	case GL_NORMAL_ARRAY_TYPE:
+	case GL_NORMAL_ARRAY_STRIDE:
+	case GL_COLOR_ARRAY_SIZE:
+	case GL_COLOR_ARRAY_TYPE:
+	case GL_COLOR_ARRAY_STRIDE:
+	case GL_TEXTURE_COORD_ARRAY_SIZE:
+	case GL_TEXTURE_COORD_ARRAY_TYPE:
+	case GL_TEXTURE_COORD_ARRAY_STRIDE:
+	case GL_VERTEX_ARRAY_POINTER:
+	case GL_NORMAL_ARRAY_POINTER:
+	case GL_COLOR_ARRAY_POINTER:
+	case GL_TEXTURE_COORD_ARRAY_POINTER:
+	case GL_LIGHT_MODEL_TWO_SIDE:
+		return 1;
+	default:
+		UNREACHABLE(pname);
+	}
+
+	return -1;
+}
+
+bool Context::isQueryParameterInt(GLenum pname)
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+	case GL_ARRAY_BUFFER_BINDING:
+	case GL_FRAMEBUFFER_BINDING_OES:
+	case GL_RENDERBUFFER_BINDING_OES:
+	case GL_PACK_ALIGNMENT:
+	case GL_UNPACK_ALIGNMENT:
+	case GL_GENERATE_MIPMAP_HINT:
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+	case GL_DEPTH_BITS:
+	case GL_STENCIL_BITS:
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+	case GL_CULL_FACE_MODE:
+	case GL_FRONT_FACE:
+	case GL_ACTIVE_TEXTURE:
+	case GL_STENCIL_FUNC:
+	case GL_STENCIL_VALUE_MASK:
+	case GL_STENCIL_REF:
+	case GL_STENCIL_FAIL:
+	case GL_STENCIL_PASS_DEPTH_FAIL:
+	case GL_STENCIL_PASS_DEPTH_PASS:
+	case GL_DEPTH_FUNC:
+	case GL_BLEND_SRC_RGB_OES:
+	case GL_BLEND_SRC_ALPHA_OES:
+	case GL_BLEND_DST_RGB_OES:
+	case GL_BLEND_DST_ALPHA_OES:
+	case GL_BLEND_EQUATION_RGB_OES:
+	case GL_BLEND_EQUATION_ALPHA_OES:
+	case GL_STENCIL_WRITEMASK:
+	case GL_STENCIL_CLEAR_VALUE:
+	case GL_SUBPIXEL_BITS:
+	case GL_MAX_TEXTURE_SIZE:
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+	case GL_TEXTURE_BINDING_2D:
+	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:
+	case GL_MAX_VIEWPORT_DIMS:
+	case GL_VIEWPORT:
+	case GL_SCISSOR_BOX:
+	case GL_MAX_LIGHTS:
+	case GL_MAX_MODELVIEW_STACK_DEPTH:
+	case GL_MAX_PROJECTION_STACK_DEPTH:
+	case GL_MAX_TEXTURE_STACK_DEPTH:
+	case GL_MAX_TEXTURE_UNITS:
+	case GL_MAX_CLIP_PLANES:
+	case GL_POINT_SIZE_ARRAY_TYPE_OES:
+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+		return true;
+	}
+
+	return false;
+}
+
+bool Context::isQueryParameterFloat(GLenum pname)
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_POLYGON_OFFSET_FACTOR:
+	case GL_POLYGON_OFFSET_UNITS:
+	case GL_SAMPLE_COVERAGE_VALUE:
+	case GL_DEPTH_CLEAR_VALUE:
+	case GL_LINE_WIDTH:
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+	case GL_ALIASED_POINT_SIZE_RANGE:
+	case GL_SMOOTH_LINE_WIDTH_RANGE:
+	case GL_SMOOTH_POINT_SIZE_RANGE:
+	case GL_DEPTH_RANGE:
+	case GL_COLOR_CLEAR_VALUE:
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+	case GL_LIGHT_MODEL_AMBIENT:
+	case GL_POINT_SIZE_MIN:
+	case GL_POINT_SIZE_MAX:
+	case GL_POINT_DISTANCE_ATTENUATION:
+	case GL_POINT_FADE_THRESHOLD_SIZE:
+		return true;
+	}
+
+	return false;
+}
+
+bool Context::isQueryParameterBool(GLenum pname)
+{
+	switch(pname)
+	{
+	case GL_SAMPLE_COVERAGE_INVERT:
+	case GL_DEPTH_WRITEMASK:
+	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
+	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
+	case GL_SAMPLE_COVERAGE:
+	case GL_SCISSOR_TEST:
+	case GL_STENCIL_TEST:
+	case GL_DEPTH_TEST:
+	case GL_BLEND:
+	case GL_DITHER:
+	case GL_COLOR_WRITEMASK:
+	case GL_LIGHT_MODEL_TWO_SIDE:
+		return true;
+	}
+
+	return false;
+}
+
+bool Context::isQueryParameterPointer(GLenum pname)
+{
+	switch(pname)
+	{
+	case GL_VERTEX_ARRAY_POINTER:
+	case GL_NORMAL_ARRAY_POINTER:
+	case GL_COLOR_ARRAY_POINTER:
+	case GL_TEXTURE_COORD_ARRAY_POINTER:
+	case GL_POINT_SIZE_ARRAY_POINTER_OES:
+		return true;
+	}
+
+	return false;
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
+bool Context::applyRenderTarget()
+{
+	Framebuffer *framebuffer = getFramebuffer();
+	int width, height, samples;
+
+	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);
+	}
+
+	egl::Image *renderTarget = framebuffer->getRenderTarget();
+	device->setRenderTarget(0, renderTarget);
+	if(renderTarget) renderTarget->release();
+
+	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
+	device->setDepthBuffer(depthBuffer);
+	if(depthBuffer) depthBuffer->release();
+
+	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
+	device->setStencilBuffer(stencilBuffer);
+	if(stencilBuffer) stencilBuffer->release();
+
+	Viewport viewport;
+	float zNear = clamp01(mState.zNear);
+	float zFar = clamp01(mState.zFar);
+
+	viewport.x0 = mState.viewportX;
+	viewport.y0 = mState.viewportY;
+	viewport.width = mState.viewportWidth;
+	viewport.height = mState.viewportHeight;
+	viewport.minZ = zNear;
+	viewport.maxZ = zFar;
+
+	device->setViewport(viewport);
+
+	if(mState.scissorTestEnabled)
+	{
+		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
+		scissor.clip(0, 0, width, height);
+
+		device->setScissorRect(scissor);
+		device->setScissorEnable(true);
+	}
+	else
+	{
+		device->setScissorEnable(false);
+	}
+
+	return true;
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
+void Context::applyState(GLenum drawMode)
+{
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(mState.cullFaceEnabled)
+	{
+		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
+	}
+	else
+	{
+		device->setCullMode(sw::CULL_NONE);
+	}
+
+	if(mDepthStateDirty)
+	{
+		if(mState.depthTestEnabled)
+		{
+			device->setDepthBufferEnable(true);
+			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
+		}
+		else
+		{
+			device->setDepthBufferEnable(false);
+		}
+
+		mDepthStateDirty = false;
+	}
+
+	if(mBlendStateDirty)
+	{
+		if(mState.blendEnabled)
+		{
+			device->setAlphaBlendEnable(true);
+			device->setSeparateAlphaBlendEnable(true);
+
+			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
+			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
+			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
+
+			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
+			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
+			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
+		}
+		else
+		{
+			device->setAlphaBlendEnable(false);
+		}
+
+		mBlendStateDirty = false;
+	}
+
+	if(mStencilStateDirty || mFrontFaceDirty)
+	{
+		if(mState.stencilTestEnabled && framebuffer->hasStencil())
+		{
+			device->setStencilEnable(true);
+			device->setTwoSidedStencil(true);
+
+			// get the maximum size of the stencil ref
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
+
+			device->setStencilWriteMask(mState.stencilWritemask);
+			device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+			device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+			device->setStencilMask(mState.stencilMask);
+
+			device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
+			device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+			device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+
+			device->setStencilWriteMaskCCW(mState.stencilWritemask);
+			device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+			device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+			device->setStencilMaskCCW(mState.stencilMask);
+
+			device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
+			device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+			device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+		}
+		else
+		{
+			device->setStencilEnable(false);
+		}
+
+		mStencilStateDirty = false;
+		mFrontFaceDirty = false;
+	}
+
+	if(mMaskStateDirty)
+	{
+		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
+		device->setDepthWriteEnable(mState.depthMask);
+
+		mMaskStateDirty = false;
+	}
+
+	if(mPolygonOffsetStateDirty)
+	{
+		if(mState.polygonOffsetFillEnabled)
+		{
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+			if(depthbuffer)
+			{
+				device->setSlopeDepthBias(mState.polygonOffsetFactor);
+				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
+				device->setDepthBias(depthBias);
+			}
+		}
+		else
+		{
+			device->setSlopeDepthBias(0);
+			device->setDepthBias(0);
+		}
+
+		mPolygonOffsetStateDirty = false;
+	}
+
+	if(mSampleStateDirty)
+	{
+		if(mState.sampleAlphaToCoverageEnabled)
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
+		}
+		else
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
+		}
+
+		if(mState.sampleCoverageEnabled)
+		{
+			unsigned int mask = 0;
+			if(mState.sampleCoverageValue != 0)
+			{
+				int width, height, samples;
+				framebuffer->completeness(width, height, samples);
+
+				float threshold = 0.5f;
+
+				for(int i = 0; i < samples; i++)
+				{
+					mask <<= 1;
+
+					if((i + 1) * mState.sampleCoverageValue >= threshold)
+					{
+						threshold += 1.0f;
+						mask |= 1;
+					}
+				}
+			}
+
+			if(mState.sampleCoverageInvert)
+			{
+				mask = ~mask;
+			}
+
+			device->setMultiSampleMask(mask);
+		}
+		else
+		{
+			device->setMultiSampleMask(0xFFFFFFFF);
+		}
+
+		mSampleStateDirty = false;
+	}
+
+	if(mDitherStateDirty)
+	{
+	//	UNIMPLEMENTED();   // FIXME
+
+		mDitherStateDirty = false;
+	}
+
+	switch(mState.shadeModel)
+	{
+	default: UNREACHABLE(mState.shadeModel);
+	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
+	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
+	}
+
+	device->setLightingEnable(lightingEnabled);
+	device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));
+
+	for(int i = 0; i < MAX_LIGHTS; i++)
+	{
+		device->setLightEnable(i, light[i].enabled);
+		device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));
+		device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));
+		device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));
+		device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);
+
+		if(light[i].position.w != 0.0f)
+		{
+			device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));
+		}
+		else   // Directional light
+		{
+			// Hack: set the position far way
+			float max = sw::max(abs(light[i].position.x), abs(light[i].position.y), abs(light[i].position.z));
+			device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));
+		}
+	}
+
+	device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));
+	device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));
+	device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));
+	device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));
+	device->setMaterialShininess(materialShininess);
+
+	device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
+	device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+	device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
+	device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+
+	const sw::Matrix Z(1, 0, 0, 0,
+	                   0, 1, 0, 0,
+	                   0, 0, 0.5, 0.5,
+	                   0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]
+
+	device->setProjectionMatrix(Z * projectionStack.current());
+	device->setModelMatrix(modelViewStack.current());
+	device->setTextureMatrix(0, textureStack0.current());
+	device->setTextureMatrix(1, textureStack1.current());
+	device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);
+	device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);
+	device->setTexGen(0, sw::TEXGEN_NONE);
+	device->setTexGen(1, sw::TEXGEN_NONE);
+
+	device->setAlphaTestEnable(alphaTestEnabled);
+	device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));
+	device->setAlphaReference(alphaTestRef * 0xFF);
+
+	device->setFogEnable(fogEnabled);
+	device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));
+	device->setFogDensity(fogDensity);
+	device->setFogStart(fogStart);
+	device->setFogEnd(fogEnd);
+
+	switch(fogMode)
+	{
+	case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
+	case GL_EXP:    device->setVertexFogMode(sw::FOG_EXP);    break;
+	case GL_EXP2:   device->setVertexFogMode(sw::FOG_EXP2);   break;
+	default: UNREACHABLE(fogMode);
+	}
+
+	device->setColorLogicOpEnabled(colorLogicOpEnabled);
+	device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));
+
+	device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);
+}
+
+GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
+{
+	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
+
+	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
+	if(err != GL_NO_ERROR)
+	{
+		return err;
+	}
+
+	device->resetInputStreams(false);
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		sw::Resource *resource = attributes[i].vertexBuffer;
+		const void *buffer = (char*)resource->data() + attributes[i].offset;
+
+		int stride = attributes[i].stride;
+
+		buffer = (char*)buffer + stride * base;
+
+		sw::Stream attribute(resource, buffer, stride);
+
+		attribute.type = attributes[i].type;
+		attribute.count = attributes[i].count;
+		attribute.normalized = attributes[i].normalized;
+
+		device->setInputStream(i, attribute);
+	}
+
+	return GL_NO_ERROR;
+}
+
+// Applies the indices and element array bindings
+GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
+
+	if(err == GL_NO_ERROR)
+	{
+		device->setIndexBuffer(indexInfo->indexBuffer);
+	}
+
+	return err;
+}
+
+void Context::applyTextures()
+{
+	for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)
+	{
+		Texture *texture = nullptr;
+
+		if(textureExternalEnabled[unit])
+		{
+			texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);
+		}
+		else if(texture2Denabled[unit])
+		{
+			texture = getSamplerTexture(unit, TEXTURE_2D);
+		}
+
+		if(texture && texture->isSamplerComplete())
+		{
+			texture->autoGenerateMipmaps();
+
+			GLenum wrapS = texture->getWrapS();
+			GLenum wrapT = texture->getWrapT();
+			GLenum minFilter = texture->getMinFilter();
+			GLenum magFilter = texture->getMagFilter();
+			GLfloat maxAnisotropy = texture->getMaxAnisotropy();
+
+			device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));
+			device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));
+
+			device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
+			device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMipMapFilter(minFilter));
+			device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);
+
+			applyTexture(unit, texture);
+
+			device->setConstantColor(unit, sw::Color<float>(mState.textureUnit[unit].color.red, mState.textureUnit[unit].color.green, mState.textureUnit[unit].color.blue, mState.textureUnit[unit].color.alpha));
+
+			if(mState.textureUnit[unit].environmentMode != GL_COMBINE)
+			{
+				device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE);    // Cs
+				device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+				device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT);   // Cp
+				device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+				device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT);   // Cc
+				device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+
+				device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE);    // As
+				device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+				device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);   // Ap
+				device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+				device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT);   // Ac
+				device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+
+				GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);
+
+				switch(mState.textureUnit[unit].environmentMode)
+				{
+				case GL_REPLACE:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = As
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cs, Av = As
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_MODULATE:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = CpCs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = CpCs, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_DECAL:
+					if(texFormat == GL_ALPHA ||
+					   texFormat == GL_LUMINANCE ||
+					   texFormat == GL_LUMINANCE_ALPHA)
+					{
+						// undefined   // FIXME: Log
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cp(1 - As) + CsAs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);   // Alpha * (Arg1 - Arg2) + Arg2
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_BLEND:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cp(1 - Cs) + CcCs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cp(1 - Cs) + CcCs, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_ADD:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cp + Cs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cp + Cs, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				default:
+					UNREACHABLE(mState.textureUnit[unit].environmentMode);
+				}
+			}
+			else   // GL_COMBINE
+			{
+				device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));
+				device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));
+				device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));
+				device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));
+				device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));
+				device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));
+
+				device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));
+
+				device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));
+				device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));
+				device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));
+				device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));
+				device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));
+				device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));
+
+				device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));
+			}
+		}
+		else
+		{
+			applyTexture(unit, nullptr);
+
+			device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);
+			device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+			device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+
+			device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);
+			device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+			device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
+		}
+	}
+}
+
+void Context::setTextureEnvMode(GLenum texEnvMode)
+{
+	mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;
+}
+
+void Context::setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	mState.textureUnit[mState.activeSampler].color = {red, green, blue, alpha};
+}
+
+void Context::setCombineRGB(GLenum combineRGB)
+{
+	mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;
+}
+
+void Context::setCombineAlpha(GLenum combineAlpha)
+{
+	mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;
+}
+
+void Context::setOperand0RGB(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand0RGB = operand;
+}
+
+void Context::setOperand1RGB(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand1RGB = operand;
+}
+
+void Context::setOperand2RGB(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand2RGB = operand;
+}
+
+void Context::setOperand0Alpha(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand0Alpha = operand;
+}
+
+void Context::setOperand1Alpha(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand1Alpha = operand;
+}
+
+void Context::setOperand2Alpha(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand2Alpha = operand;
+}
+
+void Context::setSrc0RGB(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src0RGB = src;
+}
+
+void Context::setSrc1RGB(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src1RGB = src;
+}
+
+void Context::setSrc2RGB(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src2RGB = src;
+}
+
+void Context::setSrc0Alpha(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src0Alpha = src;
+}
+
+void Context::setSrc1Alpha(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src1Alpha = src;
+}
+
+void Context::setSrc2Alpha(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src2Alpha = src;
+}
+
+void Context::applyTexture(int index, Texture *baseTexture)
+{
+	sw::Resource *resource = 0;
+
+	if(baseTexture)
+	{
+		resource = baseTexture->getResource();
+	}
+
+	device->setTextureResource(index, resource);
+
+	if(baseTexture)
+	{
+		int levelCount = baseTexture->getLevelCount();
+
+		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
+
+			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+			{
+				int surfaceLevel = mipmapLevel;
+
+				if(surfaceLevel < 0)
+				{
+					surfaceLevel = 0;
+				}
+				else if(surfaceLevel >= levelCount)
+				{
+					surfaceLevel = levelCount - 1;
+				}
+
+				egl::Image *surface = texture->getImage(surfaceLevel);
+				device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);
+			}
+		}
+		else UNIMPLEMENTED();
+	}
+	else
+	{
+		device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);
+	}
+}
+
+void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+{
+	Framebuffer *framebuffer = getFramebuffer();
+	int framebufferWidth, framebufferHeight, framebufferSamples;
+
+	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+	}
+
+	if(getFramebufferName() != 0 && framebufferSamples != 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
+	{
+		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	GLsizei outputPitch = egl::ComputePitch(width, format, type, mState.packAlignment);
+
+	// Sized query sanity check
+	if(bufSize)
+	{
+		int requiredSize = outputPitch * height;
+		if(requiredSize > *bufSize)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	egl::Image *renderTarget = framebuffer->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	sw::Rect rect = {x, y, x + width, y + height};
+	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
+	unsigned char *dest = (unsigned char*)pixels;
+	int inputPitch = (int)renderTarget->getPitch();
+
+	for(int j = 0; j < rect.y1 - rect.y0; j++)
+	{
+		unsigned short *dest16 = (unsigned short*)dest;
+		unsigned int *dest32 = (unsigned int*)dest;
+
+		if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&
+		   format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				unsigned int argb = *(unsigned int*)(source + 4 * i);
+
+				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
+			}
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
+
+				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
+			}
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
+
+				dest32[i] = xrgb | 0xFF000000;
+			}
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
+				format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
+				format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
+		}
+		else
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				float r;
+				float g;
+				float b;
+				float a;
+
+				switch(renderTarget->getInternalFormat())
+				{
+				case sw::FORMAT_R5G6B5:
+					{
+						unsigned short rgb = *(unsigned short*)(source + 2 * i);
+
+						a = 1.0f;
+						b = (rgb & 0x001F) * (1.0f / 0x001F);
+						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
+						r = (rgb & 0xF800) * (1.0f / 0xF800);
+					}
+					break;
+				case sw::FORMAT_A1R5G5B5:
+					{
+						unsigned short argb = *(unsigned short*)(source + 2 * i);
+
+						a = (argb & 0x8000) ? 1.0f : 0.0f;
+						b = (argb & 0x001F) * (1.0f / 0x001F);
+						g = (argb & 0x03E0) * (1.0f / 0x03E0);
+						r = (argb & 0x7C00) * (1.0f / 0x7C00);
+					}
+					break;
+				case sw::FORMAT_A8R8G8B8:
+					{
+						unsigned int argb = *(unsigned int*)(source + 4 * i);
+
+						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
+						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
+						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
+					}
+					break;
+				case sw::FORMAT_A8B8G8R8:
+					{
+						unsigned int abgr = *(unsigned int*)(source + 4 * i);
+
+						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
+						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
+						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
+					}
+					break;
+				case sw::FORMAT_X8R8G8B8:
+					{
+						unsigned int xrgb = *(unsigned int*)(source + 4 * i);
+
+						a = 1.0f;
+						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
+						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
+					}
+					break;
+				case sw::FORMAT_X8B8G8R8:
+					{
+						unsigned int xbgr = *(unsigned int*)(source + 4 * i);
+
+						a = 1.0f;
+						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
+						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
+					}
+					break;
+				case sw::FORMAT_A2R10G10B10:
+					{
+						unsigned int argb = *(unsigned int*)(source + 4 * i);
+
+						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
+						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
+						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
+						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
+					}
+					break;
+				default:
+					UNIMPLEMENTED();   // FIXME
+					UNREACHABLE(renderTarget->getInternalFormat());
+				}
+
+				switch(format)
+				{
+				case GL_RGBA:
+					switch(type)
+					{
+					case GL_UNSIGNED_BYTE:
+						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
+						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
+						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
+						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				case GL_BGRA_EXT:
+					switch(type)
+					{
+					case GL_UNSIGNED_BYTE:
+						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
+						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
+						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
+						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
+						break;
+					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+						// this type is packed as follows:
+						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+						//  --------------------------------------------------------------------------------
+						// |       4th         |        3rd         |        2nd        |   1st component   |
+						//  --------------------------------------------------------------------------------
+						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+						dest16[i] =
+							((unsigned short)(15 * a + 0.5f) << 12)|
+							((unsigned short)(15 * r + 0.5f) << 8) |
+							((unsigned short)(15 * g + 0.5f) << 4) |
+							((unsigned short)(15 * b + 0.5f) << 0);
+						break;
+					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+						// this type is packed as follows:
+						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+						//  --------------------------------------------------------------------------------
+						// | 4th |          3rd           |           2nd          |      1st component     |
+						//  --------------------------------------------------------------------------------
+						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+						dest16[i] =
+							((unsigned short)(     a + 0.5f) << 15) |
+							((unsigned short)(31 * r + 0.5f) << 10) |
+							((unsigned short)(31 * g + 0.5f) << 5) |
+							((unsigned short)(31 * b + 0.5f) << 0);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				case GL_RGB:
+					switch(type)
+					{
+					case GL_UNSIGNED_SHORT_5_6_5:
+						dest16[i] =
+							((unsigned short)(31 * b + 0.5f) << 0) |
+							((unsigned short)(63 * g + 0.5f) << 5) |
+							((unsigned short)(31 * r + 0.5f) << 11);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				default: UNREACHABLE(format);
+				}
+			}
+		}
+
+		source += inputPitch;
+		dest += outputPitch;
+	}
+
+	renderTarget->unlock();
+	renderTarget->release();
+}
+
+void Context::clear(GLbitfield mask)
+{
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	float depth = clamp01(mState.depthClearValue);
+	int stencil = mState.stencilClearValue & 0x000000FF;
+
+	if(mask & GL_COLOR_BUFFER_BIT)
+	{
+		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
+		                        (mState.colorMaskGreen ? 0x2 : 0) |
+		                        (mState.colorMaskBlue ? 0x4 : 0) |
+		                        (mState.colorMaskAlpha ? 0x8 : 0);
+
+		if(rgbaMask != 0)
+		{
+			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
+		}
+	}
+
+	if(mask & GL_DEPTH_BUFFER_BIT)
+	{
+		if(mState.depthMask != 0)
+		{
+			device->clearDepth(depth);
+		}
+	}
+
+	if(mask & GL_STENCIL_BUFFER_BIT)
+	{
+		if(mState.stencilWritemask != 0)
+		{
+			device->clearStencil(stencil, mState.stencilWritemask);
+		}
+	}
+}
+
+void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	sw::DrawType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	GLenum err = applyVertexBuffer(0, first, count);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	applyTextures();
+
+	if(!cullSkipsDraw(mode))
+	{
+		device->drawPrimitive(primitiveType, primitiveCount);
+	}
+}
+
+void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+	if(!indices && !mState.elementArrayBuffer)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	sw::DrawType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	TranslatedIndexData indexInfo;
+	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	applyTextures();
+
+	if(!cullSkipsDraw(mode))
+	{
+		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
+	}
+}
+
+void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+	es1::Framebuffer *framebuffer = getFramebuffer();
+	es1::Renderbuffer *renderbuffer = framebuffer->getColorbuffer();
+	float targetWidth = (float)renderbuffer->getWidth();
+	float targetHeight = (float)renderbuffer->getHeight();
+	float x0 = 2.0f * x / targetWidth - 1.0f;
+	float y0 = 2.0f * y / targetHeight - 1.0f;
+	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;
+	float y1 = 2.0f * (y + height) / targetHeight - 1.0f;
+	float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);
+
+	float vertices[][3] = {{x0, y0, Zw},
+	                       {x0, y1, Zw},
+	                       {x1, y0, Zw},
+	                       {x1, y1, Zw}};
+
+	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented
+	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);
+	float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);
+	float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);
+	int Ucr = texture->getCropRectU();
+	int Vcr = texture->getCropRectV();
+	int Wcr = texture->getCropRectW();
+	int Hcr = texture->getCropRectH();
+
+	float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},
+	                        {Ucr / textureWidth, (Vcr + Hcr) / textureHeight},
+	                        {(Ucr + Wcr) / textureWidth, Vcr / textureHeight},
+	                        {(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};
+
+	VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];
+	VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];
+	gl::BindingPointer<Buffer> oldArrayBuffer = mState.arrayBuffer;
+	mState.arrayBuffer = nullptr;
+
+	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+	sw::Matrix P = projectionStack.current();
+	sw::Matrix M = modelViewStack.current();
+	sw::Matrix T = textureStack0.current();
+
+	projectionStack.identity();
+	modelViewStack.identity();
+	textureStack0.identity();
+
+	drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+	// Restore state
+	mState.vertexAttribute[sw::Position] = oldPositionAttribute;
+	mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;
+	mState.arrayBuffer = oldArrayBuffer;
+	oldArrayBuffer = nullptr;
+	oldPositionAttribute.mBoundBuffer = nullptr;
+	oldTexCoord0Attribute.mBoundBuffer = nullptr;
+	textureStack0.load(T);
+	modelViewStack.load(M);
+	projectionStack.load(P);
+}
+
+void Context::finish()
+{
+	device->finish();
+}
+
+void Context::flush()
+{
+	// We don't queue anything without processing it as fast as possible
+}
+
+void Context::recordInvalidEnum()
+{
+	mInvalidEnum = true;
+}
+
+void Context::recordInvalidValue()
+{
+	mInvalidValue = true;
+}
+
+void Context::recordInvalidOperation()
+{
+	mInvalidOperation = true;
+}
+
+void Context::recordOutOfMemory()
+{
+	mOutOfMemory = true;
+}
+
+void Context::recordInvalidFramebufferOperation()
+{
+	mInvalidFramebufferOperation = true;
+}
+
+void Context::recordMatrixStackOverflow()
+{
+	mMatrixStackOverflow = true;
+}
+
+void Context::recordMatrixStackUnderflow()
+{
+	mMatrixStackUnderflow = true;
+}
+
+// Get one of the recorded errors and clear its flag, if any.
+// [OpenGL ES 2.0.24] section 2.5 page 13.
+GLenum Context::getError()
+{
+	if(mInvalidEnum)
+	{
+		mInvalidEnum = false;
+
+		return GL_INVALID_ENUM;
+	}
+
+	if(mInvalidValue)
+	{
+		mInvalidValue = false;
+
+		return GL_INVALID_VALUE;
+	}
+
+	if(mInvalidOperation)
+	{
+		mInvalidOperation = false;
+
+		return GL_INVALID_OPERATION;
+	}
+
+	if(mOutOfMemory)
+	{
+		mOutOfMemory = false;
+
+		return GL_OUT_OF_MEMORY;
+	}
+
+	if(mInvalidFramebufferOperation)
+	{
+		mInvalidFramebufferOperation = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
+	}
+
+	if(mMatrixStackOverflow)
+	{
+		mMatrixStackOverflow = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
+	}
+
+	if(mMatrixStackUnderflow)
+	{
+		mMatrixStackUnderflow = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
+	}
+
+	return GL_NO_ERROR;
+}
+
+int Context::getSupportedMultisampleCount(int requested)
+{
+	int supported = 0;
+
+	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
+	{
+		if(supported >= requested)
+		{
+			return supported;
+		}
+
+		supported = multisampleCount[i];
+	}
+
+	return supported;
+}
+
+void Context::detachBuffer(GLuint buffer)
+{
+	// [OpenGL ES 2.0.24] section 2.9 page 22:
+	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
+	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
+
+	if(mState.arrayBuffer.name() == buffer)
+	{
+		mState.arrayBuffer = nullptr;
+	}
+
+	if(mState.elementArrayBuffer.name() == buffer)
+	{
+		mState.elementArrayBuffer = nullptr;
+	}
+
+	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+	{
+		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
+		{
+			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
+		}
+	}
+}
+
+void Context::detachTexture(GLuint texture)
+{
+	// [OpenGL ES 2.0.24] section 3.8 page 84:
+	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
+	// rebound to texture object zero
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
+		{
+			if(mState.samplerTexture[type][sampler].name() == texture)
+			{
+				mState.samplerTexture[type][sampler] = nullptr;
+			}
+		}
+	}
+
+	// [OpenGL ES 2.0.24] section 4.4 page 112:
+	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
+	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
+	// image was attached in the currently bound framebuffer.
+
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(framebuffer)
+	{
+		framebuffer->detachTexture(texture);
+	}
+}
+
+void Context::detachFramebuffer(GLuint framebuffer)
+{
+	// [OpenGL ES 2.0.24] section 4.4 page 107:
+	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
+	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
+
+	if(mState.framebuffer == framebuffer)
+	{
+		bindFramebuffer(0);
+	}
+}
+
+void Context::detachRenderbuffer(GLuint renderbuffer)
+{
+	// [OpenGL ES 2.0.24] section 4.4 page 109:
+	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
+	// had been executed with the target RENDERBUFFER and name of zero.
+
+	if(mState.renderbuffer.name() == renderbuffer)
+	{
+		bindRenderbuffer(0);
+	}
+
+	// [OpenGL ES 2.0.24] section 4.4 page 111:
+	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
+	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
+	// point to which this image was attached in the currently bound framebuffer.
+
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(framebuffer)
+	{
+		framebuffer->detachRenderbuffer(renderbuffer);
+	}
+}
+
+bool Context::cullSkipsDraw(GLenum drawMode)
+{
+	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
+}
+
+bool Context::isTriangleMode(GLenum drawMode)
+{
+	switch(drawMode)
+	{
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		return true;
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+		return false;
+	default: UNREACHABLE(drawMode);
+	}
+
+	return false;
+}
+
+void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+	mState.vertexAttribute[index].mCurrentValue[0] = x;
+	mState.vertexAttribute[index].mCurrentValue[1] = y;
+	mState.vertexAttribute[index].mCurrentValue[2] = z;
+	mState.vertexAttribute[index].mCurrentValue[3] = w;
+
+	mVertexDataManager->dirtyCurrentValue(index);
+}
+
+void Context::bindTexImage(egl::Surface *surface)
+{
+	es1::Texture2D *textureObject = getTexture2D();
+
+	if(textureObject)
+	{
+		textureObject->bindTexImage(surface);
+	}
+}
+
+EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+	switch(target)
+	{
+	case EGL_GL_TEXTURE_2D_KHR:
+		break;
+	case EGL_GL_RENDERBUFFER_KHR:
+		break;
+	default:
+		return EGL_BAD_PARAMETER;
+	}
+
+	if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return EGL_BAD_MATCH;
+	}
+
+	if(target == EGL_GL_TEXTURE_2D_KHR)
+	{
+		Texture *texture = getTexture(name);
+
+		if(!texture || texture->getTarget() != GL_TEXTURE_2D)
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(texture->isShared(GL_TEXTURE_2D, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
+		{
+			return EGL_BAD_ACCESS;
+		}
+
+		if(textureLevel != 0 && !texture->isSamplerComplete())
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+		{
+			return EGL_BAD_PARAMETER;
+		}
+	}
+	else if(target == EGL_GL_RENDERBUFFER_KHR)
+	{
+		Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+		if(!renderbuffer)
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(renderbuffer->isShared())   // Already an EGLImage sibling
+		{
+			return EGL_BAD_ACCESS;
+		}
+	}
+	else UNREACHABLE(target);
+
+	return EGL_SUCCESS;
+}
+
+egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+	if(target == EGL_GL_TEXTURE_2D_KHR)
+	{
+		es1::Texture *texture = getTexture(name);
+
+		return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
+	}
+	else if(target == EGL_GL_RENDERBUFFER_KHR)
+	{
+		es1::Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+		return renderbuffer->createSharedImage();
+	}
+	else UNREACHABLE(target);
+
+	return 0;
+}
+
+Device *Context::getDevice()
+{
+	return device;
+}
+
+void Context::setMatrixMode(GLenum mode)
+{
+	matrixMode = mode;
+}
+
+sw::MatrixStack &Context::currentMatrixStack()
+{
+	switch(matrixMode)
+	{
+	case GL_MODELVIEW:
+		return modelViewStack;
+	case GL_PROJECTION:
+		return projectionStack;
+	case GL_TEXTURE:
+		switch(mState.activeSampler)
+		{
+		case 0: return textureStack0;
+		case 1: return textureStack1;
+		}
+		break;
+	}
+
+	UNREACHABLE(matrixMode);
+	return textureStack0;
+}
+
+void Context::loadIdentity()
+{
+	currentMatrixStack().identity();
+}
+
+void Context::load(const GLfloat *m)
+{
+	currentMatrixStack().load(m);
+}
+
+void Context::pushMatrix()
+{
+	if(!currentMatrixStack().push())
+	{
+		return error(GL_STACK_OVERFLOW);
+	}
+}
+
+void Context::popMatrix()
+{
+	if(!currentMatrixStack().pop())
+	{
+		return error(GL_STACK_OVERFLOW);
+	}
+}
+
+void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	currentMatrixStack().rotate(angle, x, y, z);
+}
+
+void Context::translate(GLfloat x, GLfloat y, GLfloat z)
+{
+	currentMatrixStack().translate(x, y, z);
+}
+
+void Context::scale(GLfloat x, GLfloat y, GLfloat z)
+{
+	currentMatrixStack().scale(x, y, z);
+}
+
+void Context::multiply(const GLfloat *m)
+{
+	currentMatrixStack().multiply(m);
+}
+
+void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
+}
+
+void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
+}
+
+void Context::setClipPlane(int index, const float plane[4])
+{
+	sw::Plane clipPlane = modelViewStack.current() * sw::Plane(plane);
+	device->setClipPlane(index, &clipPlane.A);
+}
+
+void Context::setClipPlaneEnabled(int index, bool enable)
+{
+	clipFlags = (clipFlags & ~((int)!enable << index)) | ((int)enable << index);
+	device->setClipFlags(clipFlags);
+}
+
+bool Context::isClipPlaneEnabled(int index) const
+{
+	return (clipFlags & (1 << index)) != 0;
+}
+
+void Context::setColorLogicOpEnabled(bool enable)
+{
+	colorLogicOpEnabled = enable;
+}
+
+bool Context::isColorLogicOpEnabled() const
+{
+	return colorLogicOpEnabled;
+}
+
+void Context::setLogicalOperation(GLenum logicOp)
+{
+	logicalOperation = logicOp;
+}
+
+void Context::setLineSmoothEnabled(bool enable)
+{
+	lineSmoothEnabled = enable;
+}
+
+bool Context::isLineSmoothEnabled() const
+{
+	return lineSmoothEnabled;
+}
+
+void Context::setColorMaterialEnabled(bool enable)
+{
+	colorMaterialEnabled = enable;
+}
+
+bool Context::isColorMaterialEnabled() const
+{
+	return colorMaterialEnabled;
+}
+
+void Context::setNormalizeEnabled(bool enable)
+{
+	normalizeEnabled = enable;
+}
+
+bool Context::isNormalizeEnabled() const
+{
+	return normalizeEnabled;
+}
+
+void Context::setRescaleNormalEnabled(bool enable)
+{
+	rescaleNormalEnabled = enable;
+}
+
+bool Context::isRescaleNormalEnabled() const
+{
+	return rescaleNormalEnabled;
+}
+
+void Context::setVertexArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::Position].mArrayEnabled = enable;
+}
+
+bool Context::isVertexArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::Position].mArrayEnabled;
+}
+
+void Context::setNormalArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;
+}
+
+bool Context::isNormalArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::Normal].mArrayEnabled;
+}
+
+void Context::setColorArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;
+}
+
+bool Context::isColorArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::Color0].mArrayEnabled;
+}
+
+void Context::setPointSizeArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;
+}
+
+bool Context::isPointSizeArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::PointSize].mArrayEnabled;
+}
+
+void Context::setTextureCoordArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;
+}
+
+bool Context::isTextureCoordArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;
+}
+
+void Context::setMultisampleEnabled(bool enable)
+{
+	multisampleEnabled = enable;
+}
+
+bool Context::isMultisampleEnabled() const
+{
+	return multisampleEnabled;
+}
+
+void Context::setSampleAlphaToOneEnabled(bool enable)
+{
+	sampleAlphaToOneEnabled = enable;
+}
+
+bool Context::isSampleAlphaToOneEnabled() const
+{
+	return sampleAlphaToOneEnabled;
+}
+
+void Context::setPointSpriteEnabled(bool enable)
+{
+	pointSpriteEnabled = enable;
+}
+
+bool Context::isPointSpriteEnabled() const
+{
+	return pointSpriteEnabled;
+}
+
+void Context::setPointSmoothEnabled(bool enable)
+{
+	pointSmoothEnabled = enable;
+}
+
+bool Context::isPointSmoothEnabled() const
+{
+	return pointSmoothEnabled;
+}
+
+void Context::setPointSizeMin(float min)
+{
+	pointSizeMin = min;
+}
+
+void Context::setPointSizeMax(float max)
+{
+	pointSizeMax = max;
+}
+
+void Context::setPointDistanceAttenuation(float a, float b, float c)
+{
+	pointDistanceAttenuation = {a, b, c};
+}
+
+void Context::setPointFadeThresholdSize(float threshold)
+{
+	pointFadeThresholdSize = threshold;
+}
+
+void Context::clientActiveTexture(GLenum texture)
+{
+	clientTexture = texture;
+}
+
+GLenum Context::getClientActiveTexture() const
+{
+	return clientTexture;
+}
+
+unsigned int Context::getActiveTexture() const
+{
+	return mState.activeSampler;
+}
+
+}
+
+egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext)
+{
+	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext
+	return new es1::Context(config, static_cast<const es1::Context*>(shareContext));
+}
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index 90293e3..9051e02 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -1,680 +1,683 @@
-// 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.

-//

-

-// Context.h: Defines the Context class, managing all GL state and performing

-// rendering operations. It is the GLES2 specific implementation of EGLContext.

-

-#ifndef LIBGLES_CM_CONTEXT_H_

-#define LIBGLES_CM_CONTEXT_H_

-

-#include "libEGL/Context.hpp"

-#include "ResourceManager.h"

-#include "common/NameSpace.hpp"

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-#include "Renderer/Sampler.hpp"

-#include "common/MatrixStack.hpp"

-

-#include <GLES/gl.h>

-#include <GLES/glext.h>

-#include <EGL/egl.h>

-

-#include <map>

-#include <string>

-

-namespace egl

-{

-class Display;

-class Surface;

-class Config;

-}

-

-namespace es1

-{

-struct TranslatedAttribute;

-struct TranslatedIndexData;

-

-class Device;

-class Buffer;

-class Texture;

-class Texture2D;

-class TextureExternal;

-class Framebuffer;

-class Renderbuffer;

-class RenderbufferStorage;

-class Colorbuffer;

-class Depthbuffer;

-class StreamingIndexBuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-class VertexDataManager;

-class IndexDataManager;

-

-enum

-{

-    MAX_VERTEX_ATTRIBS = sw::VERTEX_ATTRIBUTES,

-    MAX_VARYING_VECTORS = 10,

-    MAX_TEXTURE_UNITS = 2,

-    MAX_DRAW_BUFFERS = 1,

-	MAX_LIGHTS = 8,

-	MAX_CLIP_PLANES = sw::MAX_CLIP_PLANES,

-

-	MAX_MODELVIEW_STACK_DEPTH = 32,

-	MAX_PROJECTION_STACK_DEPTH = 2,

-	MAX_TEXTURE_STACK_DEPTH = 2,

-};

-

-const GLenum compressedTextureFormats[] =

-{

-	GL_ETC1_RGB8_OES,

-#if (S3TC_SUPPORT)

-	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,

-	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,

-#endif

-};

-

-const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);

-

-const GLint multisampleCount[] = {4, 2, 1};

-const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);

-const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];

-

-const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;

-const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;

-const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;

-const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;

-const float SMOOTH_LINE_WIDTH_RANGE_MIN = 1.0f;

-const float SMOOTH_LINE_WIDTH_RANGE_MAX = 1.0f;

-const float SMOOTH_POINT_SIZE_RANGE_MIN = 0.125f;

-const float SMOOTH_POINT_SIZE_RANGE_MAX = 8192.0f;

-const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;

-

-struct Color

-{

-    float red;

-    float green;

-    float blue;

-    float alpha;

-};

-

-struct Point

-{

-	float x;

-	float y;

-	float z;

-	float w;

-};

-

-struct Vector

-{

-	float x;

-	float y;

-	float z;

-};

-

-struct Attenuation

-{

-	float constant;

-	float linear;

-	float quadratic;

-};

-

-struct Light

-{

-	bool enabled;

-	Color ambient;

-	Color diffuse;

-	Color specular;

-	Point position;

-	Vector direction;

-	Attenuation attenuation;

-	float spotExponent;

-	float spotCutoffAngle;

-};

-

-// Helper structure describing a single vertex attribute

-class VertexAttribute

-{

-public:

-    VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)

-    {

-        mCurrentValue[0] = 0.0f;

-        mCurrentValue[1] = 0.0f;

-        mCurrentValue[2] = 0.0f;

-        mCurrentValue[3] = 1.0f;

-    }

-

-    int typeSize() const

-    {

-        switch(mType)

-        {

-        case GL_BYTE:           return mSize * sizeof(GLbyte);

-        case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);

-        case GL_SHORT:          return mSize * sizeof(GLshort);

-        case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);

-        case GL_FIXED:          return mSize * sizeof(GLfixed);

-        case GL_FLOAT:          return mSize * sizeof(GLfloat);

-        default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);

-        }

-    }

-

-    GLsizei stride() const

-    {

-        return mStride ? mStride : typeSize();

-    }

-

-    // From glVertexAttribPointer

-    GLenum mType;

-    GLint mSize;

-    bool mNormalized;

-    GLsizei mStride;   // 0 means natural stride

-

-    union

-    {

-        const void *mPointer;

-        intptr_t mOffset;

-    };

-

-    gl::BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.

-

-    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray

-    float mCurrentValue[4];   // From glVertexAttrib

-};

-

-typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];

-

-struct TextureUnit

-{

-	Color color;

-	GLenum environmentMode;

-	GLenum combineRGB;

-	GLenum combineAlpha;

-	GLenum src0RGB;

-	GLenum src0Alpha;

-	GLenum src1RGB;

-	GLenum src1Alpha;

-	GLenum src2RGB;

-	GLenum src2Alpha;

-	GLenum operand0RGB;

-	GLenum operand0Alpha;

-	GLenum operand1RGB;

-	GLenum operand1Alpha;

-	GLenum operand2RGB;

-	GLenum operand2Alpha;

-};

-

-// Helper structure to store all raw state

-struct State

-{

-    Color colorClearValue;

-    GLclampf depthClearValue;

-    int stencilClearValue;

-

-    bool cullFaceEnabled;

-    GLenum cullMode;

-    GLenum frontFace;

-    bool depthTestEnabled;

-    GLenum depthFunc;

-    bool blendEnabled;

-    GLenum sourceBlendRGB;

-    GLenum destBlendRGB;

-    GLenum sourceBlendAlpha;

-    GLenum destBlendAlpha;

-    GLenum blendEquationRGB;

-    GLenum blendEquationAlpha;

-    bool stencilTestEnabled;

-    GLenum stencilFunc;

-    GLint stencilRef;

-    GLuint stencilMask;

-    GLenum stencilFail;

-    GLenum stencilPassDepthFail;

-    GLenum stencilPassDepthPass;

-    GLuint stencilWritemask;

-    bool polygonOffsetFillEnabled;

-    GLfloat polygonOffsetFactor;

-    GLfloat polygonOffsetUnits;

-    bool sampleAlphaToCoverageEnabled;

-    bool sampleCoverageEnabled;

-    GLclampf sampleCoverageValue;

-    bool sampleCoverageInvert;

-    bool scissorTestEnabled;

-    bool ditherEnabled;

-	GLenum shadeModel;

-

-    GLfloat lineWidth;

-

-    GLenum generateMipmapHint;

-	GLenum perspectiveCorrectionHint;

-	GLenum fogHint;

-

-    GLint viewportX;

-    GLint viewportY;

-    GLsizei viewportWidth;

-    GLsizei viewportHeight;

-    float zNear;

-    float zFar;

-

-    GLint scissorX;

-    GLint scissorY;

-    GLsizei scissorWidth;

-    GLsizei scissorHeight;

-

-    bool colorMaskRed;

-    bool colorMaskGreen;

-    bool colorMaskBlue;

-    bool colorMaskAlpha;

-    bool depthMask;

-

-    unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0

-    gl::BindingPointer<Buffer> arrayBuffer;

-    gl::BindingPointer<Buffer> elementArrayBuffer;

-    GLuint framebuffer;

-    gl::BindingPointer<Renderbuffer> renderbuffer;

-

-    VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];

-    gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_TEXTURE_UNITS];

-

-    GLint unpackAlignment;

-    GLint packAlignment;

-

-	TextureUnit textureUnit[MAX_TEXTURE_UNITS];

-};

-

-class Context : public egl::Context

-{

-public:

-    Context(const egl::Config *config, const Context *shareContext);

-

-	virtual void makeCurrent(egl::Surface *surface);

-	virtual int getClientVersion() const;

-    virtual void finish();

-

-    void markAllStateDirty();

-

-    // State manipulation

-    void setClearColor(float red, float green, float blue, float alpha);

-    void setClearDepth(float depth);

-    void setClearStencil(int stencil);

-

-    void setCullFaceEnabled(bool enabled);

-    bool isCullFaceEnabled() const;

-    void setCullMode(GLenum mode);

-    void setFrontFace(GLenum front);

-

-    void setDepthTestEnabled(bool enabled);

-    bool isDepthTestEnabled() const;

-    void setDepthFunc(GLenum depthFunc);

-    void setDepthRange(float zNear, float zFar);

-

-	void setAlphaTestEnabled(bool enabled);

-    bool isAlphaTestEnabled() const;

-    void setAlphaFunc(GLenum alphaFunc, GLclampf reference);

-

-    void setBlendEnabled(bool enabled);

-    bool isBlendEnabled() const;

-    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);

-    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);

-

-    void setStencilTestEnabled(bool enabled);

-    bool isStencilTestEnabled() const;

-    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);

-    void setStencilWritemask(GLuint stencilWritemask);

-    void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);

-

-    void setPolygonOffsetFillEnabled(bool enabled);

-    bool isPolygonOffsetFillEnabled() const;

-    void setPolygonOffsetParams(GLfloat factor, GLfloat units);

-

-    void setSampleAlphaToCoverageEnabled(bool enabled);

-    bool isSampleAlphaToCoverageEnabled() const;

-    void setSampleCoverageEnabled(bool enabled);

-    bool isSampleCoverageEnabled() const;

-    void setSampleCoverageParams(GLclampf value, bool invert);

-

-	void setShadeModel(GLenum mode);

-    void setDitherEnabled(bool enabled);

-    bool isDitherEnabled() const;

-	void setLightingEnabled(bool enabled);

-	bool isLightingEnabled() const;

-	void setLightEnabled(int index, bool enable);

-	bool isLightEnabled(int index) const;

-	void setLightAmbient(int index, float r, float g, float b, float a);

-	void setLightDiffuse(int index, float r, float g, float b, float a);

-	void setLightSpecular(int index, float r, float g, float b, float a);

-	void setLightPosition(int index, float x, float y, float z, float w);

-	void setLightDirection(int index, float x, float y, float z);

-	void setLightAttenuationConstant(int index, float constant);

-	void setLightAttenuationLinear(int index, float linear);

-	void setLightAttenuationQuadratic(int index, float quadratic);

-	void setSpotLightExponent(int index, float exponent);

-	void setSpotLightCutoff(int index, float cutoff);

-

-	void setGlobalAmbient(float red, float green, float blue, float alpha);

-	void setMaterialAmbient(float red, float green, float blue, float alpha);

-	void setMaterialDiffuse(float red, float green, float blue, float alpha);

-	void setMaterialSpecular(float red, float green, float blue, float alpha);

-	void setMaterialEmission(float red, float green, float blue, float alpha);

-	void setMaterialShininess(float shininess);

-	void setLightModelTwoSide(bool enable);

-

-	void setFogEnabled(bool enabled);

-	bool isFogEnabled() const;

-	void setFogMode(GLenum mode);

-	void setFogDensity(float fogDensity);

-	void setFogStart(float fogStart);

-	void setFogEnd(float fogEnd);

-	void setFogColor(float r, float g, float b, float a);

-

-    void setTexture2Denabled(bool enabled);

-	bool isTexture2Denabled() const;

-	void setTextureExternalEnabled(bool enabled);

-	bool isTextureExternalEnabled() const;

-    void clientActiveTexture(GLenum texture);

-	GLenum getClientActiveTexture() const;

-	unsigned int getActiveTexture() const;

-

-	void setTextureEnvMode(GLenum texEnvMode);

-	void setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

-	void setCombineRGB(GLenum combineRGB);

-	void setCombineAlpha(GLenum combineAlpha);

-	void setOperand0RGB(GLenum operand);

-	void setOperand1RGB(GLenum operand);

-	void setOperand2RGB(GLenum operand);

-	void setOperand0Alpha(GLenum operand);

-	void setOperand1Alpha(GLenum operand);

-	void setOperand2Alpha(GLenum operand);

-	void setSrc0RGB(GLenum src);

-	void setSrc1RGB(GLenum src);

-	void setSrc2RGB(GLenum src);

-	void setSrc0Alpha(GLenum src);

-	void setSrc1Alpha(GLenum src);

-	void setSrc2Alpha(GLenum src);

-

-    void setLineWidth(GLfloat width);

-

-    void setGenerateMipmapHint(GLenum hint);

-	void setPerspectiveCorrectionHint(GLenum hint);

-	void setFogHint(GLenum hint);

-

-    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-	void setScissorTestEnabled(bool enabled);

-    bool isScissorTestEnabled() const;

-    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-    void setColorMask(bool red, bool green, bool blue, bool alpha);

-    void setDepthMask(bool mask);

-

-    void setActiveSampler(unsigned int active);

-

-    GLuint getFramebufferName() const;

-    GLuint getRenderbufferName() const;

-

-    GLuint getArrayBufferName() const;

-

-    void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);

-    const VertexAttribute &getVertexAttribState(unsigned int attribNum);

-    void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,

-                              bool normalized, GLsizei stride, const void *pointer);

-    const void *getVertexAttribPointer(unsigned int attribNum) const;

-

-    const VertexAttributeArray &getVertexAttributes();

-

-    void setUnpackAlignment(GLint alignment);

-    GLint getUnpackAlignment() const;

-

-    void setPackAlignment(GLint alignment);

-    GLint getPackAlignment() const;

-

-    // These create and destroy methods are merely pass-throughs to

-    // ResourceManager, which owns these object types

-    GLuint createBuffer();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-

-    void deleteBuffer(GLuint buffer);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-

-    // Framebuffers are owned by the Context, so these methods do not pass through

-    GLuint createFramebuffer();

-    void deleteFramebuffer(GLuint framebuffer);

-

-    void bindArrayBuffer(GLuint buffer);

-    void bindElementArrayBuffer(GLuint buffer);

-    void bindTexture2D(GLuint texture);

-    void bindTextureExternal(GLuint texture);

-    void bindFramebuffer(GLuint framebuffer);

-    void bindRenderbuffer(GLuint renderbuffer);

-

-    void setFramebufferZero(Framebuffer *framebuffer);

-

-    void setRenderbufferStorage(RenderbufferStorage *renderbuffer);

-

-    void setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);

-

-    Buffer *getBuffer(GLuint handle);

-    virtual Texture *getTexture(GLuint handle);

-    Framebuffer *getFramebuffer(GLuint handle);

-    virtual Renderbuffer *getRenderbuffer(GLuint handle);

-

-    Buffer *getArrayBuffer();

-    Buffer *getElementArrayBuffer();

-    Texture2D *getTexture2D();

-    TextureExternal *getTextureExternal();

-    Texture *getSamplerTexture(unsigned int sampler, TextureType type);

-    Framebuffer *getFramebuffer();

-

-    bool getFloatv(GLenum pname, GLfloat *params);

-    bool getIntegerv(GLenum pname, GLint *params);

-    bool getBooleanv(GLenum pname, GLboolean *params);

-    bool getPointerv(GLenum pname, const GLvoid **params);

-

-    int getQueryParameterNum(GLenum pname);

-	bool isQueryParameterInt(GLenum pname);

-	bool isQueryParameterFloat(GLenum pname);

-	bool isQueryParameterBool(GLenum pname);

-	bool isQueryParameterPointer(GLenum pname);

-

-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);

-    void clear(GLbitfield mask);

-    void drawArrays(GLenum mode, GLint first, GLsizei count);

-    void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);

-    void drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);

-    void flush();

-

-    void recordInvalidEnum();

-    void recordInvalidValue();

-    void recordInvalidOperation();

-    void recordOutOfMemory();

-    void recordInvalidFramebufferOperation();

-	void recordMatrixStackOverflow();

-	void recordMatrixStackUnderflow();

-

-    GLenum getError();

-

-    static int getSupportedMultisampleCount(int requested);

-

-	virtual void bindTexImage(egl::Surface *surface);

-	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);

-	virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);

-

-	Device *getDevice();

-

-    void setMatrixMode(GLenum mode);

-    void loadIdentity();

-	void load(const GLfloat *m);

-    void pushMatrix();

-    void popMatrix();

-    void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

-    void translate(GLfloat x, GLfloat y, GLfloat z);

-	void scale(GLfloat x, GLfloat y, GLfloat z);

-    void multiply(const GLfloat *m);

-	void frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-    void ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-

-	void setClipPlane(int index, const float plane[4]);

-	void setClipPlaneEnabled(int index, bool enable);

-	bool isClipPlaneEnabled(int index) const;

-

-	void setColorLogicOpEnabled(bool enable);

-	bool isColorLogicOpEnabled() const;

-	void setLogicalOperation(GLenum logicOp);

-

-	void setPointSmoothEnabled(bool enable);

-	bool isPointSmoothEnabled() const;

-

-	void setLineSmoothEnabled(bool enable);

-	bool isLineSmoothEnabled() const;

-

-	void setColorMaterialEnabled(bool enable);

-	bool isColorMaterialEnabled() const;

-

-	void setNormalizeEnabled(bool enable);

-	bool isNormalizeEnabled() const;

-

-	void setRescaleNormalEnabled(bool enable);

-	bool isRescaleNormalEnabled() const;

-

-	void setVertexArrayEnabled(bool enable);

-	bool isVertexArrayEnabled() const;

-

-	void setNormalArrayEnabled(bool enable);

-	bool isNormalArrayEnabled() const;

-

-	void setColorArrayEnabled(bool enable);

-	bool isColorArrayEnabled() const;

-

-	void setPointSizeArrayEnabled(bool enable);

-	bool isPointSizeArrayEnabled() const;

-

-	void setTextureCoordArrayEnabled(bool enable);

-	bool isTextureCoordArrayEnabled() const;

-

-	void setMultisampleEnabled(bool enable);

-	bool isMultisampleEnabled() const;

-

-	void setSampleAlphaToOneEnabled(bool enable);

-	bool isSampleAlphaToOneEnabled() const;

-

-	void setPointSpriteEnabled(bool enable);

-	bool isPointSpriteEnabled() const;

-	void setPointSizeMin(float min);

-	void setPointSizeMax(float max);

-	void setPointDistanceAttenuation(float a, float b, float c);

-	void setPointFadeThresholdSize(float threshold);

-

-private:

-	virtual ~Context();

-

-    bool applyRenderTarget();

-    void applyState(GLenum drawMode);

-    GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);

-    GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);

-    void applyTextures();

-	void applyTexture(int sampler, Texture *texture);

-

-    void detachBuffer(GLuint buffer);

-    void detachTexture(GLuint texture);

-    void detachFramebuffer(GLuint framebuffer);

-    void detachRenderbuffer(GLuint renderbuffer);

-

-    bool cullSkipsDraw(GLenum drawMode);

-    bool isTriangleMode(GLenum drawMode);

-

-    State mState;

-

-    gl::BindingPointer<Texture2D> mTexture2DZero;

-    gl::BindingPointer<TextureExternal> mTextureExternalZero;

-

-	gl::NameSpace<Framebuffer> mFramebufferNameSpace;

-

-    VertexDataManager *mVertexDataManager;

-    IndexDataManager *mIndexDataManager;

-

-	bool lightingEnabled;

-	Light light[MAX_LIGHTS];

-	Color globalAmbient;

-	Color materialAmbient;

-	Color materialDiffuse;

-	Color materialSpecular;

-	Color materialEmission;

-	GLfloat materialShininess;

-	bool lightModelTwoSide;

-

-    // Recorded errors

-    bool mInvalidEnum;

-    bool mInvalidValue;

-    bool mInvalidOperation;

-    bool mOutOfMemory;

-    bool mInvalidFramebufferOperation;

-	bool mMatrixStackOverflow;

-	bool mMatrixStackUnderflow;

-

-    bool mHasBeenCurrent;

-

-    // state caching flags

-    bool mDepthStateDirty;

-    bool mMaskStateDirty;

-    bool mBlendStateDirty;

-    bool mStencilStateDirty;

-    bool mPolygonOffsetStateDirty;

-    bool mSampleStateDirty;

-    bool mFrontFaceDirty;

-    bool mDitherStateDirty;

-

-	sw::MatrixStack &currentMatrixStack();

-	GLenum matrixMode;

-    sw::MatrixStack modelViewStack;

-	sw::MatrixStack projectionStack;

-	sw::MatrixStack textureStack0;

-	sw::MatrixStack textureStack1;

-

-	bool texture2Denabled[MAX_TEXTURE_UNITS];

-	bool textureExternalEnabled[MAX_TEXTURE_UNITS];

-	GLenum clientTexture;

-

-	int clipFlags;

-

-	bool alphaTestEnabled;

-	GLenum alphaTestFunc;

-	float alphaTestRef;

-

-	bool fogEnabled;

-	GLenum fogMode;

-	float fogDensity;

-	float fogStart;

-	float fogEnd;

-	Color fogColor;

-

-	bool lineSmoothEnabled;

-	bool colorMaterialEnabled;

-	bool normalizeEnabled;

-	bool rescaleNormalEnabled;

-	bool multisampleEnabled;

-	bool sampleAlphaToOneEnabled;

-

-	bool pointSpriteEnabled;

-	bool pointSmoothEnabled;

-	float pointSizeMin;

-	float pointSizeMax;

-	Attenuation pointDistanceAttenuation;

-	float pointFadeThresholdSize;

-

-	bool colorLogicOpEnabled;

-	GLenum logicalOperation;

-

-	Device *device;

-    ResourceManager *mResourceManager;

-};

-}

-

-#endif   // INCLUDE_CONTEXT_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Context.h: Defines the Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#ifndef LIBGLES_CM_CONTEXT_H_
+#define LIBGLES_CM_CONTEXT_H_
+
+#include "libEGL/Context.hpp"
+#include "ResourceManager.h"
+#include "common/NameSpace.hpp"
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+#include "Renderer/Sampler.hpp"
+#include "common/MatrixStack.hpp"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <EGL/egl.h>
+
+#include <map>
+#include <string>
+
+namespace egl
+{
+class Display;
+class Surface;
+class Config;
+}
+
+namespace es1
+{
+struct TranslatedAttribute;
+struct TranslatedIndexData;
+
+class Device;
+class Buffer;
+class Texture;
+class Texture2D;
+class TextureExternal;
+class Framebuffer;
+class Renderbuffer;
+class RenderbufferStorage;
+class Colorbuffer;
+class Depthbuffer;
+class StreamingIndexBuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+class VertexDataManager;
+class IndexDataManager;
+
+enum
+{
+	MAX_VERTEX_ATTRIBS = sw::VERTEX_ATTRIBUTES,
+	MAX_VARYING_VECTORS = 10,
+	MAX_TEXTURE_UNITS = 2,
+	MAX_DRAW_BUFFERS = 1,
+	MAX_LIGHTS = 8,
+	MAX_CLIP_PLANES = sw::MAX_CLIP_PLANES,
+
+	MAX_MODELVIEW_STACK_DEPTH = 32,
+	MAX_PROJECTION_STACK_DEPTH = 2,
+	MAX_TEXTURE_STACK_DEPTH = 2,
+};
+
+const GLenum compressedTextureFormats[] =
+{
+	GL_ETC1_RGB8_OES,
+#if (S3TC_SUPPORT)
+	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+#endif
+};
+
+const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
+
+const GLint multisampleCount[] = {4, 2, 1};
+const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);
+const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];
+
+const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
+const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
+const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;
+const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;
+const float SMOOTH_LINE_WIDTH_RANGE_MIN = 1.0f;
+const float SMOOTH_LINE_WIDTH_RANGE_MAX = 1.0f;
+const float SMOOTH_POINT_SIZE_RANGE_MIN = 0.125f;
+const float SMOOTH_POINT_SIZE_RANGE_MAX = 8192.0f;
+const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;
+
+struct Color
+{
+	float red;
+	float green;
+	float blue;
+	float alpha;
+};
+
+struct Point
+{
+	float x;
+	float y;
+	float z;
+	float w;
+};
+
+struct Vector
+{
+	float x;
+	float y;
+	float z;
+};
+
+struct Attenuation
+{
+	float constant;
+	float linear;
+	float quadratic;
+};
+
+struct Light
+{
+	bool enabled;
+	Color ambient;
+	Color diffuse;
+	Color specular;
+	Point position;
+	Vector direction;
+	Attenuation attenuation;
+	float spotExponent;
+	float spotCutoffAngle;
+};
+
+// Helper structure describing a single vertex attribute
+class VertexAttribute
+{
+public:
+	VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mStride(0), mPointer(nullptr), mArrayEnabled(false)
+	{
+		mCurrentValue[0] = 0.0f;
+		mCurrentValue[1] = 0.0f;
+		mCurrentValue[2] = 0.0f;
+		mCurrentValue[3] = 1.0f;
+	}
+
+	int typeSize() const
+	{
+		switch(mType)
+		{
+		case GL_BYTE:           return mSize * sizeof(GLbyte);
+		case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);
+		case GL_SHORT:          return mSize * sizeof(GLshort);
+		case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
+		case GL_FIXED:          return mSize * sizeof(GLfixed);
+		case GL_FLOAT:          return mSize * sizeof(GLfloat);
+		default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);
+		}
+	}
+
+	GLsizei stride() const
+	{
+		return mStride ? mStride : typeSize();
+	}
+
+	// From glVertexAttribPointer
+	GLenum mType;
+	GLint mSize;
+	bool mNormalized;
+	GLsizei mStride;   // 0 means natural stride
+
+	union
+	{
+		const void *mPointer;
+		intptr_t mOffset;
+	};
+
+	gl::BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
+
+	bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
+	float mCurrentValue[4];   // From glVertexAttrib
+};
+
+typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
+
+struct TextureUnit
+{
+	Color color;
+	GLenum environmentMode;
+	GLenum combineRGB;
+	GLenum combineAlpha;
+	GLenum src0RGB;
+	GLenum src0Alpha;
+	GLenum src1RGB;
+	GLenum src1Alpha;
+	GLenum src2RGB;
+	GLenum src2Alpha;
+	GLenum operand0RGB;
+	GLenum operand0Alpha;
+	GLenum operand1RGB;
+	GLenum operand1Alpha;
+	GLenum operand2RGB;
+	GLenum operand2Alpha;
+};
+
+// Helper structure to store all raw state
+struct State
+{
+	Color colorClearValue;
+	GLclampf depthClearValue;
+	int stencilClearValue;
+
+	bool cullFaceEnabled;
+	GLenum cullMode;
+	GLenum frontFace;
+	bool depthTestEnabled;
+	GLenum depthFunc;
+	bool blendEnabled;
+	GLenum sourceBlendRGB;
+	GLenum destBlendRGB;
+	GLenum sourceBlendAlpha;
+	GLenum destBlendAlpha;
+	GLenum blendEquationRGB;
+	GLenum blendEquationAlpha;
+	bool stencilTestEnabled;
+	GLenum stencilFunc;
+	GLint stencilRef;
+	GLuint stencilMask;
+	GLenum stencilFail;
+	GLenum stencilPassDepthFail;
+	GLenum stencilPassDepthPass;
+	GLuint stencilWritemask;
+	bool polygonOffsetFillEnabled;
+	GLfloat polygonOffsetFactor;
+	GLfloat polygonOffsetUnits;
+	bool sampleAlphaToCoverageEnabled;
+	bool sampleCoverageEnabled;
+	GLclampf sampleCoverageValue;
+	bool sampleCoverageInvert;
+	bool scissorTestEnabled;
+	bool ditherEnabled;
+	GLenum shadeModel;
+
+	GLfloat lineWidth;
+
+	GLenum generateMipmapHint;
+	GLenum perspectiveCorrectionHint;
+	GLenum fogHint;
+
+	GLint viewportX;
+	GLint viewportY;
+	GLsizei viewportWidth;
+	GLsizei viewportHeight;
+	float zNear;
+	float zFar;
+
+	GLint scissorX;
+	GLint scissorY;
+	GLsizei scissorWidth;
+	GLsizei scissorHeight;
+
+	bool colorMaskRed;
+	bool colorMaskGreen;
+	bool colorMaskBlue;
+	bool colorMaskAlpha;
+	bool depthMask;
+
+	unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0
+	gl::BindingPointer<Buffer> arrayBuffer;
+	gl::BindingPointer<Buffer> elementArrayBuffer;
+	GLuint framebuffer;
+	gl::BindingPointer<Renderbuffer> renderbuffer;
+
+	VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
+	gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_TEXTURE_UNITS];
+
+	GLint unpackAlignment;
+	GLint packAlignment;
+
+	TextureUnit textureUnit[MAX_TEXTURE_UNITS];
+};
+
+class Context : public egl::Context
+{
+public:
+	Context(const egl::Config *config, const Context *shareContext);
+
+	virtual void makeCurrent(egl::Surface *surface);
+	virtual int getClientVersion() const;
+	virtual void finish();
+
+	void markAllStateDirty();
+
+	// State manipulation
+	void setClearColor(float red, float green, float blue, float alpha);
+	void setClearDepth(float depth);
+	void setClearStencil(int stencil);
+
+	void setCullFaceEnabled(bool enabled);
+	bool isCullFaceEnabled() const;
+	void setCullMode(GLenum mode);
+	void setFrontFace(GLenum front);
+
+	void setDepthTestEnabled(bool enabled);
+	bool isDepthTestEnabled() const;
+	void setDepthFunc(GLenum depthFunc);
+	void setDepthRange(float zNear, float zFar);
+
+	void setAlphaTestEnabled(bool enabled);
+	bool isAlphaTestEnabled() const;
+	void setAlphaFunc(GLenum alphaFunc, GLclampf reference);
+
+	void setBlendEnabled(bool enabled);
+	bool isBlendEnabled() const;
+	void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
+	void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
+
+	void setStencilTestEnabled(bool enabled);
+	bool isStencilTestEnabled() const;
+	void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
+	void setStencilWritemask(GLuint stencilWritemask);
+	void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
+
+	void setPolygonOffsetFillEnabled(bool enabled);
+	bool isPolygonOffsetFillEnabled() const;
+	void setPolygonOffsetParams(GLfloat factor, GLfloat units);
+
+	void setSampleAlphaToCoverageEnabled(bool enabled);
+	bool isSampleAlphaToCoverageEnabled() const;
+	void setSampleCoverageEnabled(bool enabled);
+	bool isSampleCoverageEnabled() const;
+	void setSampleCoverageParams(GLclampf value, bool invert);
+
+	void setShadeModel(GLenum mode);
+	void setDitherEnabled(bool enabled);
+	bool isDitherEnabled() const;
+	void setLightingEnabled(bool enabled);
+	bool isLightingEnabled() const;
+	void setLightEnabled(int index, bool enable);
+	bool isLightEnabled(int index) const;
+	void setLightAmbient(int index, float r, float g, float b, float a);
+	void setLightDiffuse(int index, float r, float g, float b, float a);
+	void setLightSpecular(int index, float r, float g, float b, float a);
+	void setLightPosition(int index, float x, float y, float z, float w);
+	void setLightDirection(int index, float x, float y, float z);
+	void setLightAttenuationConstant(int index, float constant);
+	void setLightAttenuationLinear(int index, float linear);
+	void setLightAttenuationQuadratic(int index, float quadratic);
+	void setSpotLightExponent(int index, float exponent);
+	void setSpotLightCutoff(int index, float cutoff);
+
+	void setGlobalAmbient(float red, float green, float blue, float alpha);
+	void setMaterialAmbient(float red, float green, float blue, float alpha);
+	void setMaterialDiffuse(float red, float green, float blue, float alpha);
+	void setMaterialSpecular(float red, float green, float blue, float alpha);
+	void setMaterialEmission(float red, float green, float blue, float alpha);
+	void setMaterialShininess(float shininess);
+	void setLightModelTwoSide(bool enable);
+
+	void setFogEnabled(bool enabled);
+	bool isFogEnabled() const;
+	void setFogMode(GLenum mode);
+	void setFogDensity(float fogDensity);
+	void setFogStart(float fogStart);
+	void setFogEnd(float fogEnd);
+	void setFogColor(float r, float g, float b, float a);
+
+	void setTexture2Denabled(bool enabled);
+	bool isTexture2Denabled() const;
+	void setTextureExternalEnabled(bool enabled);
+	bool isTextureExternalEnabled() const;
+	void clientActiveTexture(GLenum texture);
+	GLenum getClientActiveTexture() const;
+	unsigned int getActiveTexture() const;
+
+	void setTextureEnvMode(GLenum texEnvMode);
+	void setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void setCombineRGB(GLenum combineRGB);
+	void setCombineAlpha(GLenum combineAlpha);
+	void setOperand0RGB(GLenum operand);
+	void setOperand1RGB(GLenum operand);
+	void setOperand2RGB(GLenum operand);
+	void setOperand0Alpha(GLenum operand);
+	void setOperand1Alpha(GLenum operand);
+	void setOperand2Alpha(GLenum operand);
+	void setSrc0RGB(GLenum src);
+	void setSrc1RGB(GLenum src);
+	void setSrc2RGB(GLenum src);
+	void setSrc0Alpha(GLenum src);
+	void setSrc1Alpha(GLenum src);
+	void setSrc2Alpha(GLenum src);
+
+	void setLineWidth(GLfloat width);
+
+	void setGenerateMipmapHint(GLenum hint);
+	void setPerspectiveCorrectionHint(GLenum hint);
+	void setFogHint(GLenum hint);
+
+	void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setScissorTestEnabled(bool enabled);
+	bool isScissorTestEnabled() const;
+	void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setColorMask(bool red, bool green, bool blue, bool alpha);
+	void setDepthMask(bool mask);
+
+	void setActiveSampler(unsigned int active);
+
+	GLuint getFramebufferName() const;
+	GLuint getRenderbufferName() const;
+
+	GLuint getArrayBufferName() const;
+
+	void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);
+	const VertexAttribute &getVertexAttribState(unsigned int attribNum);
+	void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
+	                          bool normalized, GLsizei stride, const void *pointer);
+	const void *getVertexAttribPointer(unsigned int attribNum) const;
+
+	const VertexAttributeArray &getVertexAttributes();
+
+	void setUnpackAlignment(GLint alignment);
+	GLint getUnpackAlignment() const;
+
+	void setPackAlignment(GLint alignment);
+	GLint getPackAlignment() const;
+
+	// These create and destroy methods are merely pass-throughs to
+	// ResourceManager, which owns these object types
+	GLuint createBuffer();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+
+	void deleteBuffer(GLuint buffer);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+
+	// Framebuffers are owned by the Context, so these methods do not pass through
+	GLuint createFramebuffer();
+	void deleteFramebuffer(GLuint framebuffer);
+
+	void bindArrayBuffer(GLuint buffer);
+	void bindElementArrayBuffer(GLuint buffer);
+	void bindTexture2D(GLuint texture);
+	void bindTextureExternal(GLuint texture);
+	void bindFramebuffer(GLuint framebuffer);
+	void bindRenderbuffer(GLuint renderbuffer);
+
+	void setFramebufferZero(Framebuffer *framebuffer);
+
+	void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
+
+	void setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+	Buffer *getBuffer(GLuint handle);
+	virtual Texture *getTexture(GLuint handle);
+	Framebuffer *getFramebuffer(GLuint handle);
+	virtual Renderbuffer *getRenderbuffer(GLuint handle);
+
+	Buffer *getArrayBuffer();
+	Buffer *getElementArrayBuffer();
+	Texture2D *getTexture2D();
+	TextureExternal *getTextureExternal();
+	Texture *getSamplerTexture(unsigned int sampler, TextureType type);
+	Framebuffer *getFramebuffer();
+
+	bool getFloatv(GLenum pname, GLfloat *params);
+	bool getIntegerv(GLenum pname, GLint *params);
+	bool getBooleanv(GLenum pname, GLboolean *params);
+	bool getPointerv(GLenum pname, const GLvoid **params);
+
+	int getQueryParameterNum(GLenum pname);
+	bool isQueryParameterInt(GLenum pname);
+	bool isQueryParameterFloat(GLenum pname);
+	bool isQueryParameterBool(GLenum pname);
+	bool isQueryParameterPointer(GLenum pname);
+
+	void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
+	void clear(GLbitfield mask);
+	void drawArrays(GLenum mode, GLint first, GLsizei count);
+	void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
+	void drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+	void flush();
+
+	void recordInvalidEnum();
+	void recordInvalidValue();
+	void recordInvalidOperation();
+	void recordOutOfMemory();
+	void recordInvalidFramebufferOperation();
+	void recordMatrixStackOverflow();
+	void recordMatrixStackUnderflow();
+
+	GLenum getError();
+
+	static int getSupportedMultisampleCount(int requested);
+
+	virtual void bindTexImage(egl::Surface *surface);
+	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+	virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+
+	Device *getDevice();
+
+	void setMatrixMode(GLenum mode);
+	void loadIdentity();
+	void load(const GLfloat *m);
+	void pushMatrix();
+	void popMatrix();
+	void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+	void translate(GLfloat x, GLfloat y, GLfloat z);
+	void scale(GLfloat x, GLfloat y, GLfloat z);
+	void multiply(const GLfloat *m);
+	void frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+
+	void setClipPlane(int index, const float plane[4]);
+	void setClipPlaneEnabled(int index, bool enable);
+	bool isClipPlaneEnabled(int index) const;
+
+	void setColorLogicOpEnabled(bool enable);
+	bool isColorLogicOpEnabled() const;
+	void setLogicalOperation(GLenum logicOp);
+
+	void setPointSmoothEnabled(bool enable);
+	bool isPointSmoothEnabled() const;
+
+	void setLineSmoothEnabled(bool enable);
+	bool isLineSmoothEnabled() const;
+
+	void setColorMaterialEnabled(bool enable);
+	bool isColorMaterialEnabled() const;
+
+	void setNormalizeEnabled(bool enable);
+	bool isNormalizeEnabled() const;
+
+	void setRescaleNormalEnabled(bool enable);
+	bool isRescaleNormalEnabled() const;
+
+	void setVertexArrayEnabled(bool enable);
+	bool isVertexArrayEnabled() const;
+
+	void setNormalArrayEnabled(bool enable);
+	bool isNormalArrayEnabled() const;
+
+	void setColorArrayEnabled(bool enable);
+	bool isColorArrayEnabled() const;
+
+	void setPointSizeArrayEnabled(bool enable);
+	bool isPointSizeArrayEnabled() const;
+
+	void setTextureCoordArrayEnabled(bool enable);
+	bool isTextureCoordArrayEnabled() const;
+
+	void setMultisampleEnabled(bool enable);
+	bool isMultisampleEnabled() const;
+
+	void setSampleAlphaToOneEnabled(bool enable);
+	bool isSampleAlphaToOneEnabled() const;
+
+	void setPointSpriteEnabled(bool enable);
+	bool isPointSpriteEnabled() const;
+	void setPointSizeMin(float min);
+	void setPointSizeMax(float max);
+	void setPointDistanceAttenuation(float a, float b, float c);
+	void setPointFadeThresholdSize(float threshold);
+
+private:
+	virtual ~Context();
+
+	bool applyRenderTarget();
+	void applyState(GLenum drawMode);
+	GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);
+	GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+	void applyTextures();
+	void applyTexture(int sampler, Texture *texture);
+
+	void detachBuffer(GLuint buffer);
+	void detachTexture(GLuint texture);
+	void detachFramebuffer(GLuint framebuffer);
+	void detachRenderbuffer(GLuint renderbuffer);
+
+	bool cullSkipsDraw(GLenum drawMode);
+	bool isTriangleMode(GLenum drawMode);
+
+	State mState;
+
+	gl::BindingPointer<Texture2D> mTexture2DZero;
+	gl::BindingPointer<TextureExternal> mTextureExternalZero;
+
+	gl::NameSpace<Framebuffer> mFramebufferNameSpace;
+
+	VertexDataManager *mVertexDataManager;
+	IndexDataManager *mIndexDataManager;
+
+	bool lightingEnabled;
+	Light light[MAX_LIGHTS];
+	Color globalAmbient;
+	Color materialAmbient;
+	Color materialDiffuse;
+	Color materialSpecular;
+	Color materialEmission;
+	GLfloat materialShininess;
+	bool lightModelTwoSide;
+
+	// Recorded errors
+	bool mInvalidEnum;
+	bool mInvalidValue;
+	bool mInvalidOperation;
+	bool mOutOfMemory;
+	bool mInvalidFramebufferOperation;
+	bool mMatrixStackOverflow;
+	bool mMatrixStackUnderflow;
+
+	bool mHasBeenCurrent;
+
+	// state caching flags
+	bool mDepthStateDirty;
+	bool mMaskStateDirty;
+	bool mBlendStateDirty;
+	bool mStencilStateDirty;
+	bool mPolygonOffsetStateDirty;
+	bool mSampleStateDirty;
+	bool mFrontFaceDirty;
+	bool mDitherStateDirty;
+
+	sw::MatrixStack &currentMatrixStack();
+	GLenum matrixMode;
+	sw::MatrixStack modelViewStack;
+	sw::MatrixStack projectionStack;
+	sw::MatrixStack textureStack0;
+	sw::MatrixStack textureStack1;
+
+	bool texture2Denabled[MAX_TEXTURE_UNITS];
+	bool textureExternalEnabled[MAX_TEXTURE_UNITS];
+	GLenum clientTexture;
+
+	int clipFlags;
+
+	bool alphaTestEnabled;
+	GLenum alphaTestFunc;
+	float alphaTestRef;
+
+	bool fogEnabled;
+	GLenum fogMode;
+	float fogDensity;
+	float fogStart;
+	float fogEnd;
+	Color fogColor;
+
+	bool lineSmoothEnabled;
+	bool colorMaterialEnabled;
+	bool normalizeEnabled;
+	bool rescaleNormalEnabled;
+	bool multisampleEnabled;
+	bool sampleAlphaToOneEnabled;
+
+	bool pointSpriteEnabled;
+	bool pointSmoothEnabled;
+	float pointSizeMin;
+	float pointSizeMax;
+	Attenuation pointDistanceAttenuation;
+	float pointFadeThresholdSize;
+
+	bool colorLogicOpEnabled;
+	GLenum logicalOperation;
+
+	Device *device;
+	ResourceManager *mResourceManager;
+};
+}
+
+#endif   // INCLUDE_CONTEXT_H_
diff --git a/src/OpenGL/libGLES_CM/Device.cpp b/src/OpenGL/libGLES_CM/Device.cpp
index 65f29fc..7a7f022 100644
--- a/src/OpenGL/libGLES_CM/Device.cpp
+++ b/src/OpenGL/libGLES_CM/Device.cpp
@@ -1,608 +1,611 @@
-// 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.

-//

-

-#include "Device.hpp"

-

-#include "common/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"

-

-namespace es1

-{

-	using namespace sw;

-

-	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)

-	{

-		renderTarget = nullptr;

-		depthBuffer = nullptr;

-		stencilBuffer = nullptr;

-

-		setDepthBufferEnable(true);

-		setFillMode(FILL_SOLID);

-		setShadingMode(SHADING_GOURAUD);

-		setDepthWriteEnable(true);

-		setAlphaTestEnable(false);

-		setSourceBlendFactor(BLEND_ONE);

-		setDestBlendFactor(BLEND_ZERO);

-		setCullMode(CULL_COUNTERCLOCKWISE);

-		setDepthCompare(DEPTH_LESSEQUAL);

-		setAlphaReference(0.0f);

-		setAlphaCompare(ALPHA_ALWAYS);

-		setAlphaBlendEnable(false);

-		setFogEnable(false);

-		setSpecularEnable(true);

-		setLocalViewer(false);

-		setFogColor(0);

-		setPixelFogMode(FOG_NONE);

-		setFogStart(0.0f);

-		setFogEnd(1.0f);

-		setFogDensity(1.0f);

-		setRangeFogEnable(false);

-		setStencilEnable(false);

-		setStencilFailOperation(OPERATION_KEEP);

-		setStencilZFailOperation(OPERATION_KEEP);

-		setStencilPassOperation(OPERATION_KEEP);

-		setStencilCompare(STENCIL_ALWAYS);

-		setStencilReference(0);

-		setStencilMask(0xFFFFFFFF);

-		setStencilWriteMask(0xFFFFFFFF);

-		setVertexFogMode(FOG_NONE);

-		setClipFlags(0);

-		setPointSize(1.0f);

-		setPointSizeMin(0.125f);

-        setPointSizeMax(8192.0f);

-		setColorWriteMask(0, 0x0000000F);

-		setBlendOperation(BLENDOP_ADD);

-		scissorEnable = false;

-		setSlopeDepthBias(0.0f);

-		setTwoSidedStencil(false);

-		setStencilFailOperationCCW(OPERATION_KEEP);

-		setStencilZFailOperationCCW(OPERATION_KEEP);

-		setStencilPassOperationCCW(OPERATION_KEEP);

-		setStencilCompareCCW(STENCIL_ALWAYS);

-		setColorWriteMask(1, 0x0000000F);

-		setColorWriteMask(2, 0x0000000F);

-		setColorWriteMask(3, 0x0000000F);

-		setBlendConstant(0xFFFFFFFF);

-		setWriteSRGB(false);

-		setDepthBias(0.0f);

-		setSeparateAlphaBlendEnable(false);

-		setSourceBlendFactorAlpha(BLEND_ONE);

-		setDestBlendFactorAlpha(BLEND_ZERO);

-		setBlendOperationAlpha(BLENDOP_ADD);

-		setPointSpriteEnable(true);

-

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

-		}

-	}

-

-	Device::~Device()

-	{

-		if(renderTarget)

-		{

-			renderTarget->release();

-			renderTarget = nullptr;

-		}

-

-		if(depthBuffer)

-		{

-			depthBuffer->release();

-			depthBuffer = nullptr;

-		}

-

-		if(stencilBuffer)

-		{

-			stencilBuffer->release();

-			stencilBuffer = nullptr;

-		}

-

-		delete context;

-	}

-

-	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)

-	{

-		if(!renderTarget || !rgbaMask)

-		{

-			return;

-		}

-

-		float rgba[4];

-		rgba[0] = red;

-		rgba[1] = green;

-		rgba[2] = blue;

-		rgba[3] = alpha;

-

-		sw::SliceRect clearRect = renderTarget->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);

-	}

-

-	void Device::clearDepth(float z)

-	{

-		if(!depthBuffer)

-		{

-			return;

-		}

-

-		z = clamp01(z);

-		sw::SliceRect clearRect = depthBuffer->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	void Device::clearStencil(unsigned int stencil, unsigned int mask)

-	{

-		if(!stencilBuffer)

-		{

-			return;

-		}

-

-		sw::SliceRect clearRect = stencilBuffer->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return nullptr;

-		}

-

-		bool lockable = true;

-

-		switch(format)

-		{

-	//	case FORMAT_D15S1:

-		case FORMAT_D24S8:

-		case FORMAT_D24X8:

-	//	case FORMAT_D24X4S4:

-		case FORMAT_D24FS8:

-		case FORMAT_D32:

-		case FORMAT_D16:

-			lockable = false;

-			break;

-	//	case FORMAT_S8_LOCKABLE:

-	//	case FORMAT_D16_LOCKABLE:

-		case FORMAT_D32F_LOCKABLE:

-	//	case FORMAT_D32_LOCKABLE:

-		case FORMAT_DF24S8:

-		case FORMAT_DF16S8:

-			lockable = true;

-			break;

-		default:

-			UNREACHABLE(format);

-		}

-

-		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return nullptr;

-		}

-

-		return surface;

-	}

-

-	egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return nullptr;

-		}

-

-		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return nullptr;

-		}

-

-		return surface;

-	}

-

-	void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		draw(type, indexOffset, primitiveCount);

-	}

-

-	void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		setIndexBuffer(nullptr);

-

-		draw(type, 0, primitiveCount);

-	}

-

-	void Device::setScissorEnable(bool enable)

-	{

-		scissorEnable = enable;

-	}

-

-	void Device::setRenderTarget(int index, egl::Image *renderTarget)

-	{

-		if(renderTarget)

-		{

-			renderTarget->addRef();

-		}

-

-		if(this->renderTarget)

-		{

-			this->renderTarget->release();

-		}

-

-		this->renderTarget = renderTarget;

-

-		Renderer::setRenderTarget(index, renderTarget);

-	}

-

-	void Device::setDepthBuffer(egl::Image *depthBuffer)

-	{

-		if(this->depthBuffer == depthBuffer)

-		{

-			return;

-		}

-

-		if(depthBuffer)

-		{

-			depthBuffer->addRef();

-		}

-

-		if(this->depthBuffer)

-		{

-			this->depthBuffer->release();

-		}

-

-		this->depthBuffer = depthBuffer;

-

-		Renderer::setDepthBuffer(depthBuffer);

-	}

-

-	void Device::setStencilBuffer(egl::Image *stencilBuffer)

-	{

-		if(this->stencilBuffer == stencilBuffer)

-		{

-			return;

-		}

-

-		if(stencilBuffer)

-		{

-			stencilBuffer->addRef();

-		}

-

-		if(this->stencilBuffer)

-		{

-			this->stencilBuffer->release();

-		}

-

-		this->stencilBuffer = stencilBuffer;

-

-		Renderer::setStencilBuffer(stencilBuffer);

-	}

-

-	void Device::setScissorRect(const sw::Rect &rect)

-	{

-		scissorRect = rect;

-	}

-

-	void Device::setViewport(const Viewport &viewport)

-	{

-		this->viewport = viewport;

-	}

-

-	bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter)

-	{

-		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))

-		{

-			ERR("Invalid parameters");

-			return false;

-		}

-

-		int sWidth = source->getWidth();

-		int sHeight = source->getHeight();

-		int dWidth = dest->getWidth();

-		int dHeight = dest->getHeight();

-

-		SliceRect sRect;

-		SliceRect dRect;

-

-		if(sourceRect)

-		{

-			sRect = *sourceRect;

-		}

-		else

-		{

-			sRect.y0 = 0;

-			sRect.x0 = 0;

-			sRect.y1 = sHeight;

-			sRect.x1 = sWidth;

-		}

-

-		if(destRect)

-		{

-			dRect = *destRect;

-		}

-		else

-		{

-			dRect.y0 = 0;

-			dRect.x0 = 0;

-			dRect.y1 = dHeight;

-			dRect.x1 = dWidth;

-		}

-

-		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);

-		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();

-		bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat());

-		bool alpha0xFF = false;

-

-		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||

-		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))

-		{

-			equalFormats = true;

-			alpha0xFF = true;

-		}

-

-		if(depthStencil)   // Copy entirely, internally   // FIXME: Check

-		{

-			if(source->hasDepth())

-			{

-				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);

-				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getInternalPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockInternal();

-				dest->unlockInternal();

-			}

-

-			if(source->hasStencil())

-			{

-				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC);

-				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getStencilPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockStencil();

-				dest->unlockStencil();

-			}

-		}

-		else if(!scaling && equalFormats)

-		{

-			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);

-			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);

-			unsigned int sourcePitch = source->getInternalPitchB();

-			unsigned int destPitch = dest->getInternalPitchB();

-

-			unsigned int width = dRect.x1 - dRect.x0;

-			unsigned int height = dRect.y1 - dRect.y0;

-			unsigned int bytes = width * egl::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::bindResources()

-	{

-		if(!bindViewport())

-		{

-			return false;   // Zero-area target region

-		}

-

-		return true;

-	}

-

-	bool Device::bindViewport()

-	{

-		if(viewport.width <= 0 || viewport.height <= 0)

-		{

-			return false;

-		}

-

-		if(scissorEnable)

-		{

-			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)

-			{

-				return false;

-			}

-

-			sw::Rect scissor;

-			scissor.x0 = scissorRect.x0;

-			scissor.x1 = scissorRect.x1;

-			scissor.y0 = scissorRect.y0;

-			scissor.y1 = scissorRect.y1;

-

-			setScissor(scissor);

-		}

-		else

-		{

-			sw::Rect scissor;

-			scissor.x0 = viewport.x0;

-			scissor.x1 = viewport.x0 + viewport.width;

-			scissor.y0 = viewport.y0;

-			scissor.y1 = viewport.y0 + viewport.height;

-

-			if(renderTarget)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, renderTarget->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, renderTarget->getHeight());

-			}

-

-			if(depthBuffer)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, depthBuffer->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, depthBuffer->getHeight());

-			}

-

-			if(stencilBuffer)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, stencilBuffer->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, stencilBuffer->getHeight());

-			}

-

-			setScissor(scissor);

-		}

-

-		sw::Viewport view;

-		view.x0 = (float)viewport.x0;

-		view.y0 = (float)viewport.y0;

-		view.width = (float)viewport.width;

-		view.height = (float)viewport.height;

-		view.minZ = viewport.minZ;

-		view.maxZ = viewport.maxZ;

-

-		Renderer::setViewport(view);

-

-		return true;

-	}

-

-	bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface)

-	{

-		if(!rect)

-		{

-			return true;

-		}

-

-		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)

-		{

-			return false;

-		}

-

-		if(rect->x0 < 0 || rect->y0 < 0)

-		{

-			return false;

-		}

-

-		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	void Device::finish()

-	{

-		synchronize();

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Device.hpp"
+
+#include "common/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"
+
+namespace es1
+{
+	using namespace sw;
+
+	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)
+	{
+		renderTarget = nullptr;
+		depthBuffer = nullptr;
+		stencilBuffer = nullptr;
+
+		setDepthBufferEnable(true);
+		setFillMode(FILL_SOLID);
+		setShadingMode(SHADING_GOURAUD);
+		setDepthWriteEnable(true);
+		setAlphaTestEnable(false);
+		setSourceBlendFactor(BLEND_ONE);
+		setDestBlendFactor(BLEND_ZERO);
+		setCullMode(CULL_COUNTERCLOCKWISE);
+		setDepthCompare(DEPTH_LESSEQUAL);
+		setAlphaReference(0.0f);
+		setAlphaCompare(ALPHA_ALWAYS);
+		setAlphaBlendEnable(false);
+		setFogEnable(false);
+		setSpecularEnable(true);
+		setLocalViewer(false);
+		setFogColor(0);
+		setPixelFogMode(FOG_NONE);
+		setFogStart(0.0f);
+		setFogEnd(1.0f);
+		setFogDensity(1.0f);
+		setRangeFogEnable(false);
+		setStencilEnable(false);
+		setStencilFailOperation(OPERATION_KEEP);
+		setStencilZFailOperation(OPERATION_KEEP);
+		setStencilPassOperation(OPERATION_KEEP);
+		setStencilCompare(STENCIL_ALWAYS);
+		setStencilReference(0);
+		setStencilMask(0xFFFFFFFF);
+		setStencilWriteMask(0xFFFFFFFF);
+		setVertexFogMode(FOG_NONE);
+		setClipFlags(0);
+		setPointSize(1.0f);
+		setPointSizeMin(0.125f);
+        setPointSizeMax(8192.0f);
+		setColorWriteMask(0, 0x0000000F);
+		setBlendOperation(BLENDOP_ADD);
+		scissorEnable = false;
+		setSlopeDepthBias(0.0f);
+		setTwoSidedStencil(false);
+		setStencilFailOperationCCW(OPERATION_KEEP);
+		setStencilZFailOperationCCW(OPERATION_KEEP);
+		setStencilPassOperationCCW(OPERATION_KEEP);
+		setStencilCompareCCW(STENCIL_ALWAYS);
+		setColorWriteMask(1, 0x0000000F);
+		setColorWriteMask(2, 0x0000000F);
+		setColorWriteMask(3, 0x0000000F);
+		setBlendConstant(0xFFFFFFFF);
+		setWriteSRGB(false);
+		setDepthBias(0.0f);
+		setSeparateAlphaBlendEnable(false);
+		setSourceBlendFactorAlpha(BLEND_ONE);
+		setDestBlendFactorAlpha(BLEND_ZERO);
+		setBlendOperationAlpha(BLENDOP_ADD);
+		setPointSpriteEnable(true);
+
+		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);
+		}
+	}
+
+	Device::~Device()
+	{
+		if(renderTarget)
+		{
+			renderTarget->release();
+			renderTarget = nullptr;
+		}
+
+		if(depthBuffer)
+		{
+			depthBuffer->release();
+			depthBuffer = nullptr;
+		}
+
+		if(stencilBuffer)
+		{
+			stencilBuffer->release();
+			stencilBuffer = nullptr;
+		}
+
+		delete context;
+	}
+
+	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
+	{
+		if(!renderTarget || !rgbaMask)
+		{
+			return;
+		}
+
+		float rgba[4];
+		rgba[0] = red;
+		rgba[1] = green;
+		rgba[2] = blue;
+		rgba[3] = alpha;
+
+		sw::SliceRect clearRect = renderTarget->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);
+	}
+
+	void Device::clearDepth(float z)
+	{
+		if(!depthBuffer)
+		{
+			return;
+		}
+
+		z = clamp01(z);
+		sw::SliceRect clearRect = depthBuffer->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	void Device::clearStencil(unsigned int stencil, unsigned int mask)
+	{
+		if(!stencilBuffer)
+		{
+			return;
+		}
+
+		sw::SliceRect clearRect = stencilBuffer->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return nullptr;
+		}
+
+		bool lockable = true;
+
+		switch(format)
+		{
+	//	case FORMAT_D15S1:
+		case FORMAT_D24S8:
+		case FORMAT_D24X8:
+	//	case FORMAT_D24X4S4:
+		case FORMAT_D24FS8:
+		case FORMAT_D32:
+		case FORMAT_D16:
+			lockable = false;
+			break;
+	//	case FORMAT_S8_LOCKABLE:
+	//	case FORMAT_D16_LOCKABLE:
+		case FORMAT_D32F_LOCKABLE:
+	//	case FORMAT_D32_LOCKABLE:
+		case FORMAT_DF24S8:
+		case FORMAT_DF16S8:
+			lockable = true;
+			break;
+		default:
+			UNREACHABLE(format);
+		}
+
+		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return nullptr;
+		}
+
+		return surface;
+	}
+
+	egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return nullptr;
+		}
+
+		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return nullptr;
+		}
+
+		return surface;
+	}
+
+	void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		draw(type, indexOffset, primitiveCount);
+	}
+
+	void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		setIndexBuffer(nullptr);
+
+		draw(type, 0, primitiveCount);
+	}
+
+	void Device::setScissorEnable(bool enable)
+	{
+		scissorEnable = enable;
+	}
+
+	void Device::setRenderTarget(int index, egl::Image *renderTarget)
+	{
+		if(renderTarget)
+		{
+			renderTarget->addRef();
+		}
+
+		if(this->renderTarget)
+		{
+			this->renderTarget->release();
+		}
+
+		this->renderTarget = renderTarget;
+
+		Renderer::setRenderTarget(index, renderTarget);
+	}
+
+	void Device::setDepthBuffer(egl::Image *depthBuffer)
+	{
+		if(this->depthBuffer == depthBuffer)
+		{
+			return;
+		}
+
+		if(depthBuffer)
+		{
+			depthBuffer->addRef();
+		}
+
+		if(this->depthBuffer)
+		{
+			this->depthBuffer->release();
+		}
+
+		this->depthBuffer = depthBuffer;
+
+		Renderer::setDepthBuffer(depthBuffer);
+	}
+
+	void Device::setStencilBuffer(egl::Image *stencilBuffer)
+	{
+		if(this->stencilBuffer == stencilBuffer)
+		{
+			return;
+		}
+
+		if(stencilBuffer)
+		{
+			stencilBuffer->addRef();
+		}
+
+		if(this->stencilBuffer)
+		{
+			this->stencilBuffer->release();
+		}
+
+		this->stencilBuffer = stencilBuffer;
+
+		Renderer::setStencilBuffer(stencilBuffer);
+	}
+
+	void Device::setScissorRect(const sw::Rect &rect)
+	{
+		scissorRect = rect;
+	}
+
+	void Device::setViewport(const Viewport &viewport)
+	{
+		this->viewport = viewport;
+	}
+
+	bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter)
+	{
+		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		int sWidth = source->getWidth();
+		int sHeight = source->getHeight();
+		int dWidth = dest->getWidth();
+		int dHeight = dest->getHeight();
+
+		SliceRect sRect;
+		SliceRect dRect;
+
+		if(sourceRect)
+		{
+			sRect = *sourceRect;
+		}
+		else
+		{
+			sRect.y0 = 0;
+			sRect.x0 = 0;
+			sRect.y1 = sHeight;
+			sRect.x1 = sWidth;
+		}
+
+		if(destRect)
+		{
+			dRect = *destRect;
+		}
+		else
+		{
+			dRect.y0 = 0;
+			dRect.x0 = 0;
+			dRect.y1 = dHeight;
+			dRect.x1 = dWidth;
+		}
+
+		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
+		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
+		bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat());
+		bool alpha0xFF = false;
+
+		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||
+		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))
+		{
+			equalFormats = true;
+			alpha0xFF = true;
+		}
+
+		if(depthStencil)   // Copy entirely, internally   // FIXME: Check
+		{
+			if(source->hasDepth())
+			{
+				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getInternalPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockInternal();
+				dest->unlockInternal();
+			}
+
+			if(source->hasStencil())
+			{
+				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getStencilPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockStencil();
+				dest->unlockStencil();
+			}
+		}
+		else if(!scaling && equalFormats)
+		{
+			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);
+			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);
+			unsigned int sourcePitch = source->getInternalPitchB();
+			unsigned int destPitch = dest->getInternalPitchB();
+
+			unsigned int width = dRect.x1 - dRect.x0;
+			unsigned int height = dRect.y1 - dRect.y0;
+			unsigned int bytes = width * egl::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::bindResources()
+	{
+		if(!bindViewport())
+		{
+			return false;   // Zero-area target region
+		}
+
+		return true;
+	}
+
+	bool Device::bindViewport()
+	{
+		if(viewport.width <= 0 || viewport.height <= 0)
+		{
+			return false;
+		}
+
+		if(scissorEnable)
+		{
+			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)
+			{
+				return false;
+			}
+
+			sw::Rect scissor;
+			scissor.x0 = scissorRect.x0;
+			scissor.x1 = scissorRect.x1;
+			scissor.y0 = scissorRect.y0;
+			scissor.y1 = scissorRect.y1;
+
+			setScissor(scissor);
+		}
+		else
+		{
+			sw::Rect scissor;
+			scissor.x0 = viewport.x0;
+			scissor.x1 = viewport.x0 + viewport.width;
+			scissor.y0 = viewport.y0;
+			scissor.y1 = viewport.y0 + viewport.height;
+
+			if(renderTarget)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, renderTarget->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, renderTarget->getHeight());
+			}
+
+			if(depthBuffer)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, depthBuffer->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, depthBuffer->getHeight());
+			}
+
+			if(stencilBuffer)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, stencilBuffer->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, stencilBuffer->getHeight());
+			}
+
+			setScissor(scissor);
+		}
+
+		sw::Viewport view;
+		view.x0 = (float)viewport.x0;
+		view.y0 = (float)viewport.y0;
+		view.width = (float)viewport.width;
+		view.height = (float)viewport.height;
+		view.minZ = viewport.minZ;
+		view.maxZ = viewport.maxZ;
+
+		Renderer::setViewport(view);
+
+		return true;
+	}
+
+	bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface)
+	{
+		if(!rect)
+		{
+			return true;
+		}
+
+		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)
+		{
+			return false;
+		}
+
+		if(rect->x0 < 0 || rect->y0 < 0)
+		{
+			return false;
+		}
+
+		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	void Device::finish()
+	{
+		synchronize();
+	}
+}
diff --git a/src/OpenGL/libGLES_CM/Device.hpp b/src/OpenGL/libGLES_CM/Device.hpp
index 15872ca..8b6ea46 100644
--- a/src/OpenGL/libGLES_CM/Device.hpp
+++ b/src/OpenGL/libGLES_CM/Device.hpp
@@ -1,78 +1,81 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef gl_Device_hpp

-#define gl_Device_hpp

-

-#include "Renderer/Renderer.hpp"

-

-namespace egl

-{

-	class Image;

-}

-

-namespace es1

-{

-	class Texture;

-

-	struct Viewport

-	{

-		int x0;

-		int y0;

-		unsigned int width;

-		unsigned int height;

-		float minZ;

-		float maxZ;

-	};

-

-	class Device : public sw::Renderer

-	{

-	public:

-		explicit Device(sw::Context *context);

-

-		virtual ~Device();

-

-		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);

-		virtual void clearDepth(float z);

-		virtual void clearStencil(unsigned int stencil, unsigned int mask);

-		virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-		virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);

-		virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);

-		virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount);

-		virtual void setScissorEnable(bool enable);

-		virtual void setRenderTarget(int index, egl::Image *renderTarget);

-		virtual void setDepthBuffer(egl::Image *depthBuffer);

-		virtual void setStencilBuffer(egl::Image *stencilBuffer);

-		virtual void setScissorRect(const sw::Rect &rect);

-		virtual void setViewport(const Viewport &viewport);

-

-		virtual bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRect *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, bool filter);

-		virtual void finish();

-

-	private:

-		sw::Context *const context;

-

-		bool bindResources();

-		bool bindViewport();   // Also adjusts for scissoring

-

-		bool validRectangle(const sw::Rect *rect, sw::Surface *surface);

-

-		Viewport viewport;

-		sw::Rect scissorRect;

-		bool scissorEnable;

-

-		egl::Image *renderTarget;

-		egl::Image *depthBuffer;

-		egl::Image *stencilBuffer;

-	};

-}

-

-#endif   // gl_Device_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef gl_Device_hpp
+#define gl_Device_hpp
+
+#include "Renderer/Renderer.hpp"
+
+namespace egl
+{
+	class Image;
+}
+
+namespace es1
+{
+	class Texture;
+
+	struct Viewport
+	{
+		int x0;
+		int y0;
+		unsigned int width;
+		unsigned int height;
+		float minZ;
+		float maxZ;
+	};
+
+	class Device : public sw::Renderer
+	{
+	public:
+		explicit Device(sw::Context *context);
+
+		virtual ~Device();
+
+		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
+		virtual void clearDepth(float z);
+		virtual void clearStencil(unsigned int stencil, unsigned int mask);
+		virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+		virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);
+		virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);
+		virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount);
+		virtual void setScissorEnable(bool enable);
+		virtual void setRenderTarget(int index, egl::Image *renderTarget);
+		virtual void setDepthBuffer(egl::Image *depthBuffer);
+		virtual void setStencilBuffer(egl::Image *stencilBuffer);
+		virtual void setScissorRect(const sw::Rect &rect);
+		virtual void setViewport(const Viewport &viewport);
+
+		virtual bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRect *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, bool filter);
+		virtual void finish();
+
+	private:
+		sw::Context *const context;
+
+		bool bindResources();
+		bool bindViewport();   // Also adjusts for scissoring
+
+		bool validRectangle(const sw::Rect *rect, sw::Surface *surface);
+
+		Viewport viewport;
+		sw::Rect scissorRect;
+		bool scissorEnable;
+
+		egl::Image *renderTarget;
+		egl::Image *depthBuffer;
+		egl::Image *stencilBuffer;
+	};
+}
+
+#endif   // gl_Device_hpp
diff --git a/src/OpenGL/libGLES_CM/Framebuffer.cpp b/src/OpenGL/libGLES_CM/Framebuffer.cpp
index 25db3d6..5dfa67c 100644
--- a/src/OpenGL/libGLES_CM/Framebuffer.cpp
+++ b/src/OpenGL/libGLES_CM/Framebuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
diff --git a/src/OpenGL/libGLES_CM/Framebuffer.h b/src/OpenGL/libGLES_CM/Framebuffer.h
index fa9a684..39f227c 100644
--- a/src/OpenGL/libGLES_CM/Framebuffer.h
+++ b/src/OpenGL/libGLES_CM/Framebuffer.h
@@ -1,91 +1,94 @@
-// 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.

-//

-

-// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer

-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.

-

-#ifndef LIBGLES_CM_FRAMEBUFFER_H_

-#define LIBGLES_CM_FRAMEBUFFER_H_

-

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-class Renderbuffer;

-class Colorbuffer;

-class Depthbuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-

-class Framebuffer

-{

-public:

-    Framebuffer();

-

-    virtual ~Framebuffer();

-

-    void setColorbuffer(GLenum type, GLuint colorbuffer);

-    void setDepthbuffer(GLenum type, GLuint depthbuffer);

-    void setStencilbuffer(GLenum type, GLuint stencilbuffer);

-

-    void detachTexture(GLuint texture);

-    void detachRenderbuffer(GLuint renderbuffer);

-

-    egl::Image *getRenderTarget();

-    egl::Image *getDepthBuffer();

-	egl::Image *getStencilBuffer();

-

-    Renderbuffer *getColorbuffer();

-    Renderbuffer *getDepthbuffer();

-    Renderbuffer *getStencilbuffer();

-

-    GLenum getColorbufferType();

-    GLenum getDepthbufferType();

-    GLenum getStencilbufferType();

-

-    GLuint getColorbufferName();

-    GLuint getDepthbufferName();

-    GLuint getStencilbufferName();

-

-    bool hasStencil();

-

-	virtual GLenum completeness();

-	GLenum completeness(int &width, int &height, int &samples);

-

-	GLenum getImplementationColorReadFormat();

-	GLenum getImplementationColorReadType();

-

-protected:

-    GLenum mColorbufferType;

-    gl::BindingPointer<Renderbuffer> mColorbufferPointer;

-

-    GLenum mDepthbufferType;

-    gl::BindingPointer<Renderbuffer> mDepthbufferPointer;

-

-    GLenum mStencilbufferType;

-    gl::BindingPointer<Renderbuffer> mStencilbufferPointer;

-

-private:

-    Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;

-};

-

-class DefaultFramebuffer : public Framebuffer

-{

-public:

-    DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);

-};

-

-}

-

-#endif   // LIBGLES_CM_FRAMEBUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
+
+#ifndef LIBGLES_CM_FRAMEBUFFER_H_
+#define LIBGLES_CM_FRAMEBUFFER_H_
+
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+class Renderbuffer;
+class Colorbuffer;
+class Depthbuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+
+class Framebuffer
+{
+public:
+	Framebuffer();
+
+	virtual ~Framebuffer();
+
+	void setColorbuffer(GLenum type, GLuint colorbuffer);
+	void setDepthbuffer(GLenum type, GLuint depthbuffer);
+	void setStencilbuffer(GLenum type, GLuint stencilbuffer);
+
+	void detachTexture(GLuint texture);
+	void detachRenderbuffer(GLuint renderbuffer);
+
+	egl::Image *getRenderTarget();
+	egl::Image *getDepthBuffer();
+	egl::Image *getStencilBuffer();
+
+	Renderbuffer *getColorbuffer();
+	Renderbuffer *getDepthbuffer();
+	Renderbuffer *getStencilbuffer();
+
+	GLenum getColorbufferType();
+	GLenum getDepthbufferType();
+	GLenum getStencilbufferType();
+
+	GLuint getColorbufferName();
+	GLuint getDepthbufferName();
+	GLuint getStencilbufferName();
+
+	bool hasStencil();
+
+	virtual GLenum completeness();
+	GLenum completeness(int &width, int &height, int &samples);
+
+	GLenum getImplementationColorReadFormat();
+	GLenum getImplementationColorReadType();
+
+protected:
+	GLenum mColorbufferType;
+	gl::BindingPointer<Renderbuffer> mColorbufferPointer;
+
+	GLenum mDepthbufferType;
+	gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
+
+	GLenum mStencilbufferType;
+	gl::BindingPointer<Renderbuffer> mStencilbufferPointer;
+
+private:
+	Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
+};
+
+class DefaultFramebuffer : public Framebuffer
+{
+public:
+	DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+};
+
+}
+
+#endif   // LIBGLES_CM_FRAMEBUFFER_H_
diff --git a/src/OpenGL/libGLES_CM/IndexDataManager.cpp b/src/OpenGL/libGLES_CM/IndexDataManager.cpp
index 3e31314..874e17a 100644
--- a/src/OpenGL/libGLES_CM/IndexDataManager.cpp
+++ b/src/OpenGL/libGLES_CM/IndexDataManager.cpp
@@ -1,241 +1,244 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// IndexDataManager.cpp: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#include "IndexDataManager.h"

-

-#include "Buffer.h"

-#include "common/debug.h"

-

-#include <string.h>

-#include <algorithm>

-

-namespace

-{

-    enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };

-}

-

-namespace es1

-{

-

-IndexDataManager::IndexDataManager()

-{

-    mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming index buffer.");

-    }

-}

-

-IndexDataManager::~IndexDataManager()

-{

-    delete mStreamingBuffer;

-}

-

-void copyIndices(GLenum type, const void *input, GLsizei count, void *output)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        memcpy(output, input, count * sizeof(GLubyte));

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        memcpy(output, input, count * sizeof(GLushort));

-    }

-    else UNREACHABLE(type);

-}

-

-template<class IndexType>

-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    *minIndex = indices[0];

-    *maxIndex = indices[0];

-

-    for(GLsizei i = 0; i < count; i++)

-    {

-        if(*minIndex > indices[i]) *minIndex = indices[i];

-        if(*maxIndex < indices[i]) *maxIndex = indices[i];

-    }

-}

-

-void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);

-    }

-    else UNREACHABLE(type);

-}

-

-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-    intptr_t offset = reinterpret_cast<intptr_t>(indices);

-

-    if(buffer != NULL)

-    {

-        if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))

-        {

-            return GL_INVALID_OPERATION;

-        }

-

-        indices = static_cast<const GLubyte*>(buffer->data()) + offset;

-    }

-

-    StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;

-

-	sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-    if(staticBuffer)

-    {

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = staticBuffer;

-		translated->indexOffset = offset;

-    }

-    else

-    {

-		unsigned int streamOffset = 0;

-        int convertCount = count;

-

-        streamingBuffer->reserveSpace(convertCount * typeSize(type), type);

-        void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);

-        

-        if(output == NULL)

-        {

-            ERR("Failed to map index buffer.");

-            return GL_OUT_OF_MEMORY;

-        }

-

-        copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);

-        streamingBuffer->unmap();

-

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = streamingBuffer->getResource();

-		translated->indexOffset = streamOffset;

-    }

-

-    return GL_NO_ERROR;

-}

-

-std::size_t IndexDataManager::typeSize(GLenum type)

-{

-    switch(type)

-    {

-    case GL_UNSIGNED_SHORT: return sizeof(GLushort);

-    case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);

-    default: UNREACHABLE(type); return sizeof(GLushort);

-    }

-}

-

-StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(nullptr), mBufferSize(initialSize)

-{

-	if(initialSize > 0)

-    {

-		mIndexBuffer = new sw::Resource(initialSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", initialSize);

-        }

-    }

-

-    mWritePosition = 0;

-}

-

-StreamingIndexBuffer::~StreamingIndexBuffer()

-{

-	if(mIndexBuffer)

-    {

-        mIndexBuffer->destruct();

-    }

-}

-

-void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mIndexBuffer)

-    {

-        mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;

-     

-        if(!mapPtr)

-        {

-            ERR(" Lock failed");

-            return NULL;

-        }

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingIndexBuffer::unmap()

-{

-    if(mIndexBuffer)

-    {

-        mIndexBuffer->unlock();

-    }

-}

-

-void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)

-{

-    if(requiredSpace > mBufferSize)

-    {

-        if(mIndexBuffer)

-        {

-            mIndexBuffer->destruct();

-            mIndexBuffer = 0;

-        }

-

-        mBufferSize = std::max(requiredSpace, 2 * mBufferSize);

-

-		mIndexBuffer = new sw::Resource(mBufferSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle

-    {

-		if(mIndexBuffer)

-		{

-			mIndexBuffer->destruct();

-			mIndexBuffer = new sw::Resource(mBufferSize + 16);

-		}

-

-        mWritePosition = 0;

-    }

-}

-

-sw::Resource *StreamingIndexBuffer::getResource() const

-{

-    return mIndexBuffer;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// IndexDataManager.cpp: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#include "IndexDataManager.h"
+
+#include "Buffer.h"
+#include "common/debug.h"
+
+#include <string.h>
+#include <algorithm>
+
+namespace
+{
+	enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
+}
+
+namespace es1
+{
+
+IndexDataManager::IndexDataManager()
+{
+	mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming index buffer.");
+	}
+}
+
+IndexDataManager::~IndexDataManager()
+{
+	delete mStreamingBuffer;
+}
+
+void copyIndices(GLenum type, const void *input, GLsizei count, void *output)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		memcpy(output, input, count * sizeof(GLubyte));
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		memcpy(output, input, count * sizeof(GLushort));
+	}
+	else UNREACHABLE(type);
+}
+
+template<class IndexType>
+void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	*minIndex = indices[0];
+	*maxIndex = indices[0];
+
+	for(GLsizei i = 0; i < count; i++)
+	{
+		if(*minIndex > indices[i]) *minIndex = indices[i];
+		if(*maxIndex < indices[i]) *maxIndex = indices[i];
+	}
+}
+
+void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
+	}
+	else UNREACHABLE(type);
+}
+
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	intptr_t offset = reinterpret_cast<intptr_t>(indices);
+
+	if(buffer != NULL)
+	{
+		if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		indices = static_cast<const GLubyte*>(buffer->data()) + offset;
+	}
+
+	StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;
+
+	sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;
+
+	if(staticBuffer)
+	{
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = staticBuffer;
+		translated->indexOffset = offset;
+	}
+	else
+	{
+		unsigned int streamOffset = 0;
+		int convertCount = count;
+
+		streamingBuffer->reserveSpace(convertCount * typeSize(type), type);
+		void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);
+
+		if(output == NULL)
+		{
+			ERR("Failed to map index buffer.");
+			return GL_OUT_OF_MEMORY;
+		}
+
+		copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
+		streamingBuffer->unmap();
+
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = streamingBuffer->getResource();
+		translated->indexOffset = streamOffset;
+	}
+
+	return GL_NO_ERROR;
+}
+
+std::size_t IndexDataManager::typeSize(GLenum type)
+{
+	switch(type)
+	{
+	case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+	case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);
+	default: UNREACHABLE(type); return sizeof(GLushort);
+	}
+}
+
+StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(nullptr), mBufferSize(initialSize)
+{
+	if(initialSize > 0)
+	{
+		mIndexBuffer = new sw::Resource(initialSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", initialSize);
+		}
+	}
+
+	mWritePosition = 0;
+}
+
+StreamingIndexBuffer::~StreamingIndexBuffer()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->destruct();
+	}
+}
+
+void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = NULL;
+
+	if(mIndexBuffer)
+	{
+		mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;
+
+		if(!mapPtr)
+		{
+			ERR(" Lock failed");
+			return NULL;
+		}
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingIndexBuffer::unmap()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->unlock();
+	}
+}
+
+void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)
+{
+	if(requiredSpace > mBufferSize)
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = 0;
+		}
+
+		mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
+
+		mIndexBuffer = new sw::Resource(mBufferSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = new sw::Resource(mBufferSize + 16);
+		}
+
+		mWritePosition = 0;
+	}
+}
+
+sw::Resource *StreamingIndexBuffer::getResource() const
+{
+	return mIndexBuffer;
+}
+
+}
diff --git a/src/OpenGL/libGLES_CM/IndexDataManager.h b/src/OpenGL/libGLES_CM/IndexDataManager.h
index 9ef6a96..d7e83d6 100644
--- a/src/OpenGL/libGLES_CM/IndexDataManager.h
+++ b/src/OpenGL/libGLES_CM/IndexDataManager.h
@@ -1,68 +1,71 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// IndexDataManager.h: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#ifndef LIBGLES_CM_INDEXDATAMANAGER_H_

-#define LIBGLES_CM_INDEXDATAMANAGER_H_

-

-#include "Context.h"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-

-struct TranslatedIndexData

-{

-    unsigned int minIndex;

-    unsigned int maxIndex;

-    unsigned int indexOffset;

-

-    sw::Resource *indexBuffer;

-};

-

-class StreamingIndexBuffer

-{

-  public:

-    StreamingIndexBuffer(unsigned int initialSize);

-    virtual ~StreamingIndexBuffer();

-

-    void *map(unsigned int requiredSpace, unsigned int *offset);

-	void unmap();

-    void reserveSpace(unsigned int requiredSpace, GLenum type);

-

-	sw::Resource *getResource() const;

-

-  private:

-    sw::Resource *mIndexBuffer;

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-};

-

-class IndexDataManager

-{

-  public:

-    IndexDataManager();

-    virtual ~IndexDataManager();

-

-    GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);

-

-	static std::size_t typeSize(GLenum type);

-

-  private:

-    StreamingIndexBuffer *mStreamingBuffer;

-};

-

-}

-

-#endif   // LIBGLES_CM_INDEXDATAMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// IndexDataManager.h: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#ifndef LIBGLES_CM_INDEXDATAMANAGER_H_
+#define LIBGLES_CM_INDEXDATAMANAGER_H_
+
+#include "Context.h"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+
+struct TranslatedIndexData
+{
+	unsigned int minIndex;
+	unsigned int maxIndex;
+	unsigned int indexOffset;
+
+	sw::Resource *indexBuffer;
+};
+
+class StreamingIndexBuffer
+{
+public:
+	StreamingIndexBuffer(unsigned int initialSize);
+	virtual ~StreamingIndexBuffer();
+
+	void *map(unsigned int requiredSpace, unsigned int *offset);
+	void unmap();
+	void reserveSpace(unsigned int requiredSpace, GLenum type);
+
+	sw::Resource *getResource() const;
+
+private:
+	sw::Resource *mIndexBuffer;
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+};
+
+class IndexDataManager
+{
+public:
+	IndexDataManager();
+	virtual ~IndexDataManager();
+
+	GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
+
+	static std::size_t typeSize(GLenum type);
+
+private:
+	StreamingIndexBuffer *mStreamingBuffer;
+};
+
+}
+
+#endif   // LIBGLES_CM_INDEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGLES_CM/Renderbuffer.cpp b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
index fccb011..96bf733 100644
--- a/src/OpenGL/libGLES_CM/Renderbuffer.cpp
+++ b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
@@ -27,7 +30,7 @@
 
 // The default case for classes inherited from RenderbufferInterface is not to
 // need to do anything upon the reference count to the parent Renderbuffer incrementing
-// or decrementing. 
+// or decrementing.
 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
 {
 }
@@ -75,19 +78,19 @@
 
 RenderbufferTexture2D::~RenderbufferTexture2D()
 {
-	mTexture2D = NULL;
+	mTexture2D = nullptr;
 }
 
 // Textures need to maintain their own reference count for references via
 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
 {
-    mTexture2D->addProxyRef(proxy);
+	mTexture2D->addProxyRef(proxy);
 }
 
 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
 {
-    mTexture2D->releaseProxy(proxy);
+	mTexture2D->releaseProxy(proxy);
 }
 
 // Increments refcount on image.
@@ -101,12 +104,12 @@
 // caller must release() the returned image
 egl::Image *RenderbufferTexture2D::createSharedImage()
 {
-    return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
+	return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
 }
 
 bool RenderbufferTexture2D::isShared() const
 {
-    return mTexture2D->isShared(GL_TEXTURE_2D, 0);
+	return mTexture2D->isShared(GL_TEXTURE_2D, 0);
 }
 
 GLsizei RenderbufferTexture2D::getWidth() const
@@ -138,7 +141,7 @@
 
 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
 {
-	ASSERT(instance != NULL);
+	ASSERT(instance);
 	mInstance = instance;
 }
 
@@ -151,16 +154,16 @@
 // its own reference count, so we pass it on here.
 void Renderbuffer::addRef()
 {
-    mInstance->addProxyRef(this);
+	mInstance->addProxyRef(this);
 
-    Object::addRef();
+	Object::addRef();
 }
 
 void Renderbuffer::release()
 {
-    mInstance->releaseProxy(this);
+	mInstance->releaseProxy(this);
 
-    Object::release();
+	Object::release();
 }
 
 // Increments refcount on image.
@@ -174,12 +177,12 @@
 // caller must Release() the returned image
 egl::Image *Renderbuffer::createSharedImage()
 {
-    return mInstance->createSharedImage();
+	return mInstance->createSharedImage();
 }
 
 bool Renderbuffer::isShared() const
 {
-    return mInstance->isShared();
+	return mInstance->isShared();
 }
 
 GLsizei Renderbuffer::getWidth() const
@@ -239,7 +242,7 @@
 
 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
 {
-	ASSERT(newStorage != NULL);
+	ASSERT(newStorage);
 
 	delete mInstance;
 	mInstance = newStorage;
@@ -288,7 +291,7 @@
 	if(renderTarget)
 	{
 		renderTarget->addRef();
-		
+
 		mWidth = renderTarget->getWidth();
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
@@ -346,18 +349,18 @@
 // caller must release() the returned image
 egl::Image *Colorbuffer::createSharedImage()
 {
-    if(mRenderTarget)
-    {
-        mRenderTarget->addRef();
-        mRenderTarget->markShared();
-    }
+	if(mRenderTarget)
+	{
+		mRenderTarget->addRef();
+		mRenderTarget->markShared();
+	}
 
-    return mRenderTarget;
+	return mRenderTarget;
 }
 
 bool Colorbuffer::isShared() const
 {
-    return mRenderTarget->isShared();
+	return mRenderTarget->isShared();
 }
 
 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
@@ -377,7 +380,7 @@
 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
 {
 	Device *device = getDevice();
-	
+
 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
 
 	if(width > 0 && height > 0)
@@ -422,18 +425,18 @@
 // caller must release() the returned image
 egl::Image *DepthStencilbuffer::createSharedImage()
 {
-    if(mDepthStencil)
-    {
-        mDepthStencil->addRef();
-        mDepthStencil->markShared();
-    }
+	if(mDepthStencil)
+	{
+		mDepthStencil->addRef();
+		mDepthStencil->markShared();
+	}
 
-    return mDepthStencil;
+	return mDepthStencil;
 }
 
 bool DepthStencilbuffer::isShared() const
 {
-    return mDepthStencil->isShared();
+	return mDepthStencil->isShared();
 }
 
 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
@@ -441,7 +444,7 @@
 	if(depthStencil)
 	{
 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                     // will expect one of the valid renderbuffer formats for use in 
+		                                     // will expect one of the valid renderbuffer formats for use in
 		                                     // glRenderbufferStorage
 	}
 }
@@ -451,7 +454,7 @@
 	if(mDepthStencil)
 	{
 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                     // will expect one of the valid renderbuffer formats for use in 
+		                                     // will expect one of the valid renderbuffer formats for use in
 		                                     // glRenderbufferStorage
 	}
 }
@@ -465,7 +468,7 @@
 	if(depthStencil)
 	{
 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                  // will expect one of the valid renderbuffer formats for use in 
+		                                  // will expect one of the valid renderbuffer formats for use in
 		                                  // glRenderbufferStorage
 	}
 }
@@ -475,7 +478,7 @@
 	if(mDepthStencil)
 	{
 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                  // will expect one of the valid renderbuffer formats for use in 
+		                                  // will expect one of the valid renderbuffer formats for use in
 		                                  // glRenderbufferStorage
 	}
 }
diff --git a/src/OpenGL/libGLES_CM/Renderbuffer.h b/src/OpenGL/libGLES_CM/Renderbuffer.h
index a0b1709..6bb462f 100644
--- a/src/OpenGL/libGLES_CM/Renderbuffer.h
+++ b/src/OpenGL/libGLES_CM/Renderbuffer.h
@@ -1,202 +1,205 @@
-// 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.

-//

-

-// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the

-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,

-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer

-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.

-

-#ifndef LIBGLES_CM_RENDERBUFFER_H_

-#define LIBGLES_CM_RENDERBUFFER_H_

-

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-class Texture2D;

-class Renderbuffer;

-class Colorbuffer;

-class DepthStencilbuffer;

-

-class RenderbufferInterface

-{

-public:

-	RenderbufferInterface();

-

-	virtual ~RenderbufferInterface() {};

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget() = 0;

-    virtual egl::Image *createSharedImage() = 0;

-    virtual bool isShared() const = 0;

-

-	virtual GLsizei getWidth() const = 0;

-	virtual GLsizei getHeight() const = 0;

-	virtual GLenum getFormat() const = 0;

-	virtual sw::Format getInternalFormat() const = 0;

-	virtual GLsizei getSamples() const = 0;

-

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-};

-

-class RenderbufferTexture2D : public RenderbufferInterface

-{

-public:

-	RenderbufferTexture2D(Texture2D *texture);

-

-	virtual ~RenderbufferTexture2D();

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-private:

-	gl::BindingPointer<Texture2D> mTexture2D;

-};

-

-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage

-// is called. The specific concrete type depends on whether the internal format is

-// colour depth, stencil or packed depth/stencil.

-class RenderbufferStorage : public RenderbufferInterface

-{

-public:

-	RenderbufferStorage();

-

-	virtual ~RenderbufferStorage() = 0;

-

-	virtual egl::Image *getRenderTarget() = 0;

-    virtual egl::Image *createSharedImage() = 0;

-    virtual bool isShared() const = 0;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-protected:

-	GLsizei mWidth;

-	GLsizei mHeight;

-	GLenum format;

-	sw::Format internalFormat;

-	GLsizei mSamples;

-};

-

-// Renderbuffer implements the GL renderbuffer object.

-// It's only a proxy for a RenderbufferInterface instance; the internal object

-// can change whenever glRenderbufferStorage is called.

-class Renderbuffer : public gl::NamedObject

-{

-public:

-	Renderbuffer(GLuint name, RenderbufferInterface *storage);

-

-	virtual ~Renderbuffer();

-

-	// These functions from Object are overloaded here because

-    // Textures need to maintain their own count of references to them via

-    // Renderbuffers/RenderbufferTextures. These functions invoke those

-    // reference counting functions on the RenderbufferInterface.

-    virtual void addRef();

-    virtual void release();

-

-	egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-	GLsizei getWidth() const;

-	GLsizei getHeight() const;

-	GLenum getFormat() const;

-	sw::Format getInternalFormat() const;

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-	GLsizei getSamples() const;

-

-	void setStorage(RenderbufferStorage *newStorage);

-

-private:

-	RenderbufferInterface *mInstance;

-};

-

-class Colorbuffer : public RenderbufferStorage

-{

-public:

-	explicit Colorbuffer(egl::Image *renderTarget);

-	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);

-

-	virtual ~Colorbuffer();

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-private:

-	egl::Image *mRenderTarget;

-};

-

-class DepthStencilbuffer : public RenderbufferStorage

-{

-public:

-	explicit DepthStencilbuffer(egl::Image *depthStencil);

-	DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	~DepthStencilbuffer();

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-protected:

-	egl::Image *mDepthStencil;

-};

-

-class Depthbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Depthbuffer(egl::Image *depthStencil);

-	Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	virtual ~Depthbuffer();

-};

-

-class Stencilbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Stencilbuffer(egl::Image *depthStencil);

-	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	virtual ~Stencilbuffer();

-};

-}

-

-#endif   // LIBGLES_CM_RENDERBUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the
+// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
+// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+
+#ifndef LIBGLES_CM_RENDERBUFFER_H_
+#define LIBGLES_CM_RENDERBUFFER_H_
+
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+class Texture2D;
+class Renderbuffer;
+class Colorbuffer;
+class DepthStencilbuffer;
+
+class RenderbufferInterface
+{
+public:
+	RenderbufferInterface();
+
+	virtual ~RenderbufferInterface() {};
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+    virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget() = 0;
+    virtual egl::Image *createSharedImage() = 0;
+    virtual bool isShared() const = 0;
+
+	virtual GLsizei getWidth() const = 0;
+	virtual GLsizei getHeight() const = 0;
+	virtual GLenum getFormat() const = 0;
+	virtual sw::Format getInternalFormat() const = 0;
+	virtual GLsizei getSamples() const = 0;
+
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+};
+
+class RenderbufferTexture2D : public RenderbufferInterface
+{
+public:
+	RenderbufferTexture2D(Texture2D *texture);
+
+	virtual ~RenderbufferTexture2D();
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+    virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+private:
+	gl::BindingPointer<Texture2D> mTexture2D;
+};
+
+// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
+// is called. The specific concrete type depends on whether the internal format is
+// colour depth, stencil or packed depth/stencil.
+class RenderbufferStorage : public RenderbufferInterface
+{
+public:
+	RenderbufferStorage();
+
+	virtual ~RenderbufferStorage() = 0;
+
+	virtual egl::Image *getRenderTarget() = 0;
+    virtual egl::Image *createSharedImage() = 0;
+    virtual bool isShared() const = 0;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+protected:
+	GLsizei mWidth;
+	GLsizei mHeight;
+	GLenum format;
+	sw::Format internalFormat;
+	GLsizei mSamples;
+};
+
+// Renderbuffer implements the GL renderbuffer object.
+// It's only a proxy for a RenderbufferInterface instance; the internal object
+// can change whenever glRenderbufferStorage is called.
+class Renderbuffer : public gl::NamedObject
+{
+public:
+	Renderbuffer(GLuint name, RenderbufferInterface *storage);
+
+	virtual ~Renderbuffer();
+
+	// These functions from Object are overloaded here because
+    // Textures need to maintain their own count of references to them via
+    // Renderbuffers/RenderbufferTextures. These functions invoke those
+    // reference counting functions on the RenderbufferInterface.
+    virtual void addRef();
+    virtual void release();
+
+	egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+	GLsizei getWidth() const;
+	GLsizei getHeight() const;
+	GLenum getFormat() const;
+	sw::Format getInternalFormat() const;
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+	GLsizei getSamples() const;
+
+	void setStorage(RenderbufferStorage *newStorage);
+
+private:
+	RenderbufferInterface *mInstance;
+};
+
+class Colorbuffer : public RenderbufferStorage
+{
+public:
+	explicit Colorbuffer(egl::Image *renderTarget);
+	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+
+	virtual ~Colorbuffer();
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+private:
+	egl::Image *mRenderTarget;
+};
+
+class DepthStencilbuffer : public RenderbufferStorage
+{
+public:
+	explicit DepthStencilbuffer(egl::Image *depthStencil);
+	DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	~DepthStencilbuffer();
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+protected:
+	egl::Image *mDepthStencil;
+};
+
+class Depthbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Depthbuffer(egl::Image *depthStencil);
+	Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	virtual ~Depthbuffer();
+};
+
+class Stencilbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Stencilbuffer(egl::Image *depthStencil);
+	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	virtual ~Stencilbuffer();
+};
+}
+
+#endif   // LIBGLES_CM_RENDERBUFFER_H_
diff --git a/src/OpenGL/libGLES_CM/ResourceManager.cpp b/src/OpenGL/libGLES_CM/ResourceManager.cpp
index 54d71b9..7f0936c 100644
--- a/src/OpenGL/libGLES_CM/ResourceManager.cpp
+++ b/src/OpenGL/libGLES_CM/ResourceManager.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // ResourceManager.cpp: Implements the ResourceManager class, which tracks and
 // retrieves objects which may be shared by multiple Contexts.
@@ -22,138 +25,138 @@
 {
 ResourceManager::ResourceManager()
 {
-    mRefCount = 1;
+	mRefCount = 1;
 }
 
 ResourceManager::~ResourceManager()
 {
-    while(!mBufferNameSpace.empty())
-    {
-        deleteBuffer(mBufferNameSpace.firstName());
-    }
+	while(!mBufferNameSpace.empty())
+	{
+		deleteBuffer(mBufferNameSpace.firstName());
+	}
 
-    while(!mRenderbufferNameSpace.empty())
-    {
-        deleteRenderbuffer(mRenderbufferNameSpace.firstName());
-    }
+	while(!mRenderbufferNameSpace.empty())
+	{
+		deleteRenderbuffer(mRenderbufferNameSpace.firstName());
+	}
 
-    while(!mTextureNameSpace.empty())
-    {
-        deleteTexture(mTextureNameSpace.firstName());
-    }
+	while(!mTextureNameSpace.empty())
+	{
+		deleteTexture(mTextureNameSpace.firstName());
+	}
 }
 
 void ResourceManager::addRef()
 {
-    mRefCount++;
+	mRefCount++;
 }
 
 void ResourceManager::release()
 {
-    if(--mRefCount == 0)
-    {
-        delete this;
-    }
+	if(--mRefCount == 0)
+	{
+		delete this;
+	}
 }
 
 // Returns an unused buffer name
 GLuint ResourceManager::createBuffer()
 {
-    return mBufferNameSpace.allocate();
+	return mBufferNameSpace.allocate();
 }
 
 // Returns an unused texture name
 GLuint ResourceManager::createTexture()
 {
-    return mTextureNameSpace.allocate();
+	return mTextureNameSpace.allocate();
 }
 
 // Returns an unused renderbuffer name
 GLuint ResourceManager::createRenderbuffer()
 {
-    return mRenderbufferNameSpace.allocate();
+	return mRenderbufferNameSpace.allocate();
 }
 
 void ResourceManager::deleteBuffer(GLuint buffer)
 {
-    Buffer *bufferObject = mBufferNameSpace.remove(buffer);
+	Buffer *bufferObject = mBufferNameSpace.remove(buffer);
 
-    if(bufferObject)
-    {
+	if(bufferObject)
+	{
 		bufferObject->release();
-    }
+	}
 }
 
 void ResourceManager::deleteTexture(GLuint texture)
 {
-    Texture *textureObject = mTextureNameSpace.remove(texture);
+	Texture *textureObject = mTextureNameSpace.remove(texture);
 
-    if(textureObject)
-    {
+	if(textureObject)
+	{
 		textureObject->release();
-    }
+	}
 }
 
 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
 {
-    Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
+	Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
 
-    if(renderbufferObject)
-    {
+	if(renderbufferObject)
+	{
 		renderbufferObject->release();
-    }
+	}
 }
 
 Buffer *ResourceManager::getBuffer(unsigned int handle)
 {
-    return mBufferNameSpace.find(handle);
+	return mBufferNameSpace.find(handle);
 }
 
 Texture *ResourceManager::getTexture(unsigned int handle)
 {
-    return mTextureNameSpace.find(handle);
+	return mTextureNameSpace.find(handle);
 }
 
 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
 {
-    return mRenderbufferNameSpace.find(handle);
+	return mRenderbufferNameSpace.find(handle);
 }
 
 void ResourceManager::checkBufferAllocation(unsigned int buffer)
 {
-    if(buffer != 0 && !getBuffer(buffer))
-    {
-        Buffer *bufferObject = new Buffer(buffer);
+	if(buffer != 0 && !getBuffer(buffer))
+	{
+		Buffer *bufferObject = new Buffer(buffer);
 		bufferObject->addRef();
 
 		mBufferNameSpace.insert(buffer, bufferObject);
-    }
+	}
 }
 
 void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
 {
-    if(!getTexture(texture) && texture != 0)
-    {
-        Texture *textureObject;
+	if(!getTexture(texture) && texture != 0)
+	{
+		Texture *textureObject;
 
-        if(type == TEXTURE_2D)
-        {
-            textureObject = new Texture2D(texture);
-        }
-        else if(type == TEXTURE_EXTERNAL)
-        {
-            textureObject = new TextureExternal(texture);
-        }
-        else
-        {
-            UNREACHABLE(type);
-            return;
-        }
+		if(type == TEXTURE_2D)
+		{
+			textureObject = new Texture2D(texture);
+		}
+		else if(type == TEXTURE_EXTERNAL)
+		{
+			textureObject = new TextureExternal(texture);
+		}
+		else
+		{
+			UNREACHABLE(type);
+			return;
+		}
 
 		textureObject->addRef();
 
 		mTextureNameSpace.insert(texture, textureObject);
-    }
+	}
 }
 
 void ResourceManager::checkRenderbufferAllocation(GLuint handle)
diff --git a/src/OpenGL/libGLES_CM/ResourceManager.h b/src/OpenGL/libGLES_CM/ResourceManager.h
index 22d719f..7520580 100644
--- a/src/OpenGL/libGLES_CM/ResourceManager.h
+++ b/src/OpenGL/libGLES_CM/ResourceManager.h
@@ -1,75 +1,78 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// ResourceManager.h : Defines the ResourceManager class, which tracks objects

-// shared by multiple GL contexts.

-

-#ifndef LIBGLES_CM_RESOURCEMANAGER_H_

-#define LIBGLES_CM_RESOURCEMANAGER_H_

-

-#include "common/NameSpace.hpp"

-

-#include <GLES/gl.h>

-

-#include <map>

-

-namespace es1

-{

-class Buffer;

-class Texture;

-class Renderbuffer;

-

-enum TextureType

-{

-    TEXTURE_2D,

-    TEXTURE_CUBE,

-    TEXTURE_EXTERNAL,

-

-    TEXTURE_TYPE_COUNT,

-    TEXTURE_UNKNOWN

-};

-

-class ResourceManager

-{

-public:

-    ResourceManager();

-    ~ResourceManager();

-

-    void addRef();

-    void release();

-

-    GLuint createBuffer();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-

-    void deleteBuffer(GLuint buffer);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-

-    Buffer *getBuffer(GLuint handle);

-    Texture *getTexture(GLuint handle);

-    Renderbuffer *getRenderbuffer(GLuint handle);

-

-    void checkBufferAllocation(unsigned int buffer);

-    void checkTextureAllocation(GLuint texture, TextureType type);

-	void checkRenderbufferAllocation(GLuint handle);

-

-private:

-    std::size_t mRefCount;

-

-    gl::NameSpace<Buffer> mBufferNameSpace;

-	gl::NameSpace<Texture> mTextureNameSpace;

-    gl::NameSpace<Renderbuffer> mRenderbufferNameSpace;

-};

-

-}

-

-#endif // LIBGLES_CM_RESOURCEMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// ResourceManager.h : Defines the ResourceManager class, which tracks objects
+// shared by multiple GL contexts.
+
+#ifndef LIBGLES_CM_RESOURCEMANAGER_H_
+#define LIBGLES_CM_RESOURCEMANAGER_H_
+
+#include "common/NameSpace.hpp"
+
+#include <GLES/gl.h>
+
+#include <map>
+
+namespace es1
+{
+class Buffer;
+class Texture;
+class Renderbuffer;
+
+enum TextureType
+{
+	TEXTURE_2D,
+	TEXTURE_CUBE,
+	TEXTURE_EXTERNAL,
+
+	TEXTURE_TYPE_COUNT,
+	TEXTURE_UNKNOWN
+};
+
+class ResourceManager
+{
+public:
+	ResourceManager();
+	~ResourceManager();
+
+	void addRef();
+	void release();
+
+	GLuint createBuffer();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+
+	void deleteBuffer(GLuint buffer);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+
+	Buffer *getBuffer(GLuint handle);
+	Texture *getTexture(GLuint handle);
+	Renderbuffer *getRenderbuffer(GLuint handle);
+
+	void checkBufferAllocation(unsigned int buffer);
+	void checkTextureAllocation(GLuint texture, TextureType type);
+	void checkRenderbufferAllocation(GLuint handle);
+
+private:
+	std::size_t mRefCount;
+
+	gl::NameSpace<Buffer> mBufferNameSpace;
+	gl::NameSpace<Texture> mTextureNameSpace;
+	gl::NameSpace<Renderbuffer> mRenderbufferNameSpace;
+};
+
+}
+
+#endif // LIBGLES_CM_RESOURCEMANAGER_H_
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index 3729d9b..b8817a0 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -1,860 +1,863 @@
-// 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.

-//

-

-// Texture.cpp: Implements the Texture class and its derived classes

-// Texture2D and TextureCubeMap. Implements GL texture objects and related

-// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

-

-#include "Texture.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "Framebuffer.h"

-#include "Device.hpp"

-#include "libEGL/Display.h"

-#include "libEGL/Surface.h"

-#include "common/debug.h"

-

-#include <algorithm>

-

-namespace es1

-{

-

-Texture::Texture(GLuint name) : egl::Texture(name)

-{

-    mMinFilter = GL_NEAREST_MIPMAP_LINEAR;

-    mMagFilter = GL_LINEAR;

-    mWrapS = GL_REPEAT;

-    mWrapT = GL_REPEAT;

-	mMaxAnisotropy = 1.0f;

-	generateMipmap = GL_FALSE;

-	cropRectU = 0;

-	cropRectV = 0;

-	cropRectW = 0;

-	cropRectH = 0;

-

-	resource = new sw::Resource(0);

-}

-

-Texture::~Texture()

-{

-	resource->destruct();

-}

-

-sw::Resource *Texture::getResource() const

-{

-	return resource;

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMinFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_NEAREST:

-    case GL_LINEAR:

-        mMinFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMagFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        mMagFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapS(GLenum wrap)

-{

-    switch(wrap)

-    {

-    case GL_REPEAT:

-    case GL_MIRRORED_REPEAT_OES:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_CLAMP_TO_EDGE:

-        mWrapS = wrap;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapT(GLenum wrap)

-{

-    switch(wrap)

-    {

-    case GL_REPEAT:

-    case GL_MIRRORED_REPEAT_OES:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_CLAMP_TO_EDGE:

-         mWrapT = wrap;

-         return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful max anisotropy update (valid anisotropy value)

-bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)

-{

-    textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);

-

-    if(textureMaxAnisotropy < 1.0f)

-    {

-        return false;

-    }

-

-	if(mMaxAnisotropy != textureMaxAnisotropy)

-    {

-        mMaxAnisotropy = textureMaxAnisotropy;

-    }

-

-    return true;

-}

-

-void Texture::setGenerateMipmap(GLboolean enable)

-{

-	generateMipmap = enable;

-}

-

-void Texture::setCropRect(GLint u, GLint v, GLint w, GLint h)

-{

-	cropRectU = u;

-	cropRectV = v;

-	cropRectW = w;

-	cropRectH = h;

-}

-

-GLenum Texture::getMinFilter() const

-{

-    return mMinFilter;

-}

-

-GLenum Texture::getMagFilter() const

-{

-    return mMagFilter;

-}

-

-GLenum Texture::getWrapS() const

-{

-    return mWrapS;

-}

-

-GLenum Texture::getWrapT() const

-{

-    return mWrapT;

-}

-

-GLfloat Texture::getMaxAnisotropy() const

-{

-    return mMaxAnisotropy;

-}

-

-GLboolean Texture::getGenerateMipmap() const

-{

-	return generateMipmap;

-}

-

-GLint Texture::getCropRectU() const

-{

-	return cropRectU;

-}

-

-GLint Texture::getCropRectV() const

-{

-	return cropRectV;

-}

-

-GLint Texture::getCropRectW() const

-{

-	return cropRectW;

-}

-

-GLint Texture::getCropRectH() const

-{

-	return cropRectH;

-}

-

-egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)

-{

-    egl::Image *image = getRenderTarget(target, level);   // Increments reference count

-

-    if(image)

-    {

-        image->markShared();

-    }

-

-    return image;

-}

-

-void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)

-{

-    if(pixels && image)

-    {

-		egl::Image::UnpackInfo unpackInfo;

-		unpackInfo.alignment = unpackAlignment;

-		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackInfo, pixels);

-    }

-}

-

-void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)

-{

-    if(pixels && image)

-    {

-		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);

-    }

-}

-

-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(IsCompressed(image->getFormat()))

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-		egl::Image::UnpackInfo unpackInfo;

-		unpackInfo.alignment = unpackAlignment;

-		image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels);

-    }

-}

-

-void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);

-    }

-}

-

-bool Texture::copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest)

-{

-    Device *device = getDevice();

-

-    sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), 0);

-    sw::SliceRect sourceSliceRect(sourceRect);

-    bool success = device->stretchRect(source, &sourceSliceRect, dest, &destRect, false);

-

-    if(!success)

-    {

-        return error(GL_OUT_OF_MEMORY, false);

-    }

-

-    return true;

-}

-

-bool Texture::isMipmapFiltered() const

-{

-	switch(mMinFilter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        return false;

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        return true;

-    default: UNREACHABLE(mMinFilter);

-    }

-

-	return false;

-}

-

-Texture2D::Texture2D(GLuint name) : Texture(name)

-{

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		image[i] = nullptr;

-	}

-

-    mSurface = nullptr;

-

-	mColorbufferProxy = nullptr;

-	mProxyRefs = 0;

-}

-

-Texture2D::~Texture2D()

-{

-	resource->lock(sw::DESTRUCT);

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i])

-		{

-			image[i]->unbind(this);

-			image[i] = nullptr;

-		}

-	}

-

-	resource->unlock();

-

-    if(mSurface)

-    {

-        mSurface->setBoundTexture(nullptr);

-        mSurface = nullptr;

-    }

-

-	mColorbufferProxy = nullptr;

-}

-

-// We need to maintain a count of references to renderbuffers acting as

-// proxies for this texture, so that we do not attempt to use a pointer

-// to a renderbuffer proxy which has been deleted.

-void Texture2D::addProxyRef(const Renderbuffer *proxy)

-{

-    mProxyRefs++;

-}

-

-void Texture2D::releaseProxy(const Renderbuffer *proxy)

-{

-    if(mProxyRefs > 0)

-	{

-        mProxyRefs--;

-	}

-

-    if(mProxyRefs == 0)

-	{

-		mColorbufferProxy = nullptr;

-	}

-}

-

-void Texture2D::sweep()

-{

-	int imageCount = 0;

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i] && image[i]->isChildOf(this))

-		{

-			if(!image[i]->hasSingleReference())

-			{

-				return;

-			}

-

-			imageCount++;

-		}

-	}

-

-	if(imageCount == referenceCount)

-	{

-		destroy();

-	}

-}

-

-GLenum Texture2D::getTarget() const

-{

-    return GL_TEXTURE_2D;

-}

-

-GLsizei Texture2D::getWidth(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getWidth() : 0;

-}

-

-GLsizei Texture2D::getHeight(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getHeight() : 0;

-}

-

-GLenum Texture2D::getFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getFormat() : GL_NONE;

-}

-

-GLenum Texture2D::getType(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getType() : GL_NONE;

-}

-

-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;

-}

-

-int Texture2D::getLevelCount() const

-{

-	ASSERT(isSamplerComplete());

-	int levels = 0;

-

-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])

-	{

-		levels++;

-	}

-

-	return levels;

-}

-

-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, format, type);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setImage(format, type, unpackAlignment, pixels, image[level]);

-}

-

-void Texture2D::bindTexImage(egl::Surface *surface)

-{

-    GLenum format;

-

-    switch(surface->getInternalFormat())

-    {

-    case sw::FORMAT_A8R8G8B8:

-		format = GL_BGRA_EXT;

-        break;

-	case sw::FORMAT_A8B8G8R8:

-        format = GL_RGBA;

-        break;

-    case sw::FORMAT_X8B8G8R8:

-	case sw::FORMAT_X8R8G8B8:

-        format = GL_RGB;

-        break;

-    default:

-        UNIMPLEMENTED();

-        return;

-    }

-

-	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-

-	image[0] = surface->getRenderTarget();

-

-    mSurface = surface;

-    mSurface->setBoundTexture(this);

-}

-

-void Texture2D::releaseTexImage()

-{

-    for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-}

-

-void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setCompressedImage(imageSize, pixels, image[level]);

-}

-

-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);

-}

-

-void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

-{

-    Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);

-}

-

-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-    egl::Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    if(width != 0 && height != 0)

-    {

-		sw::Rect sourceRect = {x, y, x + width, y + height};

-		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-

-        copy(renderTarget, sourceRect, format, 0, 0, image[level]);

-    }

-

-	renderTarget->release();

-}

-

-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	if(!image[level])

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    egl::Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	sw::Rect sourceRect = {x, y, x + width, y + height};

-	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-

-	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);

-

-	renderTarget->release();

-}

-

-void Texture2D::setImage(egl::Image *sharedImage)

-{

-	sharedImage->addRef();

-

-    if(image[0])

-    {

-        image[0]->release();

-    }

-

-    image[0] = sharedImage;

-}

-

-// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.

-bool Texture2D::isSamplerComplete() const

-{

-	if(!image[0])

-	{

-		return false;

-	}

-

-    GLsizei width = image[0]->getWidth();

-    GLsizei height = image[0]->getHeight();

-

-    if(width <= 0 || height <= 0)

-    {

-        return false;

-    }

-

-    if(isMipmapFiltered())

-    {

-        if(!generateMipmap && !isMipmapComplete())

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.

-bool Texture2D::isMipmapComplete() const

-{

-    GLsizei width = image[0]->getWidth();

-    GLsizei height = image[0]->getHeight();

-

-    int q = log2(std::max(width, height));

-

-    for(int level = 1; level <= q; level++)

-    {

-		if(!image[level])

-		{

-			return false;

-		}

-

-        if(image[level]->getFormat() != image[0]->getFormat())

-        {

-            return false;

-        }

-

-        if(image[level]->getType() != image[0]->getType())

-        {

-            return false;

-        }

-

-        if(image[level]->getWidth() != std::max(1, width >> level))

-        {

-            return false;

-        }

-

-        if(image[level]->getHeight() != std::max(1, height >> level))

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-bool Texture2D::isCompressed(GLenum target, GLint level) const

-{

-    return IsCompressed(getFormat(target, level));

-}

-

-bool Texture2D::isDepth(GLenum target, GLint level) const

-{

-    return IsDepthTexture(getFormat(target, level));

-}

-

-void Texture2D::generateMipmaps()

-{

-	if(!image[0])

-	{

-		return;   // FIXME: error?

-	}

-

-    unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));

-

-	for(unsigned int i = 1; i <= q; i++)

-    {

-		if(image[i])

-		{

-			image[i]->release();

-		}

-

-		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());

-

-		if(!image[i])

-		{

-			return error(GL_OUT_OF_MEMORY);

-		}

-

-		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);

-    }

-}

-

-void Texture2D::autoGenerateMipmaps()

-{

-	if(generateMipmap && image[0]->hasDirtyMipmaps())

-	{

-		generateMipmaps();

-		image[0]->cleanMipmaps();

-	}

-}

-

-egl::Image *Texture2D::getImage(unsigned int level)

-{

-	return image[level];

-}

-

-Renderbuffer *Texture2D::getRenderbuffer(GLenum target)

-{

-    if(target != GL_TEXTURE_2D)

-    {

-        return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);

-    }

-

-    if(!mColorbufferProxy)

-    {

-        mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));

-    }

-

-    return mColorbufferProxy;

-}

-

-egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)

-{

-    ASSERT(target == GL_TEXTURE_2D);

-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-	if(image[level])

-	{

-		image[level]->addRef();

-	}

-

-	return image[level];

-}

-

-bool Texture2D::isShared(GLenum target, unsigned int level) const

-{

-    ASSERT(target == GL_TEXTURE_2D);

-    ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-    if(mSurface)   // Bound to an EGLSurface

-    {

-        return true;

-    }

-

-    if(!image[level])

-    {

-        return false;

-    }

-

-    return image[level]->isShared();

-}

-

-TextureExternal::TextureExternal(GLuint name) : Texture2D(name)

-{

-    mMinFilter = GL_LINEAR;

-    mMagFilter = GL_LINEAR;

-    mWrapS = GL_CLAMP_TO_EDGE;

-    mWrapT = GL_CLAMP_TO_EDGE;

-}

-

-TextureExternal::~TextureExternal()

-{

-}

-

-GLenum TextureExternal::getTarget() const

-{

-    return GL_TEXTURE_EXTERNAL_OES;

-}

-

-}

-

-egl::Image *createBackBuffer(int width, int height, const egl::Config *config)

-{

-	if(config)

-	{

-		return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);

-	}

-

-	return nullptr;

-}

-

-egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-{

-	if(height > sw::OUTLINE_RESOLUTION)

-	{

-		ERR("Invalid parameters: %dx%d", width, height);

-		return 0;

-	}

-

-	bool lockable = true;

-

-	switch(format)

-	{

-//	case sw::FORMAT_D15S1:

-	case sw::FORMAT_D24S8:

-	case sw::FORMAT_D24X8:

-//	case sw::FORMAT_D24X4S4:

-	case sw::FORMAT_D24FS8:

-	case sw::FORMAT_D32:

-	case sw::FORMAT_D16:

-		lockable = false;

-		break;

-//	case sw::FORMAT_S8_LOCKABLE:

-//	case sw::FORMAT_D16_LOCKABLE:

-	case sw::FORMAT_D32F_LOCKABLE:

-//	case sw::FORMAT_D32_LOCKABLE:

-	case sw::FORMAT_DF24S8:

-	case sw::FORMAT_DF16S8:

-		lockable = true;

-		break;

-	default:

-		UNREACHABLE(format);

-	}

-

-	egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-	if(!surface)

-	{

-		ERR("Out of memory");

-		return nullptr;

-	}

-

-	return surface;

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Texture.cpp: Implements the Texture class and its derived classes
+// Texture2D and TextureCubeMap. Implements GL texture objects and related
+// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#include "Texture.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "Framebuffer.h"
+#include "Device.hpp"
+#include "libEGL/Display.h"
+#include "libEGL/Surface.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+namespace es1
+{
+
+Texture::Texture(GLuint name) : egl::Texture(name)
+{
+	mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
+	mMagFilter = GL_LINEAR;
+	mWrapS = GL_REPEAT;
+	mWrapT = GL_REPEAT;
+	mMaxAnisotropy = 1.0f;
+	generateMipmap = GL_FALSE;
+	cropRectU = 0;
+	cropRectV = 0;
+	cropRectW = 0;
+	cropRectH = 0;
+
+	resource = new sw::Resource(0);
+}
+
+Texture::~Texture()
+{
+	resource->destruct();
+}
+
+sw::Resource *Texture::getResource() const
+{
+	return resource;
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMinFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_NEAREST:
+	case GL_LINEAR:
+		mMinFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMagFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		mMagFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapS(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_REPEAT:
+	case GL_MIRRORED_REPEAT_OES:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_CLAMP_TO_EDGE:
+		mWrapS = wrap;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapT(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_REPEAT:
+	case GL_MIRRORED_REPEAT_OES:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_CLAMP_TO_EDGE:
+		 mWrapT = wrap;
+		 return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful max anisotropy update (valid anisotropy value)
+bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)
+{
+	textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);
+
+	if(textureMaxAnisotropy < 1.0f)
+	{
+		return false;
+	}
+
+	if(mMaxAnisotropy != textureMaxAnisotropy)
+	{
+		mMaxAnisotropy = textureMaxAnisotropy;
+	}
+
+	return true;
+}
+
+void Texture::setGenerateMipmap(GLboolean enable)
+{
+	generateMipmap = enable;
+}
+
+void Texture::setCropRect(GLint u, GLint v, GLint w, GLint h)
+{
+	cropRectU = u;
+	cropRectV = v;
+	cropRectW = w;
+	cropRectH = h;
+}
+
+GLenum Texture::getMinFilter() const
+{
+	return mMinFilter;
+}
+
+GLenum Texture::getMagFilter() const
+{
+	return mMagFilter;
+}
+
+GLenum Texture::getWrapS() const
+{
+	return mWrapS;
+}
+
+GLenum Texture::getWrapT() const
+{
+	return mWrapT;
+}
+
+GLfloat Texture::getMaxAnisotropy() const
+{
+	return mMaxAnisotropy;
+}
+
+GLboolean Texture::getGenerateMipmap() const
+{
+	return generateMipmap;
+}
+
+GLint Texture::getCropRectU() const
+{
+	return cropRectU;
+}
+
+GLint Texture::getCropRectV() const
+{
+	return cropRectV;
+}
+
+GLint Texture::getCropRectW() const
+{
+	return cropRectW;
+}
+
+GLint Texture::getCropRectH() const
+{
+	return cropRectH;
+}
+
+egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)
+{
+	egl::Image *image = getRenderTarget(target, level);   // Increments reference count
+
+	if(image)
+	{
+		image->markShared();
+	}
+
+	return image;
+}
+
+void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
+{
+	if(pixels && image)
+	{
+		egl::Image::UnpackInfo unpackInfo;
+		unpackInfo.alignment = unpackAlignment;
+		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackInfo, pixels);
+	}
+}
+
+void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)
+{
+	if(pixels && image)
+	{
+		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);
+	}
+}
+
+void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(IsCompressed(image->getFormat()))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		egl::Image::UnpackInfo unpackInfo;
+		unpackInfo.alignment = unpackAlignment;
+		image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels);
+	}
+}
+
+void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);
+	}
+}
+
+bool Texture::copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest)
+{
+	Device *device = getDevice();
+
+	sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), 0);
+	sw::SliceRect sourceSliceRect(sourceRect);
+	bool success = device->stretchRect(source, &sourceSliceRect, dest, &destRect, false);
+
+	if(!success)
+	{
+		return error(GL_OUT_OF_MEMORY, false);
+	}
+
+	return true;
+}
+
+bool Texture::isMipmapFiltered() const
+{
+	switch(mMinFilter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		return false;
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		return true;
+	default: UNREACHABLE(mMinFilter);
+	}
+
+	return false;
+}
+
+Texture2D::Texture2D(GLuint name) : Texture(name)
+{
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		image[i] = nullptr;
+	}
+
+	mSurface = nullptr;
+
+	mColorbufferProxy = nullptr;
+	mProxyRefs = 0;
+}
+
+Texture2D::~Texture2D()
+{
+	resource->lock(sw::DESTRUCT);
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i])
+		{
+			image[i]->unbind(this);
+			image[i] = nullptr;
+		}
+	}
+
+	resource->unlock();
+
+	if(mSurface)
+	{
+		mSurface->setBoundTexture(nullptr);
+		mSurface = nullptr;
+	}
+
+	mColorbufferProxy = nullptr;
+}
+
+// We need to maintain a count of references to renderbuffers acting as
+// proxies for this texture, so that we do not attempt to use a pointer
+// to a renderbuffer proxy which has been deleted.
+void Texture2D::addProxyRef(const Renderbuffer *proxy)
+{
+	mProxyRefs++;
+}
+
+void Texture2D::releaseProxy(const Renderbuffer *proxy)
+{
+	if(mProxyRefs > 0)
+	{
+		mProxyRefs--;
+	}
+
+	if(mProxyRefs == 0)
+	{
+		mColorbufferProxy = nullptr;
+	}
+}
+
+void Texture2D::sweep()
+{
+	int imageCount = 0;
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i] && image[i]->isChildOf(this))
+		{
+			if(!image[i]->hasSingleReference())
+			{
+				return;
+			}
+
+			imageCount++;
+		}
+	}
+
+	if(imageCount == referenceCount)
+	{
+		destroy();
+	}
+}
+
+GLenum Texture2D::getTarget() const
+{
+	return GL_TEXTURE_2D;
+}
+
+GLsizei Texture2D::getWidth(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getWidth() : 0;
+}
+
+GLsizei Texture2D::getHeight(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getHeight() : 0;
+}
+
+GLenum Texture2D::getFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getFormat() : GL_NONE;
+}
+
+GLenum Texture2D::getType(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getType() : GL_NONE;
+}
+
+sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
+}
+
+int Texture2D::getLevelCount() const
+{
+	ASSERT(isSamplerComplete());
+	int levels = 0;
+
+	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	{
+		levels++;
+	}
+
+	return levels;
+}
+
+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, format, type);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setImage(format, type, unpackAlignment, pixels, image[level]);
+}
+
+void Texture2D::bindTexImage(egl::Surface *surface)
+{
+	GLenum format;
+
+	switch(surface->getInternalFormat())
+	{
+	case sw::FORMAT_A8R8G8B8:
+		format = GL_BGRA_EXT;
+		break;
+	case sw::FORMAT_A8B8G8R8:
+		format = GL_RGBA;
+		break;
+	case sw::FORMAT_X8B8G8R8:
+	case sw::FORMAT_X8R8G8B8:
+		format = GL_RGB;
+		break;
+	default:
+		UNIMPLEMENTED();
+		return;
+	}
+
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+
+	image[0] = surface->getRenderTarget();
+
+	mSurface = surface;
+	mSurface->setBoundTexture(this);
+}
+
+void Texture2D::releaseTexImage()
+{
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+}
+
+void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setCompressedImage(imageSize, pixels, image[level]);
+}
+
+void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);
+}
+
+void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+	Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);
+}
+
+void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	egl::Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(width != 0 && height != 0)
+	{
+		sw::Rect sourceRect = {x, y, x + width, y + height};
+		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+		copy(renderTarget, sourceRect, format, 0, 0, image[level]);
+	}
+
+	renderTarget->release();
+}
+
+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	if(!image[level])
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	egl::Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	sw::Rect sourceRect = {x, y, x + width, y + height};
+	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);
+
+	renderTarget->release();
+}
+
+void Texture2D::setImage(egl::Image *sharedImage)
+{
+	sharedImage->addRef();
+
+	if(image[0])
+	{
+		image[0]->release();
+	}
+
+	image[0] = sharedImage;
+}
+
+// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+bool Texture2D::isSamplerComplete() const
+{
+	if(!image[0])
+	{
+		return false;
+	}
+
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+
+	if(width <= 0 || height <= 0)
+	{
+		return false;
+	}
+
+	if(isMipmapFiltered())
+	{
+		if(!generateMipmap && !isMipmapComplete())
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool Texture2D::isMipmapComplete() const
+{
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+
+	int q = log2(std::max(width, height));
+
+	for(int level = 1; level <= q; level++)
+	{
+		if(!image[level])
+		{
+			return false;
+		}
+
+		if(image[level]->getFormat() != image[0]->getFormat())
+		{
+			return false;
+		}
+
+		if(image[level]->getType() != image[0]->getType())
+		{
+			return false;
+		}
+
+		if(image[level]->getWidth() != std::max(1, width >> level))
+		{
+			return false;
+		}
+
+		if(image[level]->getHeight() != std::max(1, height >> level))
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool Texture2D::isCompressed(GLenum target, GLint level) const
+{
+	return IsCompressed(getFormat(target, level));
+}
+
+bool Texture2D::isDepth(GLenum target, GLint level) const
+{
+	return IsDepthTexture(getFormat(target, level));
+}
+
+void Texture2D::generateMipmaps()
+{
+	if(!image[0])
+	{
+		return;   // FIXME: error?
+	}
+
+	unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+
+	for(unsigned int i = 1; i <= q; i++)
+	{
+		if(image[i])
+		{
+			image[i]->release();
+		}
+
+		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
+
+		if(!image[i])
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+
+		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);
+	}
+}
+
+void Texture2D::autoGenerateMipmaps()
+{
+	if(generateMipmap && image[0]->hasDirtyMipmaps())
+	{
+		generateMipmaps();
+		image[0]->cleanMipmaps();
+	}
+}
+
+egl::Image *Texture2D::getImage(unsigned int level)
+{
+	return image[level];
+}
+
+Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
+{
+	if(target != GL_TEXTURE_2D)
+	{
+		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
+	}
+
+	if(!mColorbufferProxy)
+	{
+		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));
+	}
+
+	return mColorbufferProxy;
+}
+
+egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(image[level])
+	{
+		image[level]->addRef();
+	}
+
+	return image[level];
+}
+
+bool Texture2D::isShared(GLenum target, unsigned int level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(mSurface)   // Bound to an EGLSurface
+	{
+		return true;
+	}
+
+	if(!image[level])
+	{
+		return false;
+	}
+
+	return image[level]->isShared();
+}
+
+TextureExternal::TextureExternal(GLuint name) : Texture2D(name)
+{
+	mMinFilter = GL_LINEAR;
+	mMagFilter = GL_LINEAR;
+	mWrapS = GL_CLAMP_TO_EDGE;
+	mWrapT = GL_CLAMP_TO_EDGE;
+}
+
+TextureExternal::~TextureExternal()
+{
+}
+
+GLenum TextureExternal::getTarget() const
+{
+	return GL_TEXTURE_EXTERNAL_OES;
+}
+
+}
+
+egl::Image *createBackBuffer(int width, int height, const egl::Config *config)
+{
+	if(config)
+	{
+		return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);
+	}
+
+	return nullptr;
+}
+
+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+{
+	if(height > sw::OUTLINE_RESOLUTION)
+	{
+		ERR("Invalid parameters: %dx%d", width, height);
+		return 0;
+	}
+
+	bool lockable = true;
+
+	switch(format)
+	{
+//	case sw::FORMAT_D15S1:
+	case sw::FORMAT_D24S8:
+	case sw::FORMAT_D24X8:
+//	case sw::FORMAT_D24X4S4:
+	case sw::FORMAT_D24FS8:
+	case sw::FORMAT_D32:
+	case sw::FORMAT_D16:
+		lockable = false;
+		break;
+//	case sw::FORMAT_S8_LOCKABLE:
+//	case sw::FORMAT_D16_LOCKABLE:
+	case sw::FORMAT_D32F_LOCKABLE:
+//	case sw::FORMAT_D32_LOCKABLE:
+	case sw::FORMAT_DF24S8:
+	case sw::FORMAT_DF16S8:
+		lockable = true;
+		break;
+	default:
+		UNREACHABLE(format);
+	}
+
+	egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+	if(!surface)
+	{
+		ERR("Out of memory");
+		return nullptr;
+	}
+
+	return surface;
+}
diff --git a/src/OpenGL/libGLES_CM/Texture.h b/src/OpenGL/libGLES_CM/Texture.h
index 6d53711..f28022d 100644
--- a/src/OpenGL/libGLES_CM/Texture.h
+++ b/src/OpenGL/libGLES_CM/Texture.h
@@ -1,197 +1,200 @@
-// 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.

-//

-

-// Texture.h: Defines the abstract Texture class and its concrete derived

-// classes Texture2D and TextureCubeMap. Implements GL texture objects and

-// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

-

-#ifndef LIBGLES_CM_TEXTURE_H_

-#define LIBGLES_CM_TEXTURE_H_

-

-#include "Renderbuffer.h"

-#include "common/Object.hpp"

-#include "utilities.h"

-#include "libEGL/Texture.hpp"

-#include "common/debug.h"

-

-#include <GLES/gl.h>

-

-#include <vector>

-

-namespace egl

-{

-class Surface;

-class Config;

-}

-

-namespace es1

-{

-class Framebuffer;

-

-enum

-{

-	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,

-    IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,

-};

-

-class Texture : public egl::Texture

-{

-public:

-    explicit Texture(GLuint name);

-

-	sw::Resource *getResource() const;

-

-	virtual void addProxyRef(const Renderbuffer *proxy) = 0;

-    virtual void releaseProxy(const Renderbuffer *proxy) = 0;

-

-    virtual GLenum getTarget() const = 0;

-

-    bool setMinFilter(GLenum filter);

-    bool setMagFilter(GLenum filter);

-    bool setWrapS(GLenum wrap);

-    bool setWrapT(GLenum wrap);

-	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);

-	void setGenerateMipmap(GLboolean enable);

-	void setCropRect(GLint u, GLint v, GLint w, GLint h);

-

-    GLenum getMinFilter() const;

-    GLenum getMagFilter() const;

-    GLenum getWrapS() const;

-    GLenum getWrapT() const;

-	GLfloat getMaxAnisotropy() const;

-	GLboolean getGenerateMipmap() const;

-	GLint getCropRectU() const;

-    GLint getCropRectV() const;

-    GLint getCropRectW() const;

-    GLint getCropRectH() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const = 0;

-    virtual GLsizei getHeight(GLenum target, GLint level) const = 0;

-    virtual GLenum getFormat(GLenum target, GLint level) const = 0;

-    virtual GLenum getType(GLenum target, GLint level) const = 0;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;

-	virtual int getLevelCount() const = 0;

-

-    virtual bool isSamplerComplete() const = 0;

-    virtual bool isCompressed(GLenum target, GLint level) const = 0;

-	virtual bool isDepth(GLenum target, GLint level) const = 0;

-

-    virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;

-    virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;

-    virtual egl::Image *createSharedImage(GLenum target, unsigned int level);

-    virtual bool isShared(GLenum target, unsigned int level) const = 0;

-

-    virtual void generateMipmaps() = 0;

-	virtual void autoGenerateMipmaps() = 0;

-

-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

-

-protected:

-	virtual ~Texture();

-

-    void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

-    void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

-    void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);

-    void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);

-

-	bool copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest);

-

-	bool isMipmapFiltered() const;

-

-    GLenum mMinFilter;

-    GLenum mMagFilter;

-    GLenum mWrapS;

-    GLenum mWrapT;

-	GLfloat mMaxAnisotropy;

-	GLboolean generateMipmap;

-	GLint cropRectU;

-	GLint cropRectV;

-	GLint cropRectW;

-	GLint cropRectH;

-

-	sw::Resource *resource;

-};

-

-class Texture2D : public Texture

-{

-public:

-    explicit Texture2D(GLuint name);

-

-	void addProxyRef(const Renderbuffer *proxy) override;

-    void releaseProxy(const Renderbuffer *proxy) override;

-	void sweep() override;

-

-    virtual GLenum getTarget() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const;

-    virtual GLsizei getHeight(GLenum target, GLint level) const;

-    virtual GLenum getFormat(GLenum target, GLint level) const;

-    virtual GLenum getType(GLenum target, GLint level) const;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

-	virtual int getLevelCount() const;

-

-    void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);

-    void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

-    void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-

-	void setImage(egl::Image *image);

-

-    virtual bool isSamplerComplete() const;

-    virtual bool isCompressed(GLenum target, GLint level) const;

-	virtual bool isDepth(GLenum target, GLint level) const;

-    virtual void bindTexImage(egl::Surface *surface);

-    virtual void releaseTexImage();

-

-    virtual void generateMipmaps();

-	virtual void autoGenerateMipmaps();

-

-	virtual Renderbuffer *getRenderbuffer(GLenum target);

-    virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);

-	virtual bool isShared(GLenum target, unsigned int level) const;

-

-    egl::Image *getImage(unsigned int level);

-

-protected:

-	virtual ~Texture2D();

-

-	bool isMipmapComplete() const;

-

-	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-

-    egl::Surface *mSurface;

-

-	// A specific internal reference count is kept for colorbuffer proxy references,

-    // because, as the renderbuffer acting as proxy will maintain a binding pointer

-    // back to this texture, there would be a circular reference if we used a binding

-    // pointer here. This reference count will cause the pointer to be set to NULL if

-    // the count drops to zero, but will not cause deletion of the Renderbuffer.

-    Renderbuffer *mColorbufferProxy;

-    unsigned int mProxyRefs;

-};

-

-class TextureExternal : public Texture2D

-{

-public:

-    explicit TextureExternal(GLuint name);

-

-    virtual GLenum getTarget() const;

-

-protected:

-	virtual ~TextureExternal();

-};

-}

-

-#endif   // LIBGLES_CM_TEXTURE_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Texture.h: Defines the abstract Texture class and its concrete derived
+// classes Texture2D and TextureCubeMap. Implements GL texture objects and
+// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#ifndef LIBGLES_CM_TEXTURE_H_
+#define LIBGLES_CM_TEXTURE_H_
+
+#include "Renderbuffer.h"
+#include "common/Object.hpp"
+#include "utilities.h"
+#include "libEGL/Texture.hpp"
+#include "common/debug.h"
+
+#include <GLES/gl.h>
+
+#include <vector>
+
+namespace egl
+{
+class Surface;
+class Config;
+}
+
+namespace es1
+{
+class Framebuffer;
+
+enum
+{
+	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
+	IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,
+};
+
+class Texture : public egl::Texture
+{
+public:
+	explicit Texture(GLuint name);
+
+	sw::Resource *getResource() const;
+
+	virtual void addProxyRef(const Renderbuffer *proxy) = 0;
+	virtual void releaseProxy(const Renderbuffer *proxy) = 0;
+
+	virtual GLenum getTarget() const = 0;
+
+	bool setMinFilter(GLenum filter);
+	bool setMagFilter(GLenum filter);
+	bool setWrapS(GLenum wrap);
+	bool setWrapT(GLenum wrap);
+	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);
+	void setGenerateMipmap(GLboolean enable);
+	void setCropRect(GLint u, GLint v, GLint w, GLint h);
+
+	GLenum getMinFilter() const;
+	GLenum getMagFilter() const;
+	GLenum getWrapS() const;
+	GLenum getWrapT() const;
+	GLfloat getMaxAnisotropy() const;
+	GLboolean getGenerateMipmap() const;
+	GLint getCropRectU() const;
+	GLint getCropRectV() const;
+	GLint getCropRectW() const;
+	GLint getCropRectH() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
+	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
+	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
+	virtual GLenum getType(GLenum target, GLint level) const = 0;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
+	virtual int getLevelCount() const = 0;
+
+	virtual bool isSamplerComplete() const = 0;
+	virtual bool isCompressed(GLenum target, GLint level) const = 0;
+	virtual bool isDepth(GLenum target, GLint level) const = 0;
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;
+	virtual egl::Image *createSharedImage(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const = 0;
+
+	virtual void generateMipmaps() = 0;
+	virtual void autoGenerateMipmaps() = 0;
+
+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
+
+protected:
+	virtual ~Texture();
+
+	void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
+	void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
+	void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);
+	void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);
+
+	bool copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest);
+
+	bool isMipmapFiltered() const;
+
+	GLenum mMinFilter;
+	GLenum mMagFilter;
+	GLenum mWrapS;
+	GLenum mWrapT;
+	GLfloat mMaxAnisotropy;
+	GLboolean generateMipmap;
+	GLint cropRectU;
+	GLint cropRectV;
+	GLint cropRectW;
+	GLint cropRectH;
+
+	sw::Resource *resource;
+};
+
+class Texture2D : public Texture
+{
+public:
+	explicit Texture2D(GLuint name);
+
+	void addProxyRef(const Renderbuffer *proxy) override;
+	void releaseProxy(const Renderbuffer *proxy) override;
+	void sweep() override;
+
+	virtual GLenum getTarget() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const;
+	virtual GLsizei getHeight(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const;
+	virtual GLenum getType(GLenum target, GLint level) const;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
+	virtual int getLevelCount() const;
+
+	void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+	void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+
+	void setImage(egl::Image *image);
+
+	virtual bool isSamplerComplete() const;
+	virtual bool isCompressed(GLenum target, GLint level) const;
+	virtual bool isDepth(GLenum target, GLint level) const;
+	virtual void bindTexImage(egl::Surface *surface);
+	virtual void releaseTexImage();
+
+	virtual void generateMipmaps();
+	virtual void autoGenerateMipmaps();
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target);
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const;
+
+	egl::Image *getImage(unsigned int level);
+
+protected:
+	virtual ~Texture2D();
+
+	bool isMipmapComplete() const;
+
+	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+	egl::Surface *mSurface;
+
+	// A specific internal reference count is kept for colorbuffer proxy references,
+	// because, as the renderbuffer acting as proxy will maintain a binding pointer
+	// back to this texture, there would be a circular reference if we used a binding
+	// pointer here. This reference count will cause the pointer to be set to null if
+	// the count drops to zero, but will not cause deletion of the Renderbuffer.
+	Renderbuffer *mColorbufferProxy;
+	unsigned int mProxyRefs;
+};
+
+class TextureExternal : public Texture2D
+{
+public:
+	explicit TextureExternal(GLuint name);
+
+	virtual GLenum getTarget() const;
+
+protected:
+	virtual ~TextureExternal();
+};
+}
+
+#endif   // LIBGLES_CM_TEXTURE_H_
diff --git a/src/OpenGL/libGLES_CM/VertexDataManager.cpp b/src/OpenGL/libGLES_CM/VertexDataManager.cpp
index 99e8a7f..20eb6b9 100644
--- a/src/OpenGL/libGLES_CM/VertexDataManager.cpp
+++ b/src/OpenGL/libGLES_CM/VertexDataManager.cpp
@@ -1,328 +1,331 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#include "VertexDataManager.h"

-

-#include "Buffer.h"

-#include "IndexDataManager.h"

-#include "common/debug.h"

-

-#include <algorithm>

-

-namespace

-{

-    enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};

-}

-

-namespace es1

-{

-

-VertexDataManager::VertexDataManager(Context *context) : mContext(context)

-{

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        mDirtyCurrentValue[i] = true;

-        mCurrentValueBuffer[i] = NULL;

-    }

-

-    mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming vertex buffer.");

-    }

-}

-

-VertexDataManager::~VertexDataManager()

-{

-    delete mStreamingBuffer;

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        delete mCurrentValueBuffer[i];

-    }

-}

-

-unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)

-{

-    Buffer *buffer = attribute.mBoundBuffer;

-

-    int inputStride = attribute.stride();

-    int elementSize = attribute.typeSize();

-    unsigned int streamOffset = 0;

-

-    char *output = nullptr;

-

-    if(vertexBuffer)

-    {

-        output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);

-    }

-

-    if(!output)

-    {

-        ERR("Failed to map vertex buffer.");

-        return ~0u;

-    }

-

-    const char *input = nullptr;

-

-    if(buffer)

-    {

-        int offset = attribute.mOffset;

-

-        input = static_cast<const char*>(buffer->data()) + offset;

-    }

-    else

-    {

-        input = static_cast<const char*>(attribute.mPointer);

-    }

-

-    input += inputStride * start;

-

-    if(inputStride == elementSize)

-    {

-        memcpy(output, input, count * inputStride);

-    }

-    else

-    {

-		for(int i = 0; i < count; i++)

-		{

-			memcpy(output, input, elementSize);

-			output += elementSize;

-			input += inputStride;

-		}

-    }

-

-    vertexBuffer->unmap();

-

-    return streamOffset;

-}

-

-GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-    const VertexAttributeArray &attribs = mContext->getVertexAttributes();

-

-    // Determine the required storage size per used buffer

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        if(attribs[i].mArrayEnabled)

-        {

-            if(!attribs[i].mBoundBuffer)

-            {

-                mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);

-            }

-        }

-    }

-

-    mStreamingBuffer->reserveRequiredSpace();

-

-    // Perform the vertex data translations

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        if(attribs[i].mArrayEnabled)

-        {

-            Buffer *buffer = attribs[i].mBoundBuffer;

-

-            if(!buffer && attribs[i].mPointer == NULL)

-            {

-                // This is an application error that would normally result in a crash, but we catch it and return an error

-                ERR("An enabled vertex array has no buffer and no pointer.");

-                return GL_INVALID_OPERATION;

-            }

-

-            sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-            if(staticBuffer)

-            {

-				translated[i].vertexBuffer = staticBuffer;

-				translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;

-				translated[i].stride = attribs[i].stride();

-            }

-            else

-            {

-                unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);

-

-				if(streamOffset == ~0u)

-				{

-					return GL_OUT_OF_MEMORY;

-				}

-

-				translated[i].vertexBuffer = mStreamingBuffer->getResource();

-				translated[i].offset = streamOffset;

-				translated[i].stride = attribs[i].typeSize();

-            }

-

-			switch(attribs[i].mType)

-			{

-			case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;

-			case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;

-			case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;

-			case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;

-			case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;

-			case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;

-			case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;

-			case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-			default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-			}

-

-			translated[i].count = attribs[i].mSize;

-			translated[i].normalized = attribs[i].mNormalized;

-        }

-        else

-        {

-            if(mDirtyCurrentValue[i])

-            {

-                delete mCurrentValueBuffer[i];

-                mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);

-                mDirtyCurrentValue[i] = false;

-            }

-

-            translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();

-

-            translated[i].type = sw::STREAMTYPE_FLOAT;

-			translated[i].count = 4;

-            translated[i].stride = 0;

-            translated[i].offset = 0;

-        }

-    }

-

-    return GL_NO_ERROR;

-}

-

-VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(NULL)

-{

-    if(size > 0)

-    {

-        mVertexBuffer = new sw::Resource(size + 1024);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", size);

-        }

-    }

-}

-

-VertexBuffer::~VertexBuffer()

-{

-    if(mVertexBuffer)

-    {

-        mVertexBuffer->destruct();

-    }

-}

-

-void VertexBuffer::unmap()

-{

-    if(mVertexBuffer)

-    {

-		mVertexBuffer->unlock();

-    }

-}

-

-sw::Resource *VertexBuffer::getResource() const

-{

-    return mVertexBuffer;

-}

-

-ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))

-{

-    if(mVertexBuffer)

-    {

-		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);

-

-        vector[0] = x;

-        vector[1] = y;

-        vector[2] = z;

-        vector[3] = w;

-

-        mVertexBuffer->unlock();

-    }

-}

-

-ConstantVertexBuffer::~ConstantVertexBuffer()

-{

-}

-

-StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)

-{

-    mBufferSize = size;

-    mWritePosition = 0;

-    mRequiredSpace = 0;

-}

-

-StreamingVertexBuffer::~StreamingVertexBuffer()

-{

-}

-

-void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)

-{

-    mRequiredSpace += requiredSpace;

-}

-

-void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mVertexBuffer)

-    {

-		// We can use a private lock because we never overwrite the content

-		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingVertexBuffer::reserveRequiredSpace()

-{

-    if(mRequiredSpace > mBufferSize)

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-            mVertexBuffer = 0;

-        }

-

-        mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.

-

-		mVertexBuffer = new sw::Resource(mBufferSize);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-			mVertexBuffer = new sw::Resource(mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-

-    mRequiredSpace = 0;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#include "VertexDataManager.h"
+
+#include "Buffer.h"
+#include "IndexDataManager.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+namespace
+{
+	enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};
+}
+
+namespace es1
+{
+
+VertexDataManager::VertexDataManager(Context *context) : mContext(context)
+{
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mDirtyCurrentValue[i] = true;
+		mCurrentValueBuffer[i] = nullptr;
+	}
+
+	mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming vertex buffer.");
+	}
+}
+
+VertexDataManager::~VertexDataManager()
+{
+	delete mStreamingBuffer;
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		delete mCurrentValueBuffer[i];
+	}
+}
+
+unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
+{
+	Buffer *buffer = attribute.mBoundBuffer;
+
+	int inputStride = attribute.stride();
+	int elementSize = attribute.typeSize();
+	unsigned int streamOffset = 0;
+
+	char *output = nullptr;
+
+	if(vertexBuffer)
+	{
+		output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);
+	}
+
+	if(!output)
+	{
+		ERR("Failed to map vertex buffer.");
+		return ~0u;
+	}
+
+	const char *input = nullptr;
+
+	if(buffer)
+	{
+		int offset = attribute.mOffset;
+
+		input = static_cast<const char*>(buffer->data()) + offset;
+	}
+	else
+	{
+		input = static_cast<const char*>(attribute.mPointer);
+	}
+
+	input += inputStride * start;
+
+	if(inputStride == elementSize)
+	{
+		memcpy(output, input, count * inputStride);
+	}
+	else
+	{
+		for(int i = 0; i < count; i++)
+		{
+			memcpy(output, input, elementSize);
+			output += elementSize;
+			input += inputStride;
+		}
+	}
+
+	vertexBuffer->unmap();
+
+	return streamOffset;
+}
+
+GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	const VertexAttributeArray &attribs = mContext->getVertexAttributes();
+
+	// Determine the required storage size per used buffer
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(attribs[i].mArrayEnabled)
+		{
+			if(!attribs[i].mBoundBuffer)
+			{
+				mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);
+			}
+		}
+	}
+
+	mStreamingBuffer->reserveRequiredSpace();
+
+	// Perform the vertex data translations
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(attribs[i].mArrayEnabled)
+		{
+			Buffer *buffer = attribs[i].mBoundBuffer;
+
+			if(!buffer && attribs[i].mPointer == nullptr)
+			{
+				// This is an application error that would normally result in a crash, but we catch it and return an error
+				ERR("An enabled vertex array has no buffer and no pointer.");
+				return GL_INVALID_OPERATION;
+			}
+
+			sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr;
+
+			if(staticBuffer)
+			{
+				translated[i].vertexBuffer = staticBuffer;
+				translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;
+				translated[i].stride = attribs[i].stride();
+			}
+			else
+			{
+				unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
+
+				if(streamOffset == ~0u)
+				{
+					return GL_OUT_OF_MEMORY;
+				}
+
+				translated[i].vertexBuffer = mStreamingBuffer->getResource();
+				translated[i].offset = streamOffset;
+				translated[i].stride = attribs[i].typeSize();
+			}
+
+			switch(attribs[i].mType)
+			{
+			case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;
+			case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;
+			case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;
+			case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;
+			case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;
+			case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;
+			case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;
+			case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+			default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+			}
+
+			translated[i].count = attribs[i].mSize;
+			translated[i].normalized = attribs[i].mNormalized;
+		}
+		else
+		{
+			if(mDirtyCurrentValue[i])
+			{
+				delete mCurrentValueBuffer[i];
+				mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
+				mDirtyCurrentValue[i] = false;
+			}
+
+			translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();
+
+			translated[i].type = sw::STREAMTYPE_FLOAT;
+			translated[i].count = 4;
+			translated[i].stride = 0;
+			translated[i].offset = 0;
+		}
+	}
+
+	return GL_NO_ERROR;
+}
+
+VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(nullptr)
+{
+	if(size > 0)
+	{
+		mVertexBuffer = new sw::Resource(size + 1024);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", size);
+		}
+	}
+}
+
+VertexBuffer::~VertexBuffer()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->destruct();
+	}
+}
+
+void VertexBuffer::unmap()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->unlock();
+	}
+}
+
+sw::Resource *VertexBuffer::getResource() const
+{
+	return mVertexBuffer;
+}
+
+ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))
+{
+	if(mVertexBuffer)
+	{
+		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);
+
+		vector[0] = x;
+		vector[1] = y;
+		vector[2] = z;
+		vector[3] = w;
+
+		mVertexBuffer->unlock();
+	}
+}
+
+ConstantVertexBuffer::~ConstantVertexBuffer()
+{
+}
+
+StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)
+{
+	mBufferSize = size;
+	mWritePosition = 0;
+	mRequiredSpace = 0;
+}
+
+StreamingVertexBuffer::~StreamingVertexBuffer()
+{
+}
+
+void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)
+{
+	mRequiredSpace += requiredSpace;
+}
+
+void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = nullptr;
+
+	if(mVertexBuffer)
+	{
+		// We can use a private lock because we never overwrite the content
+		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingVertexBuffer::reserveRequiredSpace()
+{
+	if(mRequiredSpace > mBufferSize)
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = 0;
+		}
+
+		mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
+
+		mVertexBuffer = new sw::Resource(mBufferSize);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = new sw::Resource(mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+
+	mRequiredSpace = 0;
+}
+
+}
diff --git a/src/OpenGL/libGLES_CM/VertexDataManager.h b/src/OpenGL/libGLES_CM/VertexDataManager.h
index cce6865..55ab849 100644
--- a/src/OpenGL/libGLES_CM/VertexDataManager.h
+++ b/src/OpenGL/libGLES_CM/VertexDataManager.h
@@ -1,98 +1,101 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#ifndef LIBGLES_CM_VERTEXDATAMANAGER_H_

-#define LIBGLES_CM_VERTEXDATAMANAGER_H_

-

-#include "Context.h"

-#include "Device.hpp"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-

-struct TranslatedAttribute

-{

-    sw::StreamType type;

-	int count;

-	bool normalized;

-

-    unsigned int offset;

-    unsigned int stride;   // 0 means not to advance the read pointer at all

-

-    sw::Resource *vertexBuffer;

-};

-

-class VertexBuffer

-{

-  public:

-    VertexBuffer(unsigned int size);

-    virtual ~VertexBuffer();

-

-    void unmap();

-

-    sw::Resource *getResource() const;

-

-  protected:

-    sw::Resource *mVertexBuffer;

-};

-

-class ConstantVertexBuffer : public VertexBuffer

-{

-  public:

-    ConstantVertexBuffer(float x, float y, float z, float w);

-    ~ConstantVertexBuffer();

-};

-

-class StreamingVertexBuffer : public VertexBuffer

-{

-  public:

-    StreamingVertexBuffer(unsigned int size);

-    ~StreamingVertexBuffer();

-

-    void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);

-    void reserveRequiredSpace();

-    void addRequiredSpace(unsigned int requiredSpace);

-

-  protected:

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-    unsigned int mRequiredSpace;

-};

-

-class VertexDataManager

-{

-  public:

-    VertexDataManager(Context *context);

-    virtual ~VertexDataManager();

-

-    void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }

-

-    GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);

-

-  private:

-    unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);

-

-    Context *const mContext;

-

-    StreamingVertexBuffer *mStreamingBuffer;

-

-    bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];

-    ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];

-};

-

-}

-

-#endif   // LIBGLES_CM_VERTEXDATAMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#ifndef LIBGLES_CM_VERTEXDATAMANAGER_H_
+#define LIBGLES_CM_VERTEXDATAMANAGER_H_
+
+#include "Context.h"
+#include "Device.hpp"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+
+struct TranslatedAttribute
+{
+	sw::StreamType type;
+	int count;
+	bool normalized;
+
+	unsigned int offset;
+	unsigned int stride;   // 0 means not to advance the read pointer at all
+
+	sw::Resource *vertexBuffer;
+};
+
+class VertexBuffer
+{
+public:
+	VertexBuffer(unsigned int size);
+	virtual ~VertexBuffer();
+
+	void unmap();
+
+	sw::Resource *getResource() const;
+
+protected:
+	sw::Resource *mVertexBuffer;
+};
+
+class ConstantVertexBuffer : public VertexBuffer
+{
+public:
+	ConstantVertexBuffer(float x, float y, float z, float w);
+	~ConstantVertexBuffer();
+};
+
+class StreamingVertexBuffer : public VertexBuffer
+{
+public:
+	StreamingVertexBuffer(unsigned int size);
+	~StreamingVertexBuffer();
+
+	void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);
+	void reserveRequiredSpace();
+	void addRequiredSpace(unsigned int requiredSpace);
+
+protected:
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+	unsigned int mRequiredSpace;
+};
+
+class VertexDataManager
+{
+public:
+	VertexDataManager(Context *context);
+	virtual ~VertexDataManager();
+
+	void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
+
+	GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
+
+private:
+	unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
+
+	Context *const mContext;
+
+	StreamingVertexBuffer *mStreamingBuffer;
+
+	bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
+	ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
+};
+
+}
+
+#endif   // LIBGLES_CM_VERTEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
index 0c9dd62..1f01fb3 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -1,4770 +1,4773 @@
-// 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.

-//

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

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "Buffer.h"

-#include "Context.h"

-#include "Framebuffer.h"

-#include "Renderbuffer.h"

-#include "Texture.h"

-#include "common/debug.h"

-#include "Common/SharedLibrary.hpp"

-#include "Common/Version.h"

-

-#include <EGL/egl.h>

-#include <EGL/eglext.h>

-

-#include <GLES/gl.h>

-#include <GLES/glext.h>

-

-#include <limits>

-

-namespace es1

-{

-

-static bool validImageSize(GLint level, GLsizei width, GLsizei height)

-{

-	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)

-	{

-		return false;

-	}

-

-	return true;

-}

-

-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture)

-{

-	if(!texture)

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed != texture->isCompressed(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(format != GL_NONE_OES && format != texture->getFormat(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed)

-	{

-		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-		   (height % 4 != 0 && height != texture->getHeight(target, 0)))

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-	}

-

-	if(xoffset + width > texture->getWidth(target, level) ||

-	   yoffset + height > texture->getHeight(target, level))

-	{

-		return error(GL_INVALID_VALUE, false);

-	}

-

-	return true;

-}

-

-void ActiveTexture(GLenum texture)

-{

-	TRACE("(GLenum texture = 0x%X)", texture);

-

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

-

-	if(context)

-	{

-		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		context->setActiveSampler(texture - GL_TEXTURE0);

-	}

-}

-

-void AlphaFunc(GLenum func, GLclampf ref)

-{

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

-

-	switch(func)

-	{

-	case GL_NEVER:

-	case GL_ALWAYS:

-	case GL_LESS:

-	case GL_LEQUAL:

-	case GL_EQUAL:

-	case GL_GEQUAL:

-	case GL_GREATER:

-	case GL_NOTEQUAL:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setAlphaFunc(func, clamp01(ref));

-	}

-}

-

-void AlphaFuncx(GLenum func, GLclampx ref)

-{

-	AlphaFunc(func, (float)ref / 0x10000);

-}

-

-void BindBuffer(GLenum target, GLuint buffer)

-{

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

-

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

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			context->bindArrayBuffer(buffer);

-			return;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			context->bindElementArrayBuffer(buffer);

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void BindFramebuffer(GLenum target, GLuint framebuffer)

-{

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

-

-	if(target != GL_FRAMEBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->bindFramebuffer(framebuffer);

-	}

-}

-

-void BindFramebufferOES(GLenum target, GLuint framebuffer)

-{

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

-

-	if(target != GL_FRAMEBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->bindFramebuffer(framebuffer);

-	}

-}

-

-void BindRenderbufferOES(GLenum target, GLuint renderbuffer)

-{

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

-

-	if(target != GL_RENDERBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))

-		{

-			// [OpenGL ES 2.0.25] Section 4.4.3 page 112

-			// [OpenGL ES 3.0.2] Section 4.4.2 page 201

-			// 'renderbuffer' must be either zero or the name of an existing renderbuffer object of

-			// type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->bindRenderbuffer(renderbuffer);

-	}

-}

-

-void BindTexture(GLenum target, GLuint texture)

-{

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

-

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

-

-	if(context)

-	{

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

-

-		if(textureObject && textureObject->getTarget() != target && texture != 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			context->bindTexture2D(texture);

-			return;

-		case GL_TEXTURE_EXTERNAL_OES:

-			context->bindTextureExternal(texture);

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);

-

-void BlendEquationOES(GLenum mode)

-{

-	BlendEquationSeparateOES(mode, mode);

-}

-

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)

-{

-	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);

-

-	switch(modeRGB)

-	{

-	case GL_FUNC_ADD_OES:

-	case GL_FUNC_SUBTRACT_OES:

-	case GL_FUNC_REVERSE_SUBTRACT_OES:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(modeAlpha)

-	{

-	case GL_FUNC_ADD_OES:

-	case GL_FUNC_SUBTRACT_OES:

-	case GL_FUNC_REVERSE_SUBTRACT_OES:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setBlendEquation(modeRGB, modeAlpha);

-	}

-}

-

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

-

-void BlendFunc(GLenum sfactor, GLenum dfactor)

-{

-	BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);

-}

-

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

-{

-	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",

-		  srcRGB, dstRGB, srcAlpha, dstAlpha);

-

-	switch(srcRGB)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_SRC_ALPHA_SATURATE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(dstRGB)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(srcAlpha)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_SRC_ALPHA_SATURATE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(dstAlpha)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)

-{

-	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications

-

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

-	      target, size, data, usage);

-

-	if(size < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(usage)

-	{

-	case GL_STATIC_DRAW:

-	case GL_DYNAMIC_DRAW:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		es1::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-	}

-}

-

-void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)

-{

-	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications

-	offset = static_cast<GLint>(offset);

-

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

-	      target, offset, size, data);

-

-	if(size < 0 || offset < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(data == NULL)

-	{

-		return;

-	}

-

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

-

-	if(context)

-	{

-		es1::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if((size_t)size + offset > buffer->size())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

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

-	}

-}

-

-GLenum CheckFramebufferStatusOES(GLenum target)

-{

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

-

-	if(target != GL_FRAMEBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM, 0);

-	}

-

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

-

-	if(context)

-	{

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

-

-		return framebuffer->completeness();

-	}

-

-	return 0;

-}

-

-void Clear(GLbitfield mask)

-{

-	TRACE("(GLbitfield mask = %X)", mask);

-

-	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		context->clear(mask);

-	}

-}

-

-void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",

-	      red, green, blue, alpha);

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)

-{

-	ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);

-}

-

-void ClearDepthf(GLclampf depth)

-{

-	TRACE("(GLclampf depth = %f)", depth);

-

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

-

-	if(context)

-	{

-		context->setClearDepth(depth);

-	}

-}

-

-void ClearDepthx(GLclampx depth)

-{

-	ClearDepthf((float)depth / 0x10000);

-}

-

-void ClearStencil(GLint s)

-{

-	TRACE("(GLint s = %d)", s);

-

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

-

-	if(context)

-	{

-		context->setClearStencil(s);

-	}

-}

-

-void ClientActiveTexture(GLenum texture)

-{

-	TRACE("(GLenum texture = 0x%X)", texture);

-

-	switch(texture)

-	{

-	case GL_TEXTURE0:

-	case GL_TEXTURE1:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->clientActiveTexture(texture);

-	}

-}

-

-void ClipPlanef(GLenum plane, const GLfloat *equation)

-{

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

-

-	int index = plane - GL_CLIP_PLANE0;

-

-	if(index < 0 || index >= MAX_CLIP_PLANES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setClipPlane(index, equation);

-	}

-}

-

-void ClipPlanex(GLenum plane, const GLfixed *equation)

-{

-	GLfloat equationf[4] =

-	{

-		(float)equation[0] / 0x10000,

-		(float)equation[1] / 0x10000,

-		(float)equation[2] / 0x10000,

-		(float)equation[3] / 0x10000,

-	};

-

-	ClipPlanef(plane, equationf);

-}

-

-void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)

-{

-	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)

-{

-	Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF);

-}

-

-void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)

-{

-	Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);

-}

-

-void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)

-{

-	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",

-	      red, green, blue, alpha);

-

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

-

-	if(context)

-	{

-		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);

-	}

-}

-

-void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)

-{

-	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "

-	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",

-	      index, size, type, normalized, stride, ptr);

-

-	if(index >= es1::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(size < 1 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(type)

-	{

-	case GL_BYTE:

-	case GL_UNSIGNED_BYTE:

-	case GL_SHORT:

-	case GL_UNSIGNED_SHORT:

-	case GL_FIXED:

-	case GL_FLOAT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(stride < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);

-	}

-}

-

-void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

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

-

-	if(size != 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-}

-

-void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                          GLint border, GLsizei imageSize, const GLvoid* data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "

-	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",

-	      target, level, internalformat, width, height, border, imageSize, data);

-

-	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!validImageSize(level, width, height) || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(internalformat)

-	{

-	case GL_ETC1_RGB8_OES:

-		break;

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		if(!S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_DEPTH_COMPONENT16_OES:

-	case GL_DEPTH_COMPONENT32_OES:

-	case GL_DEPTH_STENCIL_OES:

-	case GL_DEPTH24_STENCIL8_OES:

-		return error(GL_INVALID_OPERATION);

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                             GLenum format, GLsizei imageSize, const GLvoid* data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "

-	      "GLsizei imageSize = %d, const GLvoid* data = %p)",

-	      target, level, xoffset, yoffset, width, height, format, imageSize, data);

-

-	if(!es1::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(format)

-	{

-	case GL_ETC1_RGB8_OES:

-		break;

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		if(!S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width == 0 || height == 0 || !data)

-	{

-		return;

-	}

-

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

-

-	if(context)

-	{

-		if(imageSize != egl::ComputeCompressedSize(width, height, format))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(xoffset % 4 != 0 || yoffset % 4 != 0)

-		{

-			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))

-			{

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

-			}

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "

-	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",

-	      target, level, internalformat, x, y, width, height, border);

-

-	if(!validImageSize(level, width, height))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

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

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-		}

-

-		if(context->getFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-		GLenum colorbufferFormat = source->getFormat();

-

-		// [OpenGL ES 2.0.24] table 3.9

-		switch(internalformat)

-		{

-		case GL_ALPHA:

-			if(colorbufferFormat != GL_ALPHA &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4_OES &&

-			   colorbufferFormat != GL_RGB5_A1_OES &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE:

-		case GL_RGB:

-			if(colorbufferFormat != GL_RGB &&

-			   colorbufferFormat != GL_RGB565_OES &&

-			   colorbufferFormat != GL_RGB8_OES &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4_OES &&

-			   colorbufferFormat != GL_RGB5_A1_OES &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE_ALPHA:

-		case GL_RGBA:

-			if(colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4_OES &&

-			   colorbufferFormat != GL_RGB5_A1_OES &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_ETC1_RGB8_OES:

-			return error(GL_INVALID_OPERATION);

-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-			if(S3TC_SUPPORT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",

-	      target, level, xoffset, yoffset, x, y, width, height);

-

-	if(!es1::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(width == 0 || height == 0)

-	{

-		return;

-	}

-

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

-

-	if(context)

-	{

-

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

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-		}

-

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

-

-		if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		es1::Texture *texture = NULL;

-

-		if(target == GL_TEXTURE_2D)

-		{

-			texture = context->getTexture2D();

-		}

-		else UNREACHABLE(target);

-

-		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture))

-		{

-			return;

-		}

-

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

-	}

-}

-

-void CullFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		{

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

-

-			if(context)

-			{

-				context->setCullMode(mode);

-			}

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void DeleteBuffers(GLsizei n, const GLuint* buffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteBuffer(buffers[i]);

-		}

-	}

-}

-

-void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			if(framebuffers[i] != 0)

-			{

-				context->deleteFramebuffer(framebuffers[i]);

-			}

-		}

-	}

-}

-

-void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteRenderbuffer(renderbuffers[i]);

-		}

-	}

-}

-

-void DeleteTextures(GLsizei n, const GLuint* textures)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			if(textures[i] != 0)

-			{

-				context->deleteTexture(textures[i]);

-			}

-		}

-	}

-}

-

-void DepthFunc(GLenum func)

-{

-	TRACE("(GLenum func = 0x%X)", func);

-

-	switch(func)

-	{

-	case GL_NEVER:

-	case GL_ALWAYS:

-	case GL_LESS:

-	case GL_LEQUAL:

-	case GL_EQUAL:

-	case GL_GREATER:

-	case GL_GEQUAL:

-	case GL_NOTEQUAL:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setDepthFunc(func);

-	}

-}

-

-void DepthMask(GLboolean flag)

-{

-	TRACE("(GLboolean flag = %d)", flag);

-

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

-

-	if(context)

-	{

-		context->setDepthMask(flag != GL_FALSE);

-	}

-}

-

-void DepthRangef(GLclampf zNear, GLclampf zFar)

-{

-	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);

-

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

-

-	if(context)

-	{

-		context->setDepthRange(zNear, zFar);

-	}

-}

-

-void DepthRangex(GLclampx zNear, GLclampx zFar)

-{

-	DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);

-}

-

-void Disable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

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

-

-	if(context)

-	{

-		switch(cap)

-		{

-		case GL_CULL_FACE:                context->setCullFaceEnabled(false);              break;

-		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(false);     break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;

-		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(false);        break;

-		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(false);           break;

-		case GL_STENCIL_TEST:             context->setStencilTestEnabled(false);           break;

-		case GL_DEPTH_TEST:               context->setDepthTestEnabled(false);             break;

-		case GL_BLEND:                    context->setBlendEnabled(false);                 break;

-		case GL_DITHER:                   context->setDitherEnabled(false);                break;

-		case GL_LIGHTING:                 context->setLightingEnabled(false);              break;

-		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;

-		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;

-		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;

-		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;

-		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;

-		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;

-		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;

-		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;

-		case GL_FOG:                      context->setFogEnabled(false);                   break;

-		case GL_TEXTURE_2D:               context->setTexture2Denabled(false);             break;

-		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(false);       break;

-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;

-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;

-		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(false);           break;

-		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(false);            break;

-		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;

-		case GL_NORMALIZE:                context->setNormalizeEnabled(false);             break;

-		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(false);         break;

-		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(false);           break;

-		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(false);           break;

-		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(false);            break;

-		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(false);        break;

-		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(false);     break;

-		case GL_MULTISAMPLE:              context->setMultisampleEnabled(false);           break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(false);      break;

-		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, false);          break;

-		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, false);          break;

-		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, false);          break;

-		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, false);          break;

-		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, false);          break;

-		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, false);          break;

-		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(false);           break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void DisableClientState(GLenum array)

-{

-	TRACE("(GLenum array = 0x%X)", array);

-

-	switch(array)

-	{

-	case GL_VERTEX_ARRAY:

-	case GL_NORMAL_ARRAY:

-	case GL_COLOR_ARRAY:

-	case GL_POINT_SIZE_ARRAY_OES:

-	case GL_TEXTURE_COORD_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-

-		switch(array)

-		{

-		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, false);                            break;

-		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;

-		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;

-		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false);                           break;

-		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;

-		default:                      UNREACHABLE(array);

-		}

-	}

-}

-

-void DrawArrays(GLenum mode, GLint first, GLsizei count)

-{

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

-

-	if(count < 0 || first < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		context->drawArrays(mode, first, count);

-	}

-}

-

-void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)

-{

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

-	      mode, count, type, indices);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT:

-		case GL_UNSIGNED_INT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

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

-	}

-}

-

-void Enable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

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

-

-	if(context)

-	{

-		switch(cap)

-		{

-		case GL_CULL_FACE:                context->setCullFaceEnabled(true);              break;

-		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(true);     break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;

-		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(true);        break;

-		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(true);           break;

-		case GL_STENCIL_TEST:             context->setStencilTestEnabled(true);           break;

-		case GL_DEPTH_TEST:               context->setDepthTestEnabled(true);             break;

-		case GL_BLEND:                    context->setBlendEnabled(true);                 break;

-		case GL_DITHER:                   context->setDitherEnabled(true);                break;

-		case GL_LIGHTING:                 context->setLightingEnabled(true);              break;

-		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;

-		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;

-		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;

-		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;

-		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;

-		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;

-		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;

-		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;

-		case GL_FOG:                      context->setFogEnabled(true);                   break;

-		case GL_TEXTURE_2D:               context->setTexture2Denabled(true);             break;

-		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(true);       break;

-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;

-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;

-		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(true);           break;

-		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(true);            break;

-		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;

-		case GL_NORMALIZE:                context->setNormalizeEnabled(true);             break;

-		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(true);         break;

-		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(true);           break;

-		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(true);           break;

-		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(true);            break;

-		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(true);        break;

-		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(true);     break;

-		case GL_MULTISAMPLE:              context->setMultisampleEnabled(true);           break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(true);      break;

-		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, true);          break;

-		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, true);          break;

-		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, true);          break;

-		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, true);          break;

-		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, true);          break;

-		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, true);          break;

-		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(true);           break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void EnableClientState(GLenum array)

-{

-	TRACE("(GLenum array = 0x%X)", array);

-

-	switch(array)

-	{

-	case GL_VERTEX_ARRAY:

-	case GL_NORMAL_ARRAY:

-	case GL_COLOR_ARRAY:

-	case GL_POINT_SIZE_ARRAY_OES:

-	case GL_TEXTURE_COORD_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-

-		switch(array)

-		{

-		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, true);                            break;

-		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;

-		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;

-		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true);                           break;

-		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;

-		default:                      UNREACHABLE(array);

-		}

-	}

-}

-

-void Finish(void)

-{

-	TRACE("()");

-

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

-

-	if(context)

-	{

-		context->finish();

-	}

-}

-

-void Flush(void)

-{

-	TRACE("()");

-

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

-

-	if(context)

-	{

-		context->flush();

-	}

-}

-

-void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "

-	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);

-

-	if(target != GL_FRAMEBUFFER_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

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

-		GLuint framebufferName = context->getFramebufferName();

-

-		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0_OES:

-			framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer);

-			break;

-		case GL_DEPTH_ATTACHMENT_OES:

-			framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer);

-			break;

-		case GL_STENCIL_ATTACHMENT_OES:

-			framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "

-	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);

-

-	if(target != GL_FRAMEBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(attachment)

-	{

-	case GL_COLOR_ATTACHMENT0_OES:

-	case GL_DEPTH_ATTACHMENT_OES:

-	case GL_STENCIL_ATTACHMENT_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		if(texture == 0)

-		{

-			textarget = GL_NONE_OES;

-		}

-		else

-		{

-			es1::Texture *tex = context->getTexture(texture);

-

-			if(tex == NULL)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			if(tex->isCompressed(textarget, level))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			switch(textarget)

-			{

-			case GL_TEXTURE_2D:

-				if(tex->getTarget() != GL_TEXTURE_2D)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(level != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

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

-		GLuint framebufferName = context->getFramebufferName();

-

-		if(framebufferName == 0 || !framebuffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0_OES:  framebuffer->setColorbuffer(textarget, texture);   break;

-		case GL_DEPTH_ATTACHMENT_OES:   framebuffer->setDepthbuffer(textarget, texture);   break;

-		case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break;

-		}

-	}

-}

-

-void Fogf(GLenum pname, GLfloat param)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_FOG_MODE:

-			switch((GLenum)param)

-			{

-			case GL_LINEAR:

-			case GL_EXP:

-			case GL_EXP2:

-				context->setFogMode((GLenum)param);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FOG_DENSITY:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setFogDensity(param);

-			break;

-		case GL_FOG_START:

-			context->setFogStart(param);

-			break;

-		case GL_FOG_END:

-			context->setFogEnd(param);

-			break;

-		case GL_FOG_COLOR:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glFogfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Fogfv(GLenum pname, const GLfloat *params)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_FOG_MODE:

-			switch((GLenum)params[0])

-			{

-			case GL_LINEAR:

-			case GL_EXP:

-			case GL_EXP2:

-				context->setFogMode((GLenum)params[0]);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FOG_DENSITY:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setFogDensity(params[0]);

-			break;

-		case GL_FOG_START:

-			context->setFogStart(params[0]);

-			break;

-		case GL_FOG_END:

-			context->setFogEnd(params[0]);

-			break;

-		case GL_FOG_COLOR:

-			context->setFogColor(params[0], params[1], params[2], params[3]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Fogx(GLenum pname, GLfixed param)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_FOG_MODE:

-			switch((GLenum)param)

-			{

-			case GL_LINEAR:

-			case GL_EXP:

-			case GL_EXP2:

-				context->setFogMode((GLenum)param);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FOG_DENSITY:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setFogDensity((float)param / 0x10000);

-			break;

-		case GL_FOG_START:

-			context->setFogStart((float)param / 0x10000);

-			break;

-		case GL_FOG_END:

-			context->setFogEnd((float)param / 0x10000);

-			break;

-		case GL_FOG_COLOR:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glFogxv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Fogxv(GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void FrontFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_CW:

-	case GL_CCW:

-		{

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

-

-			if(context)

-			{

-				context->setFrontFace(mode);

-			}

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);

-

-	if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);

-}

-

-void GenerateMipmapOES(GLenum target)

-{

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

-

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

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->generateMipmaps();

-	}

-}

-

-void GenBuffers(GLsizei n, GLuint* buffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			buffers[i] = context->createBuffer();

-		}

-	}

-}

-

-void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			framebuffers[i] = context->createFramebuffer();

-		}

-	}

-}

-

-void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			renderbuffers[i] = context->createRenderbuffer();

-		}

-	}

-}

-

-void GenTextures(GLsizei n, GLuint* textures)

-{

-	TRACE("(GLsizei n = %d, GLuint* textures =  %p)", n, textures);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			textures[i] = context->createTexture();

-		}

-	}

-}

-

-void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)

-{

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

-

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

-

-	if(context)

-	{

-		if(target != GL_RENDERBUFFER_OES)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(context->getRenderbufferName() == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-

-		switch(pname)

-		{

-		case GL_RENDERBUFFER_WIDTH_OES:           *params = renderbuffer->getWidth();       break;

-		case GL_RENDERBUFFER_HEIGHT_OES:          *params = renderbuffer->getHeight();      break;

-		case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: *params = renderbuffer->getFormat();      break;

-		case GL_RENDERBUFFER_RED_SIZE_OES:        *params = renderbuffer->getRedSize();     break;

-		case GL_RENDERBUFFER_GREEN_SIZE_OES:      *params = renderbuffer->getGreenSize();   break;

-		case GL_RENDERBUFFER_BLUE_SIZE_OES:       *params = renderbuffer->getBlueSize();    break;

-		case GL_RENDERBUFFER_ALPHA_SIZE_OES:      *params = renderbuffer->getAlphaSize();   break;

-		case GL_RENDERBUFFER_DEPTH_SIZE_OES:      *params = renderbuffer->getDepthSize();   break;

-		case GL_RENDERBUFFER_STENCIL_SIZE_OES:    *params = renderbuffer->getStencilSize(); break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetBooleanv(GLenum pname, GLboolean* params)

-{

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

-

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

-

-	if(context)

-	{

-		if(!(context->getBooleanv(pname, params)))

-		{

-			int numParams = context->getQueryParameterNum(pname);

-

-			if(numParams < 0)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(numParams == 0)

-			{

-				return;

-			}

-

-			if(context->isQueryParameterFloat(pname))

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(floatParams[i] == 0.0f)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] floatParams;

-			}

-			else if(context->isQueryParameterInt(pname))

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(intParams[i] == 0)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] intParams;

-			}

-			else UNREACHABLE(pname);

-		}

-	}

-}

-

-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

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

-

-	if(context)

-	{

-		es1::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_BUFFER_USAGE:

-			*params = buffer->usage();

-			break;

-		case GL_BUFFER_SIZE:

-			*params = buffer->size();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetClipPlanef(GLenum pname, GLfloat eqn[4])

-{

-	UNIMPLEMENTED();

-}

-

-void GetClipPlanex(GLenum pname, GLfixed eqn[4])

-{

-	UNIMPLEMENTED();

-}

-

-GLenum GetError(void)

-{

-	TRACE("()");

-

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

-

-	if(context)

-	{

-		return context->getError();

-	}

-

-	return GL_NO_ERROR;

-}

-

-void GetFixedv(GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetFloatv(GLenum pname, GLfloat* params)

-{

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

-

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

-

-	if(context)

-	{

-		if(!(context->getFloatv(pname, params)))

-		{

-			int numParams = context->getQueryParameterNum(pname);

-

-			if(numParams < 0)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(numParams == 0)

-			{

-				return;

-			}

-

-			if(context->isQueryParameterBool(pname))

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(boolParams[i] == GL_FALSE)

-						params[i] = 0.0f;

-					else

-						params[i] = 1.0f;

-				}

-

-				delete [] boolParams;

-			}

-			else if(context->isQueryParameterInt(pname))

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					params[i] = (GLfloat)intParams[i];

-				}

-

-				delete [] intParams;

-			}

-			else UNREACHABLE(pname);

-		}

-	}

-}

-

-void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",

-	      target, attachment, pname, params);

-

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

-

-	if(context)

-	{

-		if(target != GL_FRAMEBUFFER_OES)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(context->getFramebufferName() == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-

-		GLenum attachmentType;

-		GLuint attachmentHandle;

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0_OES:

-			attachmentType = framebuffer->getColorbufferType();

-			attachmentHandle = framebuffer->getColorbufferName();

-			break;

-		case GL_DEPTH_ATTACHMENT_OES:

-			attachmentType = framebuffer->getDepthbufferType();

-			attachmentHandle = framebuffer->getDepthbufferName();

-			break;

-		case GL_STENCIL_ATTACHMENT_OES:

-			attachmentType = framebuffer->getStencilbufferType();

-			attachmentHandle = framebuffer->getStencilbufferName();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		GLenum attachmentObjectType;   // Type category

-		if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)

-		{

-			attachmentObjectType = attachmentType;

-		}

-		else if(es1::IsTextureTarget(attachmentType))

-		{

-			attachmentObjectType = GL_TEXTURE;

-		}

-		else UNREACHABLE(attachmentType);

-

-		switch(pname)

-		{

-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:

-			*params = attachmentObjectType;

-			break;

-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:

-			if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)

-			{

-				*params = attachmentHandle;

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:

-			if(attachmentObjectType == GL_TEXTURE)

-			{

-				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetIntegerv(GLenum pname, GLint* params)

-{

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

-

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

-

-	if(context)

-	{

-		if(!(context->getIntegerv(pname, params)))

-		{

-			int numParams = context->getQueryParameterNum(pname);

-

-			if(numParams < 0)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(numParams == 0)

-			{

-				return;

-			}

-

-			if(context->isQueryParameterBool(pname))

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(boolParams[i] == GL_FALSE)

-						params[i] = 0;

-					else

-						params[i] = 1;

-				}

-

-				delete [] boolParams;

-			}

-			else if(context->isQueryParameterFloat(pname))

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)

-					{

-						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);

-					}

-					else

-					{

-						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

-					}

-				}

-

-				delete [] floatParams;

-			}

-			else UNREACHABLE(pname);

-		}

-	}

-}

-

-void GetLightfv(GLenum light, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetLightxv(GLenum light, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetPointerv(GLenum pname, GLvoid **params)

-{

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

-

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

-

-	if(context)

-	{

-		if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-const GLubyte* GetString(GLenum name)

-{

-	TRACE("(GLenum name = 0x%X)", name);

-

-	switch(name)

-	{

-	case GL_VENDOR:

-		return (GLubyte*)"TransGaming Inc.";

-	case GL_RENDERER:

-		return (GLubyte*)"Google SwiftShader";

-	case GL_VERSION:

-		return (GLubyte*)"OpenGL ES 1.1 SwiftShader " VERSION_STRING;

-	case GL_EXTENSIONS:

-		// Keep list sorted in following order:

-		// OES extensions

-		// EXT extensions

-		// Vendor extensions

-		return (GLubyte*)

-			"GL_OES_blend_equation_separate "

-			"GL_OES_blend_func_separate "

-			"GL_OES_blend_subtract "

-			"GL_OES_compressed_ETC1_RGB8_texture "

-			"GL_OES_depth_texture "

-			"GL_OES_EGL_image "

-			"GL_OES_EGL_image_external "

-			"GL_OES_EGL_sync "

-			"GL_OES_element_index_uint "

-			"GL_OES_framebuffer_object "

-			"GL_OES_packed_depth_stencil "

-			"GL_OES_read_format "

-			"GL_OES_rgb8_rgba8 "

-			"GL_OES_stencil8 "

-			"GL_OES_stencil_wrap "

-			"GL_OES_texture_mirrored_repeat "

-			"GL_OES_texture_npot "

-			"GL_EXT_blend_minmax "

-			"GL_EXT_read_format_bgra "

-			#if (S3TC_SUPPORT)

-			"GL_EXT_texture_compression_dxt1 "

-			"GL_ANGLE_texture_compression_dxt3 "

-			"GL_ANGLE_texture_compression_dxt5 "

-			#endif

-			"GL_EXT_texture_filter_anisotropic "

-			"GL_EXT_texture_format_BGRA8888";

-	default:

-		return error(GL_INVALID_ENUM, (GLubyte*)NULL);

-	}

-}

-

-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)

-{

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

-

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

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_MAG_FILTER:

-			*params = (GLfloat)texture->getMagFilter();

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			*params = (GLfloat)texture->getMinFilter();

-			break;

-		case GL_TEXTURE_WRAP_S:

-			*params = (GLfloat)texture->getWrapS();

-			break;

-		case GL_TEXTURE_WRAP_T:

-			*params = (GLfloat)texture->getWrapT();

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			*params = texture->getMaxAnisotropy();

-			break;

-		case GL_GENERATE_MIPMAP:

-			*params = (GLfloat)texture->getGenerateMipmap();

-			break;

-		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:

-			*params = (GLfloat)1;

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

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

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_MAG_FILTER:

-			*params = texture->getMagFilter();

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			*params = texture->getMinFilter();

-			break;

-		case GL_TEXTURE_WRAP_S:

-			*params = texture->getWrapS();

-			break;

-		case GL_TEXTURE_WRAP_T:

-			*params = texture->getWrapT();

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			*params = (GLint)texture->getMaxAnisotropy();

-			break;

-		case GL_GENERATE_MIPMAP:

-			*params = (GLint)texture->getGenerateMipmap();

-			break;

-		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:

-			*params = 1;

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetTexEnviv(GLenum env, GLenum pname, GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void Hint(GLenum target, GLenum mode)

-{

-	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);

-

-	switch(mode)

-	{

-	case GL_FASTEST:

-	case GL_NICEST:

-	case GL_DONT_CARE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_GENERATE_MIPMAP_HINT:

-			context->setGenerateMipmapHint(mode);

-			break;

-		case GL_PERSPECTIVE_CORRECTION_HINT:

-			context->setPerspectiveCorrectionHint(mode);

-			break;

-		case GL_FOG_HINT:

-			context->setFogHint(mode);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GLboolean IsBuffer(GLuint buffer)

-{

-	TRACE("(GLuint buffer = %d)", buffer);

-

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

-

-	if(context && buffer)

-	{

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

-

-		if(bufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsEnabled(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

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

-

-	if(context)

-	{

-		switch(cap)

-		{

-		case GL_CULL_FACE:                return context->isCullFaceEnabled();              break;

-		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();     break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;

-		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();        break;

-		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();           break;

-		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();           break;

-		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();             break;

-		case GL_BLEND:                    return context->isBlendEnabled();                 break;

-		case GL_DITHER:                   return context->isDitherEnabled();                break;

-		case GL_LIGHTING:                 return context->isLightingEnabled();              break;

-		case GL_LIGHT0:                   return context->isLightEnabled(0);                break;

-		case GL_LIGHT1:                   return context->isLightEnabled(1);                break;

-		case GL_LIGHT2:                   return context->isLightEnabled(2);                break;

-		case GL_LIGHT3:                   return context->isLightEnabled(3);                break;

-		case GL_LIGHT4:                   return context->isLightEnabled(4);                break;

-		case GL_LIGHT5:                   return context->isLightEnabled(5);                break;

-		case GL_LIGHT6:                   return context->isLightEnabled(6);                break;

-		case GL_LIGHT7:                   return context->isLightEnabled(7);                break;

-		case GL_FOG:                      return context->isFogEnabled();                   break;

-		case GL_TEXTURE_2D:               return context->isTexture2Denabled();             break;

-		case GL_TEXTURE_EXTERNAL_OES:     return context->isTextureExternalEnabled();       break;

-		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();             break;

-		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();          break;

-		case GL_POINT_SMOOTH:             return context->isPointSmoothEnabled();           break;

-		case GL_LINE_SMOOTH:              return context->isLineSmoothEnabled();            break;

-		case GL_COLOR_MATERIAL:           return context->isColorMaterialEnabled();         break;

-		case GL_NORMALIZE:                return context->isNormalizeEnabled();             break;

-		case GL_RESCALE_NORMAL:           return context->isRescaleNormalEnabled();         break;

-		case GL_VERTEX_ARRAY:             return context->isVertexArrayEnabled();           break;

-		case GL_NORMAL_ARRAY:             return context->isNormalArrayEnabled();           break;

-		case GL_COLOR_ARRAY:              return context->isColorArrayEnabled();            break;

-		case GL_POINT_SIZE_ARRAY_OES:     return context->isPointSizeArrayEnabled();        break;

-		case GL_TEXTURE_COORD_ARRAY:      return context->isTextureCoordArrayEnabled();     break;

-		case GL_MULTISAMPLE:              return context->isMultisampleEnabled();           break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      return context->isSampleAlphaToOneEnabled();      break;

-		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);            break;

-		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);            break;

-		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);            break;

-		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);            break;

-		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);            break;

-		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);            break;

-		case GL_POINT_SPRITE_OES:         return context->isPointSpriteEnabled();           break;

-		default:

-			return error(GL_INVALID_ENUM, GL_FALSE);

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsFramebufferOES(GLuint framebuffer)

-{

-	TRACE("(GLuint framebuffer = %d)", framebuffer);

-

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

-

-	if(context && framebuffer)

-	{

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

-

-		if(framebufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsTexture(GLuint texture)

-{

-	TRACE("(GLuint texture = %d)", texture);

-

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

-

-	if(context && texture)

-	{

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

-

-		if(textureObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsRenderbufferOES(GLuint renderbuffer)

-{

-	TRACE("(GLuint renderbuffer = %d)", renderbuffer);

-

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

-

-	if(context && renderbuffer)

-	{

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

-

-		if(renderbufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-void LightModelf(GLenum pname, GLfloat param)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(param != 0.0f);

-			break;

-		case GL_LIGHT_MODEL_AMBIENT:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void LightModelfv(GLenum pname, const GLfloat *params)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_AMBIENT:

-			context->setGlobalAmbient(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(params[0] != 0.0f);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void LightModelx(GLenum pname, GLfixed param)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(param != 0);

-			break;

-		case GL_LIGHT_MODEL_AMBIENT:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelxv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void LightModelxv(GLenum pname, const GLfixed *params)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_AMBIENT:

-			context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);

-			break;

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(params[0] != 0);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Lightf(GLenum light, GLenum pname, GLfloat param)

-{

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

-

-	int index = light - GL_LIGHT0;

-

-	if(index < 0 || index >= es1::MAX_LIGHTS)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_SPOT_EXPONENT:

-			if(param < 0.0f || param > 128.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightExponent(index, param);

-			break;

-		case GL_SPOT_CUTOFF:

-			if((param < 0.0f || param > 90.0f) && param != 180.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightCutoff(index, param);

-			break;

-		case GL_CONSTANT_ATTENUATION:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationConstant(index, param);

-			break;

-		case GL_LINEAR_ATTENUATION:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationLinear(index, param);

-			break;

-		case GL_QUADRATIC_ATTENUATION:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationQuadratic(index, param);

-			break;

-		case GL_AMBIENT:

-		case GL_DIFFUSE:

-		case GL_SPECULAR:

-		case GL_POSITION:

-		case GL_SPOT_DIRECTION:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glLightfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Lightfv(GLenum light, GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);

-

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

-

-	if(context)

-	{

-		int index = light - GL_LIGHT0;

-

-		if(index < 0 || index > es1::MAX_LIGHTS)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_AMBIENT:               context->setLightAmbient(index, params[0], params[1], params[2], params[3]);  break;

-		case GL_DIFFUSE:               context->setLightDiffuse(index, params[0], params[1], params[2], params[3]);  break;

-		case GL_SPECULAR:              context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;

-		case GL_POSITION:              context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;

-		case GL_SPOT_DIRECTION:        context->setLightDirection(index, params[0], params[1], params[2]);           break;

-		case GL_SPOT_EXPONENT:

-			if(params[0] < 0.0f || params[0] > 128.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightExponent(index, params[0]);

-			break;

-		case GL_SPOT_CUTOFF:

-			if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightCutoff(index, params[0]);

-			break;

-		case GL_CONSTANT_ATTENUATION:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationConstant(index, params[0]);

-			break;

-		case GL_LINEAR_ATTENUATION:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationLinear(index, params[0]);

-			break;

-		case GL_QUADRATIC_ATTENUATION:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationQuadratic(index, params[0]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Lightx(GLenum light, GLenum pname, GLfixed param)

-{

-	UNIMPLEMENTED();

-}

-

-void Lightxv(GLenum light, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void LineWidth(GLfloat width)

-{

-	TRACE("(GLfloat width = %f)", width);

-

-	if(width <= 0.0f)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		context->setLineWidth(width);

-	}

-}

-

-void LineWidthx(GLfixed width)

-{

-	LineWidth((float)width / 0x10000);

-}

-

-void LoadIdentity(void)

-{

-	TRACE("()");

-

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

-

-	if(context)

-	{

-		context->loadIdentity();

-	}

-}

-

-void LoadMatrixf(const GLfloat *m)

-{

-	TRACE("(const GLfloat *m)");

-

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

-

-	if(context)

-	{

-		context->load(m);

-	}

-}

-

-void LoadMatrixx(const GLfixed *m)

-{

-	GLfloat matrix[16] =

-	{

-		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,

-		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,

-		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,

-		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000

-	};

-

-	LoadMatrixf(matrix);

-}

-

-void LogicOp(GLenum opcode)

-{

-	TRACE("(GLenum opcode = 0x%X)", opcode);

-

-	switch(opcode)

-	{

-	case GL_CLEAR:

-	case GL_SET:

-	case GL_COPY:

-	case GL_COPY_INVERTED:

-	case GL_NOOP:

-	case GL_INVERT:

-	case GL_AND:

-	case GL_NAND:

-	case GL_OR:

-	case GL_NOR:

-	case GL_XOR:

-	case GL_EQUIV:

-	case GL_AND_REVERSE:

-	case GL_AND_INVERTED:

-	case GL_OR_REVERSE:

-	case GL_OR_INVERTED:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setLogicalOperation(opcode);

-	}

-}

-

-void Materialf(GLenum face, GLenum pname, GLfloat param)

-{

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

-

-	if(face != GL_FRONT_AND_BACK)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_SHININESS:

-			if(param < 0.0f || param > 128.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setMaterialShininess(param);

-			break;

-		case GL_AMBIENT:

-		case GL_DIFFUSE:

-		case GL_AMBIENT_AND_DIFFUSE:

-		case GL_SPECULAR:

-		case GL_EMISSION:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glMaterialfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Materialfv(GLenum face, GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);

-

-	if(face != GL_FRONT_AND_BACK)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_AMBIENT:

-			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_DIFFUSE:

-			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_AMBIENT_AND_DIFFUSE:

-			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);

-			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_SPECULAR:

-			context->setMaterialSpecular(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_EMISSION:

-			context->setMaterialEmission(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_SHININESS:

-			context->setMaterialShininess(params[0]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Materialx(GLenum face, GLenum pname, GLfixed param)

-{

-	UNIMPLEMENTED();

-}

-

-void Materialxv(GLenum face, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void MatrixMode(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

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

-

-	if(context)

-	{

-		context->setMatrixMode(mode);

-	}

-}

-

-void MultMatrixf(const GLfloat *m)

-{

-	TRACE("(const GLfloat *m)");

-

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

-

-	if(context)

-	{

-		context->multiply(m);

-	}

-}

-

-void MultMatrixx(const GLfixed *m)

-{

-	GLfloat matrix[16] =

-	{

-		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,

-		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,

-		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,

-		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000

-	};

-

-	MultMatrixf(matrix);

-}

-

-void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)

-{

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

-

-	switch(target)

-	{

-	case GL_TEXTURE0:

-	case GL_TEXTURE1:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)

-{

-	UNIMPLEMENTED();

-}

-

-void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)

-{

-	TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)

-{

-	UNIMPLEMENTED();

-}

-

-void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

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

-

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

-}

-

-void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);

-

-	if(left == right || bottom == top || zNear == zFar)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);

-}

-

-void PixelStorei(GLenum pname, GLint param)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_UNPACK_ALIGNMENT:

-			if(param != 1 && param != 2 && param != 4 && param != 8)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			context->setUnpackAlignment(param);

-			break;

-		case GL_PACK_ALIGNMENT:

-			if(param != 1 && param != 2 && param != 4 && param != 8)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			context->setPackAlignment(param);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterf(GLenum pname, GLfloat param)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin(param);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax(param);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize(param);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			return error(GL_INVALID_ENUM);   // Needs three values, should call glPointParameterfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterfv(GLenum pname, const GLfloat *params)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin(params[0]);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax(params[0]);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			context->setPointDistanceAttenuation(params[0], params[1], params[2]);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize(params[0]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterx(GLenum pname, GLfixed param)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin((float)param / 0x10000);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax((float)param / 0x10000);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize((float)param / 0x10000);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			return error(GL_INVALID_ENUM);   // Needs three parameters, should call glPointParameterxv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterxv(GLenum pname, const GLfixed *params)

-{

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

-

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

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin((float)params[0] / 0x10000);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax((float)params[0] / 0x10000);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize((float)params[0] / 0x10000);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointSize(GLfloat size)

-{

-	TRACE("(GLfloat size = %f)", size);

-

-	if(size <= 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

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

-

-	switch(type)

-	{

-	case GL_FIXED:

-	case GL_FLOAT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-}

-

-void PointSizex(GLfixed size)

-{

-	PointSize((float)size / 0x10000);

-}

-

-void PolygonOffset(GLfloat factor, GLfloat units)

-{

-	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);

-

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

-

-	if(context)

-	{

-		context->setPolygonOffsetParams(factor, units);

-	}

-}

-

-void PolygonOffsetx(GLfixed factor, GLfixed units)

-{

-	PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);

-}

-

-void PopMatrix(void)

-{

-	TRACE("()");

-

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

-

-	if(context)

-	{

-		context->popMatrix();

-	}

-}

-

-void PushMatrix(void)

-{

-	TRACE("()");

-

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

-

-	if(context)

-	{

-		context->pushMatrix();

-	}

-}

-

-void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",

-	      x, y, width, height, format, type,  pixels);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		context->readPixels(x, y, width, height, format, type, NULL, pixels);

-	}

-}

-

-void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",

-	      target, internalformat, width, height);

-

-	switch(target)

-	{

-	case GL_RENDERBUFFER_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		GLuint handle = context->getRenderbufferName();

-		if(handle == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT16_OES:

-			context->setRenderbufferStorage(new es1::Depthbuffer(width, height, 0));

-			break;

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-			context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));

-			break;

-		case GL_STENCIL_INDEX8_OES:

-			context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));

-			break;

-		case GL_DEPTH24_STENCIL8_OES:

-			context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, 0));

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)

-{

-	Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);

-}

-

-void SampleCoverage(GLclampf value, GLboolean invert)

-{

-	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

-

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

-

-	if(context)

-	{

-		context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE);

-	}

-}

-

-void SampleCoveragex(GLclampx value, GLboolean invert)

-{

-	SampleCoverage((float)value / 0x10000, invert);

-}

-

-void Scalef(GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

-

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

-

-	if(context)

-	{

-		context->scale(x, y, z);

-	}

-}

-

-void Scalex(GLfixed x, GLfixed y, GLfixed z)

-{

-	Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);

-}

-

-void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void ShadeModel(GLenum mode)

-{

-	switch(mode)

-	{

-	case GL_FLAT:

-	case GL_SMOOTH:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setShadeModel(mode);

-	}

-}

-

-void StencilFunc(GLenum func, GLint ref, GLuint mask)

-{

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

-

-	switch(func)

-	{

-	case GL_NEVER:

-	case GL_ALWAYS:

-	case GL_LESS:

-	case GL_LEQUAL:

-	case GL_EQUAL:

-	case GL_GEQUAL:

-	case GL_GREATER:

-	case GL_NOTEQUAL:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setStencilParams(func, ref, mask);

-	}

-}

-

-void StencilMask(GLuint mask)

-{

-	TRACE("(GLuint mask = %d)", mask);

-

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

-

-	if(context)

-	{

-		context->setStencilWritemask(mask);

-	}

-}

-

-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)

-{

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

-

-	switch(fail)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP_OES:

-	case GL_DECR_WRAP_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(zfail)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP_OES:

-	case GL_DECR_WRAP_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(zpass)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP_OES:

-	case GL_DECR_WRAP_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

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

-

-	if(context)

-	{

-		context->setStencilOperations(fail, zfail, zpass);

-	}

-}

-

-void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

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

-

-	if(size < 2 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-		VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);

-	}

-}

-

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

-

-void TexEnvf(GLenum target, GLenum pname, GLfloat param)

-{

-	TexEnvi(target, pname, (GLint)param);

-}

-

-void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)

-{

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

-

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

-

-	if(context)

-	{

-		GLint iParam = (GLint)roundf(params[0]);

-

-		switch(target)

-		{

-		case GL_POINT_SPRITE_OES:

-			UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_ENV:

-			switch(pname)

-			{

-			case GL_TEXTURE_ENV_MODE:

-				switch(iParam)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_DECAL:

-				case GL_BLEND:

-				case GL_ADD:

-				case GL_COMBINE:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setTextureEnvMode(iParam);

-				break;

-			case GL_TEXTURE_ENV_COLOR:

-				context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));

-				break;

-			case GL_COMBINE_RGB:

-				switch(iParam)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-				case GL_DOT3_RGB:

-				case GL_DOT3_RGBA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineRGB(iParam);

-				break;

-			case GL_COMBINE_ALPHA:

-				switch(iParam)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineAlpha(iParam);

-				break;

-			case GL_RGB_SCALE:

-				if(iParam != 1 && iParam != 2 && iParam != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(iParam != 1) UNIMPLEMENTED();

-				break;

-			case GL_ALPHA_SCALE:

-				if(iParam != 1 && iParam != 2 && iParam != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(iParam != 1) UNIMPLEMENTED();

-				break;

-			case GL_OPERAND0_RGB:

-				switch(iParam)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0RGB(iParam);

-				break;

-			case GL_OPERAND1_RGB:

-				switch(iParam)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1RGB(iParam);

-				break;

-			case GL_OPERAND2_RGB:

-				switch(iParam)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2RGB(iParam);

-				break;

-			case GL_OPERAND0_ALPHA:

-				switch(iParam)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0Alpha(iParam);

-				break;

-			case GL_OPERAND1_ALPHA:

-				switch(iParam)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1Alpha(iParam);

-				break;

-			case GL_OPERAND2_ALPHA:

-				switch(iParam)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2Alpha(iParam);

-				break;

-			case GL_SRC0_RGB:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0RGB(iParam);

-				break;

-			case GL_SRC1_RGB:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1RGB(iParam);

-				break;

-			case GL_SRC2_RGB:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2RGB(iParam);

-				break;

-			case GL_SRC0_ALPHA:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0Alpha(iParam);

-				break;

-			case GL_SRC1_ALPHA:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1Alpha(iParam);

-				break;

-			case GL_SRC2_ALPHA:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2Alpha(iParam);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

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

-{

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

-

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

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_POINT_SPRITE_OES:

-			UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_ENV:

-			switch(pname)

-			{

-			case GL_TEXTURE_ENV_MODE:

-				switch((GLenum)param)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_DECAL:

-				case GL_BLEND:

-				case GL_ADD:

-				case GL_COMBINE:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setTextureEnvMode((GLenum)param);

-				break;

-			case GL_TEXTURE_ENV_COLOR:

-				return error(GL_INVALID_ENUM);   // Needs four values, should call glTexEnviv() instead

-				break;

-			case GL_COMBINE_RGB:

-				switch((GLenum)param)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-				case GL_DOT3_RGB:

-				case GL_DOT3_RGBA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineRGB((GLenum)param);

-				break;

-			case GL_COMBINE_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineAlpha((GLenum)param);

-				break;

-			case GL_RGB_SCALE:

-				if(param != 1 && param != 2 && param != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(param != 1) UNIMPLEMENTED();

-				break;

-			case GL_ALPHA_SCALE:

-				if(param != 1 && param != 2 && param != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(param != 1) UNIMPLEMENTED();

-				break;

-			case GL_OPERAND0_RGB:

-				switch((GLenum)param)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0RGB((GLenum)param);

-				break;

-			case GL_OPERAND1_RGB:

-				switch((GLenum)param)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1RGB((GLenum)param);

-				break;

-			case GL_OPERAND2_RGB:

-				switch((GLenum)param)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2RGB((GLenum)param);

-				break;

-			case GL_OPERAND0_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0Alpha((GLenum)param);

-				break;

-			case GL_OPERAND1_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1Alpha((GLenum)param);

-				break;

-			case GL_OPERAND2_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2Alpha((GLenum)param);

-				break;

-			case GL_SRC0_RGB:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0RGB((GLenum)param);

-				break;

-			case GL_SRC1_RGB:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1RGB((GLenum)param);

-				break;

-			case GL_SRC2_RGB:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2RGB((GLenum)param);

-				break;

-			case GL_SRC0_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0Alpha((GLenum)param);

-				break;

-			case GL_SRC1_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1Alpha((GLenum)param);

-				break;

-			case GL_SRC2_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2Alpha((GLenum)param);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexEnvx(GLenum target, GLenum pname, GLfixed param)

-{

-	TexEnvi(target, pname, (GLint)param);

-}

-

-void TexEnviv(GLenum target, GLenum pname, const GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",

-	      target, level, internalformat, width, height, border, format, type, pixels);

-

-	if(!validImageSize(level, width, height))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(internalformat != (GLint)format)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	switch(format)

-	{

-	case GL_ALPHA:

-	case GL_LUMINANCE:

-	case GL_LUMINANCE_ALPHA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGB:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_5_6_5:

-		case GL_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGBA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_4_4_4_4:

-		case GL_UNSIGNED_SHORT_5_5_5_1:

-		case GL_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_BGRA_EXT:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_ETC1_RGB8_OES:

-		return error(GL_INVALID_OPERATION);

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		if(S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-		else

-		{

-			return error(GL_INVALID_ENUM);

-		}

-	case GL_DEPTH_STENCIL_OES:

-		switch(type)

-		{

-		case GL_UNSIGNED_INT_24_8_OES:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void TexParameterf(GLenum target, GLenum pname, GLfloat param)

-{

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

-

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

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_WRAP_S:

-			if(!texture->setWrapS((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_T:

-			if(!texture->setWrapT((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			if(!texture->setMinFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAG_FILTER:

-			if(!texture->setMagFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			if(!texture->setMaxAnisotropy(param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_GENERATE_MIPMAP:

-			texture->setGenerateMipmap((GLboolean)param);

-			break;

-		case GL_TEXTURE_CROP_RECT_OES:

-			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameterfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)

-{

-	TexParameterf(target, pname, *params);

-}

-

-void TexParameteri(GLenum target, GLenum pname, GLint param)

-{

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

-

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

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_WRAP_S:

-			if(!texture->setWrapS((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_T:

-			if(!texture->setWrapT((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			if(!texture->setMinFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAG_FILTER:

-			if(!texture->setMagFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			if(!texture->setMaxAnisotropy((GLfloat)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_GENERATE_MIPMAP:

-			texture->setGenerateMipmap((GLboolean)param);

-			break;

-		case GL_TEXTURE_CROP_RECT_OES:

-			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameteriv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameteriv(GLenum target, GLenum pname, const GLint* params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);

-

-	switch(pname)

-	{

-	case GL_TEXTURE_CROP_RECT_OES:

-		break;

-	default:

-		return TexParameteri(target, pname, params[0]);

-	}

-

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

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_CROP_RECT_OES:

-			texture->setCropRect(params[0], params[1], params[2], params[3]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameterx(GLenum target, GLenum pname, GLfixed param)

-{

-	TexParameteri(target, pname, (GLint)param);

-}

-

-void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                   GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "

-	      "const GLvoid* pixels = %p)",

-	      target, level, xoffset, yoffset, width, height, format, type, pixels);

-

-	if(!es1::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!es1::CheckTextureFormatType(format, type))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width == 0 || height == 0 || !pixels)

-	{

-		return;

-	}

-

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

-

-	if(context)

-	{

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))

-			{

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

-			}

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void Translatef(GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

-

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

-

-	if(context)

-	{

-		context->translate(x, y, z);

-	}

-}

-

-void Translatex(GLfixed x, GLfixed y, GLfixed z)

-{

-	Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);

-}

-

-void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

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

-

-	if(size < 2 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-}

-

-void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)

-{

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

-

-	switch(target)

-	{

-	case GL_TEXTURE_2D:

-	case GL_TEXTURE_EXTERNAL_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

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

-

-	if(context)

-	{

-		es1::Texture2D *texture = 0;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;

-		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;

-		default:                      UNREACHABLE(target);

-		}

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		egl::Image *glImage = static_cast<egl::Image*>(image);

-

-		texture->setImage(glImage);

-	}

-}

-

-void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)

-{

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

-

-	UNIMPLEMENTED();

-}

-

-void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);

-

-	if(width <= 0 || height <= 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexsvOES(const GLshort *coords)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexivOES(const GLint *coords)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexxvOES(const GLfixed *coords)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);

-

-	if(width <= 0 || height <= 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

-

-	if(context)

-	{

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

-	}

-}

-

-void DrawTexfvOES(const GLfloat *coords)

-{

-	UNIMPLEMENTED();

-}

-

-}

-

-extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)

-{

-	struct Extension

-	{

-		const char *name;

-		__eglMustCastToProperFunctionPointerType address;

-	};

-

-	static const Extension glExtensions[] =

-	{

-		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}

-

-		EXTENSION(glEGLImageTargetTexture2DOES),

-		EXTENSION(glEGLImageTargetRenderbufferStorageOES),

-		EXTENSION(glIsRenderbufferOES),

-		EXTENSION(glBindRenderbufferOES),

-		EXTENSION(glDeleteRenderbuffersOES),

-		EXTENSION(glGenRenderbuffersOES),

-		EXTENSION(glRenderbufferStorageOES),

-		EXTENSION(glGetRenderbufferParameterivOES),

-		EXTENSION(glIsFramebufferOES),

-		EXTENSION(glBindFramebufferOES),

-		EXTENSION(glDeleteFramebuffersOES),

-		EXTENSION(glGenFramebuffersOES),

-		EXTENSION(glCheckFramebufferStatusOES),

-		EXTENSION(glFramebufferRenderbufferOES),

-		EXTENSION(glFramebufferTexture2DOES),

-		EXTENSION(glGetFramebufferAttachmentParameterivOES),

-		EXTENSION(glGenerateMipmapOES),

-		EXTENSION(glBlendEquationOES),

-		EXTENSION(glBlendEquationSeparateOES),

-		EXTENSION(glBlendFuncSeparateOES),

-		EXTENSION(glPointSizePointerOES),

-

-		#undef EXTENSION

-	};

-

-	for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)

-	{

-		if(strcmp(procname, glExtensions[ext].name) == 0)

-		{

-			return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;

-		}

-	}

-

-	return NULL;

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions.
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "Buffer.h"
+#include "Context.h"
+#include "Framebuffer.h"
+#include "Renderbuffer.h"
+#include "Texture.h"
+#include "common/debug.h"
+#include "Common/SharedLibrary.hpp"
+#include "Common/Version.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <limits>
+
+namespace es1
+{
+
+static bool validImageSize(GLint level, GLsizei width, GLsizei height)
+{
+	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture)
+{
+	if(!texture)
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(compressed != texture->isCompressed(target, level))
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(format != GL_NONE_OES && format != texture->getFormat(target, level))
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(compressed)
+	{
+		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
+		   (height % 4 != 0 && height != texture->getHeight(target, 0)))
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+	}
+
+	if(xoffset + width > texture->getWidth(target, level) ||
+	   yoffset + height > texture->getHeight(target, level))
+	{
+		return error(GL_INVALID_VALUE, false);
+	}
+
+	return true;
+}
+
+void ActiveTexture(GLenum texture)
+{
+	TRACE("(GLenum texture = 0x%X)", texture);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->setActiveSampler(texture - GL_TEXTURE0);
+	}
+}
+
+void AlphaFunc(GLenum func, GLclampf ref)
+{
+	TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
+
+	switch(func)
+	{
+	case GL_NEVER:
+	case GL_ALWAYS:
+	case GL_LESS:
+	case GL_LEQUAL:
+	case GL_EQUAL:
+	case GL_GEQUAL:
+	case GL_GREATER:
+	case GL_NOTEQUAL:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setAlphaFunc(func, clamp01(ref));
+	}
+}
+
+void AlphaFuncx(GLenum func, GLclampx ref)
+{
+	AlphaFunc(func, (float)ref / 0x10000);
+}
+
+void BindBuffer(GLenum target, GLuint buffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			context->bindArrayBuffer(buffer);
+			return;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			context->bindElementArrayBuffer(buffer);
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void BindFramebuffer(GLenum target, GLuint framebuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
+
+	if(target != GL_FRAMEBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->bindFramebuffer(framebuffer);
+	}
+}
+
+void BindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
+
+	if(target != GL_FRAMEBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->bindFramebuffer(framebuffer);
+	}
+}
+
+void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
+
+	if(target != GL_RENDERBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
+		{
+			// [OpenGL ES 2.0.25] Section 4.4.3 page 112
+			// [OpenGL ES 3.0.2] Section 4.4.2 page 201
+			// 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
+			// type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->bindRenderbuffer(renderbuffer);
+	}
+}
+
+void BindTexture(GLenum target, GLuint texture)
+{
+	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject && textureObject->getTarget() != target && texture != 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			context->bindTexture2D(texture);
+			return;
+		case GL_TEXTURE_EXTERNAL_OES:
+			context->bindTextureExternal(texture);
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+
+void BlendEquationOES(GLenum mode)
+{
+	BlendEquationSeparateOES(mode, mode);
+}
+
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
+{
+	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
+
+	switch(modeRGB)
+	{
+	case GL_FUNC_ADD_OES:
+	case GL_FUNC_SUBTRACT_OES:
+	case GL_FUNC_REVERSE_SUBTRACT_OES:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(modeAlpha)
+	{
+	case GL_FUNC_ADD_OES:
+	case GL_FUNC_SUBTRACT_OES:
+	case GL_FUNC_REVERSE_SUBTRACT_OES:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setBlendEquation(modeRGB, modeAlpha);
+	}
+}
+
+void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+void BlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
+}
+
+void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
+		  srcRGB, dstRGB, srcAlpha, dstAlpha);
+
+	switch(srcRGB)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_SRC_ALPHA_SATURATE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(dstRGB)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(srcAlpha)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_SRC_ALPHA_SATURATE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(dstAlpha)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
+	}
+}
+
+void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
+
+	TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
+	      target, size, data, usage);
+
+	if(size < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(usage)
+	{
+	case GL_STATIC_DRAW:
+	case GL_DYNAMIC_DRAW:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		buffer->bufferData(data, size, usage);
+	}
+}
+
+void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
+	offset = static_cast<GLint>(offset);
+
+	TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
+	      target, offset, size, data);
+
+	if(size < 0 || offset < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!data)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if((size_t)size + offset > buffer->size())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		buffer->bufferSubData(data, size, offset);
+	}
+}
+
+GLenum CheckFramebufferStatusOES(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	if(target != GL_FRAMEBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM, 0);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		return framebuffer->completeness();
+	}
+
+	return 0;
+}
+
+void Clear(GLbitfield mask)
+{
+	TRACE("(GLbitfield mask = %X)", mask);
+
+	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->clear(mask);
+	}
+}
+
+void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
+	      red, green, blue, alpha);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClearColor(red, green, blue, alpha);
+	}
+}
+
+void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+	ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
+}
+
+void ClearDepthf(GLclampf depth)
+{
+	TRACE("(GLclampf depth = %f)", depth);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClearDepth(depth);
+	}
+}
+
+void ClearDepthx(GLclampx depth)
+{
+	ClearDepthf((float)depth / 0x10000);
+}
+
+void ClearStencil(GLint s)
+{
+	TRACE("(GLint s = %d)", s);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClearStencil(s);
+	}
+}
+
+void ClientActiveTexture(GLenum texture)
+{
+	TRACE("(GLenum texture = 0x%X)", texture);
+
+	switch(texture)
+	{
+	case GL_TEXTURE0:
+	case GL_TEXTURE1:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->clientActiveTexture(texture);
+	}
+}
+
+void ClipPlanef(GLenum plane, const GLfloat *equation)
+{
+	TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane);
+
+	int index = plane - GL_CLIP_PLANE0;
+
+	if(index < 0 || index >= MAX_CLIP_PLANES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClipPlane(index, equation);
+	}
+}
+
+void ClipPlanex(GLenum plane, const GLfixed *equation)
+{
+	GLfloat equationf[4] =
+	{
+		(float)equation[0] / 0x10000,
+		(float)equation[1] / 0x10000,
+		(float)equation[2] / 0x10000,
+		(float)equation[3] / 0x10000,
+	};
+
+	ClipPlanef(plane, equationf);
+}
+
+void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
+	}
+}
+
+void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+	Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF);
+}
+
+void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+	Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
+}
+
+void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
+	      red, green, blue, alpha);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
+	}
+}
+
+void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
+	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
+	      index, size, type, normalized, stride, ptr);
+
+	if(index >= es1::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(size < 1 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(type)
+	{
+	case GL_BYTE:
+	case GL_UNSIGNED_BYTE:
+	case GL_SHORT:
+	case GL_UNSIGNED_SHORT:
+	case GL_FIXED:
+	case GL_FLOAT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(stride < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
+	}
+}
+
+void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
+
+	if(size != 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	VertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
+}
+
+void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                          GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
+	      target, level, internalformat, width, height, border, imageSize, data);
+
+	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!validImageSize(level, width, height) || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(internalformat)
+	{
+	case GL_ETC1_RGB8_OES:
+		break;
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		if(!S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_DEPTH_COMPONENT16_OES:
+	case GL_DEPTH_COMPONENT32_OES:
+	case GL_DEPTH_STENCIL_OES:
+	case GL_DEPTH24_STENCIL8_OES:
+		return error(GL_INVALID_OPERATION);
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                             GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
+	      "GLsizei imageSize = %d, const GLvoid* data = %p)",
+	      target, level, xoffset, yoffset, width, height, format, imageSize, data);
+
+	if(!es1::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(format)
+	{
+	case GL_ETC1_RGB8_OES:
+		break;
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		if(!S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width == 0 || height == 0 || !data)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(imageSize != egl::ComputeCompressedSize(width, height, format))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(xoffset % 4 != 0 || yoffset % 4 != 0)
+		{
+			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+			}
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
+	      target, level, internalformat, x, y, width, height, border);
+
+	if(!validImageSize(level, width, height))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+		}
+
+		if(context->getFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Renderbuffer *source = framebuffer->getColorbuffer();
+		GLenum colorbufferFormat = source->getFormat();
+
+		// [OpenGL ES 2.0.24] table 3.9
+		switch(internalformat)
+		{
+		case GL_ALPHA:
+			if(colorbufferFormat != GL_ALPHA &&
+			   colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4_OES &&
+			   colorbufferFormat != GL_RGB5_A1_OES &&
+			   colorbufferFormat != GL_RGBA8_OES)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_LUMINANCE:
+		case GL_RGB:
+			if(colorbufferFormat != GL_RGB &&
+			   colorbufferFormat != GL_RGB565_OES &&
+			   colorbufferFormat != GL_RGB8_OES &&
+			   colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4_OES &&
+			   colorbufferFormat != GL_RGB5_A1_OES &&
+			   colorbufferFormat != GL_RGBA8_OES)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_LUMINANCE_ALPHA:
+		case GL_RGBA:
+			if(colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4_OES &&
+			   colorbufferFormat != GL_RGB5_A1_OES &&
+			   colorbufferFormat != GL_RGBA8_OES)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_ETC1_RGB8_OES:
+			return error(GL_INVALID_OPERATION);
+		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+			if(S3TC_SUPPORT)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+	      target, level, xoffset, yoffset, x, y, width, height);
+
+	if(!es1::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(width == 0 || height == 0)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+		}
+
+		es1::Renderbuffer *source = framebuffer->getColorbuffer();
+
+		if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Texture *texture = nullptr;
+
+		if(target == GL_TEXTURE_2D)
+		{
+			texture = context->getTexture2D();
+		}
+		else UNREACHABLE(target);
+
+		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture))
+		{
+			return;
+		}
+
+		texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
+	}
+}
+
+void CullFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		{
+			es1::Context *context = es1::getContext();
+
+			if(context)
+			{
+				context->setCullMode(mode);
+			}
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void DeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteBuffer(buffers[i]);
+		}
+	}
+}
+
+void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			if(framebuffers[i] != 0)
+			{
+				context->deleteFramebuffer(framebuffers[i]);
+			}
+		}
+	}
+}
+
+void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteRenderbuffer(renderbuffers[i]);
+		}
+	}
+}
+
+void DeleteTextures(GLsizei n, const GLuint* textures)
+{
+	TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			if(textures[i] != 0)
+			{
+				context->deleteTexture(textures[i]);
+			}
+		}
+	}
+}
+
+void DepthFunc(GLenum func)
+{
+	TRACE("(GLenum func = 0x%X)", func);
+
+	switch(func)
+	{
+	case GL_NEVER:
+	case GL_ALWAYS:
+	case GL_LESS:
+	case GL_LEQUAL:
+	case GL_EQUAL:
+	case GL_GREATER:
+	case GL_GEQUAL:
+	case GL_NOTEQUAL:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setDepthFunc(func);
+	}
+}
+
+void DepthMask(GLboolean flag)
+{
+	TRACE("(GLboolean flag = %d)", flag);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setDepthMask(flag != GL_FALSE);
+	}
+}
+
+void DepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setDepthRange(zNear, zFar);
+	}
+}
+
+void DepthRangex(GLclampx zNear, GLclampx zFar)
+{
+	DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);
+}
+
+void Disable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(cap)
+		{
+		case GL_CULL_FACE:                context->setCullFaceEnabled(false);              break;
+		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(false);     break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
+		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(false);        break;
+		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(false);           break;
+		case GL_STENCIL_TEST:             context->setStencilTestEnabled(false);           break;
+		case GL_DEPTH_TEST:               context->setDepthTestEnabled(false);             break;
+		case GL_BLEND:                    context->setBlendEnabled(false);                 break;
+		case GL_DITHER:                   context->setDitherEnabled(false);                break;
+		case GL_LIGHTING:                 context->setLightingEnabled(false);              break;
+		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;
+		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;
+		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;
+		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;
+		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;
+		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;
+		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;
+		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;
+		case GL_FOG:                      context->setFogEnabled(false);                   break;
+		case GL_TEXTURE_2D:               context->setTexture2Denabled(false);             break;
+		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(false);       break;
+		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;
+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;
+		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(false);           break;
+		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(false);            break;
+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;
+		case GL_NORMALIZE:                context->setNormalizeEnabled(false);             break;
+		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(false);         break;
+		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(false);           break;
+		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(false);           break;
+		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(false);            break;
+		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(false);        break;
+		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(false);     break;
+		case GL_MULTISAMPLE:              context->setMultisampleEnabled(false);           break;
+		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(false);      break;
+		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, false);          break;
+		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, false);          break;
+		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, false);          break;
+		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, false);          break;
+		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, false);          break;
+		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, false);          break;
+		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(false);           break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void DisableClientState(GLenum array)
+{
+	TRACE("(GLenum array = 0x%X)", array);
+
+	switch(array)
+	{
+	case GL_VERTEX_ARRAY:
+	case GL_NORMAL_ARRAY:
+	case GL_COLOR_ARRAY:
+	case GL_POINT_SIZE_ARRAY_OES:
+	case GL_TEXTURE_COORD_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+
+		switch(array)
+		{
+		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, false);                            break;
+		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;
+		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;
+		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false);                           break;
+		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
+		default:                      UNREACHABLE(array);
+		}
+	}
+}
+
+void DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
+
+	if(count < 0 || first < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->drawArrays(mode, first, count);
+	}
+}
+
+void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
+	      mode, count, type, indices);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT:
+		case GL_UNSIGNED_INT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->drawElements(mode, count, type, indices);
+	}
+}
+
+void Enable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(cap)
+		{
+		case GL_CULL_FACE:                context->setCullFaceEnabled(true);              break;
+		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(true);     break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
+		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(true);        break;
+		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(true);           break;
+		case GL_STENCIL_TEST:             context->setStencilTestEnabled(true);           break;
+		case GL_DEPTH_TEST:               context->setDepthTestEnabled(true);             break;
+		case GL_BLEND:                    context->setBlendEnabled(true);                 break;
+		case GL_DITHER:                   context->setDitherEnabled(true);                break;
+		case GL_LIGHTING:                 context->setLightingEnabled(true);              break;
+		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;
+		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;
+		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;
+		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;
+		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;
+		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;
+		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;
+		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;
+		case GL_FOG:                      context->setFogEnabled(true);                   break;
+		case GL_TEXTURE_2D:               context->setTexture2Denabled(true);             break;
+		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(true);       break;
+		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;
+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;
+		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(true);           break;
+		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(true);            break;
+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;
+		case GL_NORMALIZE:                context->setNormalizeEnabled(true);             break;
+		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(true);         break;
+		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(true);           break;
+		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(true);           break;
+		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(true);            break;
+		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(true);        break;
+		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(true);     break;
+		case GL_MULTISAMPLE:              context->setMultisampleEnabled(true);           break;
+		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(true);      break;
+		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, true);          break;
+		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, true);          break;
+		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, true);          break;
+		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, true);          break;
+		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, true);          break;
+		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, true);          break;
+		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(true);           break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void EnableClientState(GLenum array)
+{
+	TRACE("(GLenum array = 0x%X)", array);
+
+	switch(array)
+	{
+	case GL_VERTEX_ARRAY:
+	case GL_NORMAL_ARRAY:
+	case GL_COLOR_ARRAY:
+	case GL_POINT_SIZE_ARRAY_OES:
+	case GL_TEXTURE_COORD_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+
+		switch(array)
+		{
+		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, true);                            break;
+		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;
+		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;
+		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true);                           break;
+		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
+		default:                      UNREACHABLE(array);
+		}
+	}
+}
+
+void Finish(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->finish();
+	}
+}
+
+void Flush(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->flush();
+	}
+}
+
+void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
+	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
+
+	if(target != GL_FRAMEBUFFER_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+		GLuint framebufferName = context->getFramebufferName();
+
+		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0_OES:
+			framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer);
+			break;
+		case GL_DEPTH_ATTACHMENT_OES:
+			framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer);
+			break;
+		case GL_STENCIL_ATTACHMENT_OES:
+			framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
+	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
+
+	if(target != GL_FRAMEBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(attachment)
+	{
+	case GL_COLOR_ATTACHMENT0_OES:
+	case GL_DEPTH_ATTACHMENT_OES:
+	case GL_STENCIL_ATTACHMENT_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(texture == 0)
+		{
+			textarget = GL_NONE_OES;
+		}
+		else
+		{
+			es1::Texture *tex = context->getTexture(texture);
+
+			if(!tex)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			if(tex->isCompressed(textarget, level))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			switch(textarget)
+			{
+			case GL_TEXTURE_2D:
+				if(tex->getTarget() != GL_TEXTURE_2D)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(level != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+		GLuint framebufferName = context->getFramebufferName();
+
+		if(framebufferName == 0 || !framebuffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0_OES:  framebuffer->setColorbuffer(textarget, texture);   break;
+		case GL_DEPTH_ATTACHMENT_OES:   framebuffer->setDepthbuffer(textarget, texture);   break;
+		case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break;
+		}
+	}
+}
+
+void Fogf(GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_FOG_MODE:
+			switch((GLenum)param)
+			{
+			case GL_LINEAR:
+			case GL_EXP:
+			case GL_EXP2:
+				context->setFogMode((GLenum)param);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FOG_DENSITY:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setFogDensity(param);
+			break;
+		case GL_FOG_START:
+			context->setFogStart(param);
+			break;
+		case GL_FOG_END:
+			context->setFogEnd(param);
+			break;
+		case GL_FOG_COLOR:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glFogfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Fogfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_FOG_MODE:
+			switch((GLenum)params[0])
+			{
+			case GL_LINEAR:
+			case GL_EXP:
+			case GL_EXP2:
+				context->setFogMode((GLenum)params[0]);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FOG_DENSITY:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setFogDensity(params[0]);
+			break;
+		case GL_FOG_START:
+			context->setFogStart(params[0]);
+			break;
+		case GL_FOG_END:
+			context->setFogEnd(params[0]);
+			break;
+		case GL_FOG_COLOR:
+			context->setFogColor(params[0], params[1], params[2], params[3]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Fogx(GLenum pname, GLfixed param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_FOG_MODE:
+			switch((GLenum)param)
+			{
+			case GL_LINEAR:
+			case GL_EXP:
+			case GL_EXP2:
+				context->setFogMode((GLenum)param);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FOG_DENSITY:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setFogDensity((float)param / 0x10000);
+			break;
+		case GL_FOG_START:
+			context->setFogStart((float)param / 0x10000);
+			break;
+		case GL_FOG_END:
+			context->setFogEnd((float)param / 0x10000);
+			break;
+		case GL_FOG_COLOR:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glFogxv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Fogxv(GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void FrontFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_CW:
+	case GL_CCW:
+		{
+			es1::Context *context = es1::getContext();
+
+			if(context)
+			{
+				context->setFrontFace(mode);
+			}
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
+
+	if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->frustum(left, right, bottom, top, zNear, zFar);
+	}
+}
+
+void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
+}
+
+void GenerateMipmapOES(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->generateMipmaps();
+	}
+}
+
+void GenBuffers(GLsizei n, GLuint* buffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			buffers[i] = context->createBuffer();
+		}
+	}
+}
+
+void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			framebuffers[i] = context->createFramebuffer();
+		}
+	}
+}
+
+void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			renderbuffers[i] = context->createRenderbuffer();
+		}
+	}
+}
+
+void GenTextures(GLsizei n, GLuint* textures)
+{
+	TRACE("(GLsizei n = %d, GLuint* textures =  %p)", n, textures);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			textures[i] = context->createTexture();
+		}
+	}
+}
+
+void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(target != GL_RENDERBUFFER_OES)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(context->getRenderbufferName() == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
+
+		switch(pname)
+		{
+		case GL_RENDERBUFFER_WIDTH_OES:           *params = renderbuffer->getWidth();       break;
+		case GL_RENDERBUFFER_HEIGHT_OES:          *params = renderbuffer->getHeight();      break;
+		case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: *params = renderbuffer->getFormat();      break;
+		case GL_RENDERBUFFER_RED_SIZE_OES:        *params = renderbuffer->getRedSize();     break;
+		case GL_RENDERBUFFER_GREEN_SIZE_OES:      *params = renderbuffer->getGreenSize();   break;
+		case GL_RENDERBUFFER_BLUE_SIZE_OES:       *params = renderbuffer->getBlueSize();    break;
+		case GL_RENDERBUFFER_ALPHA_SIZE_OES:      *params = renderbuffer->getAlphaSize();   break;
+		case GL_RENDERBUFFER_DEPTH_SIZE_OES:      *params = renderbuffer->getDepthSize();   break;
+		case GL_RENDERBUFFER_STENCIL_SIZE_OES:    *params = renderbuffer->getStencilSize(); break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetBooleanv(GLenum pname, GLboolean* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getBooleanv(pname, params)))
+		{
+			int numParams = context->getQueryParameterNum(pname);
+
+			if(numParams < 0)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(numParams == 0)
+			{
+				return;
+			}
+
+			if(context->isQueryParameterFloat(pname))
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(floatParams[i] == 0.0f)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] floatParams;
+			}
+			else if(context->isQueryParameterInt(pname))
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(intParams[i] == 0)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] intParams;
+			}
+			else UNREACHABLE(pname);
+		}
+	}
+}
+
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_BUFFER_USAGE:
+			*params = buffer->usage();
+			break;
+		case GL_BUFFER_SIZE:
+			*params = buffer->size();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+	UNIMPLEMENTED();
+}
+
+void GetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+	UNIMPLEMENTED();
+}
+
+GLenum GetError(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		return context->getError();
+	}
+
+	return GL_NO_ERROR;
+}
+
+void GetFixedv(GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetFloatv(GLenum pname, GLfloat* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getFloatv(pname, params)))
+		{
+			int numParams = context->getQueryParameterNum(pname);
+
+			if(numParams < 0)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(numParams == 0)
+			{
+				return;
+			}
+
+			if(context->isQueryParameterBool(pname))
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(boolParams[i] == GL_FALSE)
+						params[i] = 0.0f;
+					else
+						params[i] = 1.0f;
+				}
+
+				delete [] boolParams;
+			}
+			else if(context->isQueryParameterInt(pname))
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					params[i] = (GLfloat)intParams[i];
+				}
+
+				delete [] intParams;
+			}
+			else UNREACHABLE(pname);
+		}
+	}
+}
+
+void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
+	      target, attachment, pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(target != GL_FRAMEBUFFER_OES)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(context->getFramebufferName() == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		GLenum attachmentType;
+		GLuint attachmentHandle;
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0_OES:
+			attachmentType = framebuffer->getColorbufferType();
+			attachmentHandle = framebuffer->getColorbufferName();
+			break;
+		case GL_DEPTH_ATTACHMENT_OES:
+			attachmentType = framebuffer->getDepthbufferType();
+			attachmentHandle = framebuffer->getDepthbufferName();
+			break;
+		case GL_STENCIL_ATTACHMENT_OES:
+			attachmentType = framebuffer->getStencilbufferType();
+			attachmentHandle = framebuffer->getStencilbufferName();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		GLenum attachmentObjectType;   // Type category
+		if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)
+		{
+			attachmentObjectType = attachmentType;
+		}
+		else if(es1::IsTextureTarget(attachmentType))
+		{
+			attachmentObjectType = GL_TEXTURE;
+		}
+		else UNREACHABLE(attachmentType);
+
+		switch(pname)
+		{
+		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
+			*params = attachmentObjectType;
+			break;
+		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
+			if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)
+			{
+				*params = attachmentHandle;
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
+			if(attachmentObjectType == GL_TEXTURE)
+			{
+				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetIntegerv(GLenum pname, GLint* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getIntegerv(pname, params)))
+		{
+			int numParams = context->getQueryParameterNum(pname);
+
+			if(numParams < 0)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(numParams == 0)
+			{
+				return;
+			}
+
+			if(context->isQueryParameterBool(pname))
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(boolParams[i] == GL_FALSE)
+						params[i] = 0;
+					else
+						params[i] = 1;
+				}
+
+				delete [] boolParams;
+			}
+			else if(context->isQueryParameterFloat(pname))
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
+					{
+						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
+					}
+					else
+					{
+						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
+					}
+				}
+
+				delete [] floatParams;
+			}
+			else UNREACHABLE(pname);
+		}
+	}
+}
+
+void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetPointerv(GLenum pname, GLvoid **params)
+{
+	TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+const GLubyte* GetString(GLenum name)
+{
+	TRACE("(GLenum name = 0x%X)", name);
+
+	switch(name)
+	{
+	case GL_VENDOR:
+		return (GLubyte*)"Google Inc.";
+	case GL_RENDERER:
+		return (GLubyte*)"Google SwiftShader";
+	case GL_VERSION:
+		return (GLubyte*)"OpenGL ES 1.1 SwiftShader " VERSION_STRING;
+	case GL_EXTENSIONS:
+		// Keep list sorted in following order:
+		// OES extensions
+		// EXT extensions
+		// Vendor extensions
+		return (GLubyte*)
+			"GL_OES_blend_equation_separate "
+			"GL_OES_blend_func_separate "
+			"GL_OES_blend_subtract "
+			"GL_OES_compressed_ETC1_RGB8_texture "
+			"GL_OES_depth_texture "
+			"GL_OES_EGL_image "
+			"GL_OES_EGL_image_external "
+			"GL_OES_EGL_sync "
+			"GL_OES_element_index_uint "
+			"GL_OES_framebuffer_object "
+			"GL_OES_packed_depth_stencil "
+			"GL_OES_read_format "
+			"GL_OES_rgb8_rgba8 "
+			"GL_OES_stencil8 "
+			"GL_OES_stencil_wrap "
+			"GL_OES_texture_mirrored_repeat "
+			"GL_OES_texture_npot "
+			"GL_EXT_blend_minmax "
+			"GL_EXT_read_format_bgra "
+			#if (S3TC_SUPPORT)
+			"GL_EXT_texture_compression_dxt1 "
+			"GL_ANGLE_texture_compression_dxt3 "
+			"GL_ANGLE_texture_compression_dxt5 "
+			#endif
+			"GL_EXT_texture_filter_anisotropic "
+			"GL_EXT_texture_format_BGRA8888";
+	default:
+		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
+	}
+}
+
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_MAG_FILTER:
+			*params = (GLfloat)texture->getMagFilter();
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			*params = (GLfloat)texture->getMinFilter();
+			break;
+		case GL_TEXTURE_WRAP_S:
+			*params = (GLfloat)texture->getWrapS();
+			break;
+		case GL_TEXTURE_WRAP_T:
+			*params = (GLfloat)texture->getWrapT();
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			*params = texture->getMaxAnisotropy();
+			break;
+		case GL_GENERATE_MIPMAP:
+			*params = (GLfloat)texture->getGenerateMipmap();
+			break;
+		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+			*params = (GLfloat)1;
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_MAG_FILTER:
+			*params = texture->getMagFilter();
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			*params = texture->getMinFilter();
+			break;
+		case GL_TEXTURE_WRAP_S:
+			*params = texture->getWrapS();
+			break;
+		case GL_TEXTURE_WRAP_T:
+			*params = texture->getWrapT();
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			*params = (GLint)texture->getMaxAnisotropy();
+			break;
+		case GL_GENERATE_MIPMAP:
+			*params = (GLint)texture->getGenerateMipmap();
+			break;
+		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+			*params = 1;
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void Hint(GLenum target, GLenum mode)
+{
+	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
+
+	switch(mode)
+	{
+	case GL_FASTEST:
+	case GL_NICEST:
+	case GL_DONT_CARE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_GENERATE_MIPMAP_HINT:
+			context->setGenerateMipmapHint(mode);
+			break;
+		case GL_PERSPECTIVE_CORRECTION_HINT:
+			context->setPerspectiveCorrectionHint(mode);
+			break;
+		case GL_FOG_HINT:
+			context->setFogHint(mode);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GLboolean IsBuffer(GLuint buffer)
+{
+	TRACE("(GLuint buffer = %d)", buffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && buffer)
+	{
+		es1::Buffer *bufferObject = context->getBuffer(buffer);
+
+		if(bufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsEnabled(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(cap)
+		{
+		case GL_CULL_FACE:                return context->isCullFaceEnabled();              break;
+		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();     break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;
+		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();        break;
+		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();           break;
+		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();           break;
+		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();             break;
+		case GL_BLEND:                    return context->isBlendEnabled();                 break;
+		case GL_DITHER:                   return context->isDitherEnabled();                break;
+		case GL_LIGHTING:                 return context->isLightingEnabled();              break;
+		case GL_LIGHT0:                   return context->isLightEnabled(0);                break;
+		case GL_LIGHT1:                   return context->isLightEnabled(1);                break;
+		case GL_LIGHT2:                   return context->isLightEnabled(2);                break;
+		case GL_LIGHT3:                   return context->isLightEnabled(3);                break;
+		case GL_LIGHT4:                   return context->isLightEnabled(4);                break;
+		case GL_LIGHT5:                   return context->isLightEnabled(5);                break;
+		case GL_LIGHT6:                   return context->isLightEnabled(6);                break;
+		case GL_LIGHT7:                   return context->isLightEnabled(7);                break;
+		case GL_FOG:                      return context->isFogEnabled();                   break;
+		case GL_TEXTURE_2D:               return context->isTexture2Denabled();             break;
+		case GL_TEXTURE_EXTERNAL_OES:     return context->isTextureExternalEnabled();       break;
+		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();             break;
+		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();          break;
+		case GL_POINT_SMOOTH:             return context->isPointSmoothEnabled();           break;
+		case GL_LINE_SMOOTH:              return context->isLineSmoothEnabled();            break;
+		case GL_COLOR_MATERIAL:           return context->isColorMaterialEnabled();         break;
+		case GL_NORMALIZE:                return context->isNormalizeEnabled();             break;
+		case GL_RESCALE_NORMAL:           return context->isRescaleNormalEnabled();         break;
+		case GL_VERTEX_ARRAY:             return context->isVertexArrayEnabled();           break;
+		case GL_NORMAL_ARRAY:             return context->isNormalArrayEnabled();           break;
+		case GL_COLOR_ARRAY:              return context->isColorArrayEnabled();            break;
+		case GL_POINT_SIZE_ARRAY_OES:     return context->isPointSizeArrayEnabled();        break;
+		case GL_TEXTURE_COORD_ARRAY:      return context->isTextureCoordArrayEnabled();     break;
+		case GL_MULTISAMPLE:              return context->isMultisampleEnabled();           break;
+		case GL_SAMPLE_ALPHA_TO_ONE:      return context->isSampleAlphaToOneEnabled();      break;
+		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);            break;
+		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);            break;
+		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);            break;
+		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);            break;
+		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);            break;
+		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);            break;
+		case GL_POINT_SPRITE_OES:         return context->isPointSpriteEnabled();           break;
+		default:
+			return error(GL_INVALID_ENUM, GL_FALSE);
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsFramebufferOES(GLuint framebuffer)
+{
+	TRACE("(GLuint framebuffer = %d)", framebuffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && framebuffer)
+	{
+		es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
+
+		if(framebufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsTexture(GLuint texture)
+{
+	TRACE("(GLuint texture = %d)", texture);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && texture)
+	{
+		es1::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsRenderbufferOES(GLuint renderbuffer)
+{
+	TRACE("(GLuint renderbuffer = %d)", renderbuffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && renderbuffer)
+	{
+		es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
+
+		if(renderbufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+void LightModelf(GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(param != 0.0f);
+			break;
+		case GL_LIGHT_MODEL_AMBIENT:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void LightModelfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_AMBIENT:
+			context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(params[0] != 0.0f);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void LightModelx(GLenum pname, GLfixed param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(param != 0);
+			break;
+		case GL_LIGHT_MODEL_AMBIENT:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelxv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void LightModelxv(GLenum pname, const GLfixed *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_AMBIENT:
+			context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);
+			break;
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(params[0] != 0);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Lightf(GLenum light, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);
+
+	int index = light - GL_LIGHT0;
+
+	if(index < 0 || index >= es1::MAX_LIGHTS)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_SPOT_EXPONENT:
+			if(param < 0.0f || param > 128.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightExponent(index, param);
+			break;
+		case GL_SPOT_CUTOFF:
+			if((param < 0.0f || param > 90.0f) && param != 180.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightCutoff(index, param);
+			break;
+		case GL_CONSTANT_ATTENUATION:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationConstant(index, param);
+			break;
+		case GL_LINEAR_ATTENUATION:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationLinear(index, param);
+			break;
+		case GL_QUADRATIC_ATTENUATION:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationQuadratic(index, param);
+			break;
+		case GL_AMBIENT:
+		case GL_DIFFUSE:
+		case GL_SPECULAR:
+		case GL_POSITION:
+		case GL_SPOT_DIRECTION:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		int index = light - GL_LIGHT0;
+
+		if(index < 0 || index > es1::MAX_LIGHTS)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_AMBIENT:               context->setLightAmbient(index, params[0], params[1], params[2], params[3]);  break;
+		case GL_DIFFUSE:               context->setLightDiffuse(index, params[0], params[1], params[2], params[3]);  break;
+		case GL_SPECULAR:              context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
+		case GL_POSITION:              context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
+		case GL_SPOT_DIRECTION:        context->setLightDirection(index, params[0], params[1], params[2]);           break;
+		case GL_SPOT_EXPONENT:
+			if(params[0] < 0.0f || params[0] > 128.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightExponent(index, params[0]);
+			break;
+		case GL_SPOT_CUTOFF:
+			if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightCutoff(index, params[0]);
+			break;
+		case GL_CONSTANT_ATTENUATION:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationConstant(index, params[0]);
+			break;
+		case GL_LINEAR_ATTENUATION:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationLinear(index, params[0]);
+			break;
+		case GL_QUADRATIC_ATTENUATION:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationQuadratic(index, params[0]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Lightx(GLenum light, GLenum pname, GLfixed param)
+{
+	UNIMPLEMENTED();
+}
+
+void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void LineWidth(GLfloat width)
+{
+	TRACE("(GLfloat width = %f)", width);
+
+	if(width <= 0.0f)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setLineWidth(width);
+	}
+}
+
+void LineWidthx(GLfixed width)
+{
+	LineWidth((float)width / 0x10000);
+}
+
+void LoadIdentity(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->loadIdentity();
+	}
+}
+
+void LoadMatrixf(const GLfloat *m)
+{
+	TRACE("(const GLfloat *m)");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->load(m);
+	}
+}
+
+void LoadMatrixx(const GLfixed *m)
+{
+	GLfloat matrix[16] =
+	{
+		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
+		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
+		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
+		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
+	};
+
+	LoadMatrixf(matrix);
+}
+
+void LogicOp(GLenum opcode)
+{
+	TRACE("(GLenum opcode = 0x%X)", opcode);
+
+	switch(opcode)
+	{
+	case GL_CLEAR:
+	case GL_SET:
+	case GL_COPY:
+	case GL_COPY_INVERTED:
+	case GL_NOOP:
+	case GL_INVERT:
+	case GL_AND:
+	case GL_NAND:
+	case GL_OR:
+	case GL_NOR:
+	case GL_XOR:
+	case GL_EQUIV:
+	case GL_AND_REVERSE:
+	case GL_AND_INVERTED:
+	case GL_OR_REVERSE:
+	case GL_OR_INVERTED:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setLogicalOperation(opcode);
+	}
+}
+
+void Materialf(GLenum face, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);
+
+	if(face != GL_FRONT_AND_BACK)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_SHININESS:
+			if(param < 0.0f || param > 128.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setMaterialShininess(param);
+			break;
+		case GL_AMBIENT:
+		case GL_DIFFUSE:
+		case GL_AMBIENT_AND_DIFFUSE:
+		case GL_SPECULAR:
+		case GL_EMISSION:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glMaterialfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);
+
+	if(face != GL_FRONT_AND_BACK)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_AMBIENT:
+			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_DIFFUSE:
+			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_AMBIENT_AND_DIFFUSE:
+			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
+			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_SPECULAR:
+			context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_EMISSION:
+			context->setMaterialEmission(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_SHININESS:
+			context->setMaterialShininess(params[0]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Materialx(GLenum face, GLenum pname, GLfixed param)
+{
+	UNIMPLEMENTED();
+}
+
+void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void MatrixMode(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setMatrixMode(mode);
+	}
+}
+
+void MultMatrixf(const GLfloat *m)
+{
+	TRACE("(const GLfloat *m)");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->multiply(m);
+	}
+}
+
+void MultMatrixx(const GLfixed *m)
+{
+	GLfloat matrix[16] =
+	{
+		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
+		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
+		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
+		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
+	};
+
+	MultMatrixf(matrix);
+}
+
+void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+	TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);
+
+	switch(target)
+	{
+	case GL_TEXTURE0:
+	case GL_TEXTURE1:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);
+	}
+}
+
+void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+	UNIMPLEMENTED();
+}
+
+void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+	TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
+	}
+}
+
+void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+	UNIMPLEMENTED();
+}
+
+void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
+
+	VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
+}
+
+void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
+
+	if(left == right || bottom == top || zNear == zFar)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->ortho(left, right, bottom, top, zNear, zFar);
+	}
+}
+
+void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
+}
+
+void PixelStorei(GLenum pname, GLint param)
+{
+	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_UNPACK_ALIGNMENT:
+			if(param != 1 && param != 2 && param != 4 && param != 8)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			context->setUnpackAlignment(param);
+			break;
+		case GL_PACK_ALIGNMENT:
+			if(param != 1 && param != 2 && param != 4 && param != 8)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			context->setPackAlignment(param);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterf(GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin(param);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax(param);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize(param);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			return error(GL_INVALID_ENUM);   // Needs three values, should call glPointParameterfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin(params[0]);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax(params[0]);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			context->setPointDistanceAttenuation(params[0], params[1], params[2]);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize(params[0]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterx(GLenum pname, GLfixed param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin((float)param / 0x10000);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax((float)param / 0x10000);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize((float)param / 0x10000);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			return error(GL_INVALID_ENUM);   // Needs three parameters, should call glPointParameterxv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterxv(GLenum pname, const GLfixed *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin((float)params[0] / 0x10000);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax((float)params[0] / 0x10000);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize((float)params[0] / 0x10000);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointSize(GLfloat size)
+{
+	TRACE("(GLfloat size = %f)", size);
+
+	if(size <= 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::PointSize, size, size, size, size);
+	}
+}
+
+void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
+
+	switch(type)
+	{
+	case GL_FIXED:
+	case GL_FLOAT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);
+}
+
+void PointSizex(GLfixed size)
+{
+	PointSize((float)size / 0x10000);
+}
+
+void PolygonOffset(GLfloat factor, GLfloat units)
+{
+	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setPolygonOffsetParams(factor, units);
+	}
+}
+
+void PolygonOffsetx(GLfixed factor, GLfixed units)
+{
+	PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
+}
+
+void PopMatrix(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->popMatrix();
+	}
+}
+
+void PushMatrix(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->pushMatrix();
+	}
+}
+
+void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
+	      x, y, width, height, format, type,  pixels);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
+	}
+}
+
+void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+	      target, internalformat, width, height);
+
+	switch(target)
+	{
+	case GL_RENDERBUFFER_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		GLuint handle = context->getRenderbufferName();
+		if(handle == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT16_OES:
+			context->setRenderbufferStorage(new es1::Depthbuffer(width, height, 0));
+			break;
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+			context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
+			break;
+		case GL_STENCIL_INDEX8_OES:
+			context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
+			break;
+		case GL_DEPTH24_STENCIL8_OES:
+			context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, 0));
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->rotate(angle, x, y, z);
+	}
+}
+
+void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+	Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
+}
+
+void SampleCoverage(GLclampf value, GLboolean invert)
+{
+	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
+
+	es1::Context* context = es1::getContext();
+
+	if(context)
+	{
+		context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE);
+	}
+}
+
+void SampleCoveragex(GLclampx value, GLboolean invert)
+{
+	SampleCoverage((float)value / 0x10000, invert);
+}
+
+void Scalef(GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->scale(x, y, z);
+	}
+}
+
+void Scalex(GLfixed x, GLfixed y, GLfixed z)
+{
+	Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
+}
+
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context* context = es1::getContext();
+
+	if(context)
+	{
+		context->setScissorParams(x, y, width, height);
+	}
+}
+
+void ShadeModel(GLenum mode)
+{
+	switch(mode)
+	{
+	case GL_FLAT:
+	case GL_SMOOTH:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setShadeModel(mode);
+	}
+}
+
+void StencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)",  func, ref, mask);
+
+	switch(func)
+	{
+	case GL_NEVER:
+	case GL_ALWAYS:
+	case GL_LESS:
+	case GL_LEQUAL:
+	case GL_EQUAL:
+	case GL_GEQUAL:
+	case GL_GREATER:
+	case GL_NOTEQUAL:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setStencilParams(func, ref, mask);
+	}
+}
+
+void StencilMask(GLuint mask)
+{
+	TRACE("(GLuint mask = %d)", mask);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setStencilWritemask(mask);
+	}
+}
+
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);
+
+	switch(fail)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP_OES:
+	case GL_DECR_WRAP_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(zfail)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP_OES:
+	case GL_DECR_WRAP_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(zpass)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP_OES:
+	case GL_DECR_WRAP_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setStencilOperations(fail, zfail, zpass);
+	}
+}
+
+void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
+
+	if(size < 2 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+		VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
+	}
+}
+
+void TexEnvi(GLenum target, GLenum pname, GLint param);
+
+void TexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+	TexEnvi(target, pname, (GLint)param);
+}
+
+void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLint iParam = (GLint)roundf(params[0]);
+
+		switch(target)
+		{
+		case GL_POINT_SPRITE_OES:
+			UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_ENV:
+			switch(pname)
+			{
+			case GL_TEXTURE_ENV_MODE:
+				switch(iParam)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_DECAL:
+				case GL_BLEND:
+				case GL_ADD:
+				case GL_COMBINE:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setTextureEnvMode(iParam);
+				break;
+			case GL_TEXTURE_ENV_COLOR:
+				context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));
+				break;
+			case GL_COMBINE_RGB:
+				switch(iParam)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+				case GL_DOT3_RGB:
+				case GL_DOT3_RGBA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineRGB(iParam);
+				break;
+			case GL_COMBINE_ALPHA:
+				switch(iParam)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineAlpha(iParam);
+				break;
+			case GL_RGB_SCALE:
+				if(iParam != 1 && iParam != 2 && iParam != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(iParam != 1) UNIMPLEMENTED();
+				break;
+			case GL_ALPHA_SCALE:
+				if(iParam != 1 && iParam != 2 && iParam != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(iParam != 1) UNIMPLEMENTED();
+				break;
+			case GL_OPERAND0_RGB:
+				switch(iParam)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0RGB(iParam);
+				break;
+			case GL_OPERAND1_RGB:
+				switch(iParam)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1RGB(iParam);
+				break;
+			case GL_OPERAND2_RGB:
+				switch(iParam)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2RGB(iParam);
+				break;
+			case GL_OPERAND0_ALPHA:
+				switch(iParam)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0Alpha(iParam);
+				break;
+			case GL_OPERAND1_ALPHA:
+				switch(iParam)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1Alpha(iParam);
+				break;
+			case GL_OPERAND2_ALPHA:
+				switch(iParam)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2Alpha(iParam);
+				break;
+			case GL_SRC0_RGB:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0RGB(iParam);
+				break;
+			case GL_SRC1_RGB:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1RGB(iParam);
+				break;
+			case GL_SRC2_RGB:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2RGB(iParam);
+				break;
+			case GL_SRC0_ALPHA:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0Alpha(iParam);
+				break;
+			case GL_SRC1_ALPHA:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1Alpha(iParam);
+				break;
+			case GL_SRC2_ALPHA:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2Alpha(iParam);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexEnvi(GLenum target, GLenum pname, GLint param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_POINT_SPRITE_OES:
+			UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_ENV:
+			switch(pname)
+			{
+			case GL_TEXTURE_ENV_MODE:
+				switch((GLenum)param)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_DECAL:
+				case GL_BLEND:
+				case GL_ADD:
+				case GL_COMBINE:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setTextureEnvMode((GLenum)param);
+				break;
+			case GL_TEXTURE_ENV_COLOR:
+				return error(GL_INVALID_ENUM);   // Needs four values, should call glTexEnviv() instead
+				break;
+			case GL_COMBINE_RGB:
+				switch((GLenum)param)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+				case GL_DOT3_RGB:
+				case GL_DOT3_RGBA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineRGB((GLenum)param);
+				break;
+			case GL_COMBINE_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineAlpha((GLenum)param);
+				break;
+			case GL_RGB_SCALE:
+				if(param != 1 && param != 2 && param != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(param != 1) UNIMPLEMENTED();
+				break;
+			case GL_ALPHA_SCALE:
+				if(param != 1 && param != 2 && param != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(param != 1) UNIMPLEMENTED();
+				break;
+			case GL_OPERAND0_RGB:
+				switch((GLenum)param)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0RGB((GLenum)param);
+				break;
+			case GL_OPERAND1_RGB:
+				switch((GLenum)param)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1RGB((GLenum)param);
+				break;
+			case GL_OPERAND2_RGB:
+				switch((GLenum)param)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2RGB((GLenum)param);
+				break;
+			case GL_OPERAND0_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0Alpha((GLenum)param);
+				break;
+			case GL_OPERAND1_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1Alpha((GLenum)param);
+				break;
+			case GL_OPERAND2_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2Alpha((GLenum)param);
+				break;
+			case GL_SRC0_RGB:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0RGB((GLenum)param);
+				break;
+			case GL_SRC1_RGB:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1RGB((GLenum)param);
+				break;
+			case GL_SRC2_RGB:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2RGB((GLenum)param);
+				break;
+			case GL_SRC0_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0Alpha((GLenum)param);
+				break;
+			case GL_SRC1_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1Alpha((GLenum)param);
+				break;
+			case GL_SRC2_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2Alpha((GLenum)param);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+	TexEnvi(target, pname, (GLint)param);
+}
+
+void TexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
+	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",
+	      target, level, internalformat, width, height, border, format, type, pixels);
+
+	if(!validImageSize(level, width, height))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(internalformat != (GLint)format)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	switch(format)
+	{
+	case GL_ALPHA:
+	case GL_LUMINANCE:
+	case GL_LUMINANCE_ALPHA:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_RGB:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_5_6_5:
+		case GL_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_RGBA:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_4_4_4_4:
+		case GL_UNSIGNED_SHORT_5_5_5_1:
+		case GL_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_BGRA_EXT:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_ETC1_RGB8_OES:
+		return error(GL_INVALID_OPERATION);
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		if(S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+		else
+		{
+			return error(GL_INVALID_ENUM);
+		}
+	case GL_DEPTH_STENCIL_OES:
+		switch(type)
+		{
+		case GL_UNSIGNED_INT_24_8_OES:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_WRAP_S:
+			if(!texture->setWrapS((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_T:
+			if(!texture->setWrapT((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			if(!texture->setMinFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAG_FILTER:
+			if(!texture->setMagFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			if(!texture->setMaxAnisotropy(param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_GENERATE_MIPMAP:
+			texture->setGenerateMipmap((GLboolean)param);
+			break;
+		case GL_TEXTURE_CROP_RECT_OES:
+			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameterfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	TexParameterf(target, pname, *params);
+}
+
+void TexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_WRAP_S:
+			if(!texture->setWrapS((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_T:
+			if(!texture->setWrapT((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			if(!texture->setMinFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAG_FILTER:
+			if(!texture->setMagFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			if(!texture->setMaxAnisotropy((GLfloat)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_GENERATE_MIPMAP:
+			texture->setGenerateMipmap((GLboolean)param);
+			break;
+		case GL_TEXTURE_CROP_RECT_OES:
+			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameteriv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);
+
+	switch(pname)
+	{
+	case GL_TEXTURE_CROP_RECT_OES:
+		break;
+	default:
+		return TexParameteri(target, pname, params[0]);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_CROP_RECT_OES:
+			texture->setCropRect(params[0], params[1], params[2], params[3]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+	TexParameteri(target, pname, (GLint)param);
+}
+
+void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                   GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
+	      "const GLvoid* pixels = %p)",
+	      target, level, xoffset, yoffset, width, height, format, type, pixels);
+
+	if(!es1::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!es1::CheckTextureFormatType(format, type))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width == 0 || height == 0 || !pixels)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
+			}
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void Translatef(GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->translate(x, y, z);
+	}
+}
+
+void Translatex(GLfixed x, GLfixed y, GLfixed z)
+{
+	Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
+}
+
+void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
+
+	if(size < 2 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	VertexAttribPointer(sw::Position, size, type, false, stride, pointer);
+}
+
+void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setViewportParams(x, y, width, height);
+	}
+}
+
+void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
+
+	switch(target)
+	{
+	case GL_TEXTURE_2D:
+	case GL_TEXTURE_EXTERNAL_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture2D *texture = 0;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;
+		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
+		default:                      UNREACHABLE(target);
+		}
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		egl::Image *glImage = static_cast<egl::Image*>(image);
+
+		texture->setImage(glImage);
+	}
+}
+
+void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
+
+	UNIMPLEMENTED();
+}
+
+void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);
+
+	if(width <= 0 || height <= 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);
+	}
+}
+
+void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexsvOES(const GLshort *coords)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexivOES(const GLint *coords)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexxvOES(const GLfixed *coords)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);
+
+	if(width <= 0 || height <= 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->drawTexture(x, y, z, width, height);
+	}
+}
+
+void DrawTexfvOES(const GLfloat *coords)
+{
+	UNIMPLEMENTED();
+}
+
+}
+
+extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
+{
+	struct Extension
+	{
+		const char *name;
+		__eglMustCastToProperFunctionPointerType address;
+	};
+
+	static const Extension glExtensions[] =
+	{
+		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+		EXTENSION(glEGLImageTargetTexture2DOES),
+		EXTENSION(glEGLImageTargetRenderbufferStorageOES),
+		EXTENSION(glIsRenderbufferOES),
+		EXTENSION(glBindRenderbufferOES),
+		EXTENSION(glDeleteRenderbuffersOES),
+		EXTENSION(glGenRenderbuffersOES),
+		EXTENSION(glRenderbufferStorageOES),
+		EXTENSION(glGetRenderbufferParameterivOES),
+		EXTENSION(glIsFramebufferOES),
+		EXTENSION(glBindFramebufferOES),
+		EXTENSION(glDeleteFramebuffersOES),
+		EXTENSION(glGenFramebuffersOES),
+		EXTENSION(glCheckFramebufferStatusOES),
+		EXTENSION(glFramebufferRenderbufferOES),
+		EXTENSION(glFramebufferTexture2DOES),
+		EXTENSION(glGetFramebufferAttachmentParameterivOES),
+		EXTENSION(glGenerateMipmapOES),
+		EXTENSION(glBlendEquationOES),
+		EXTENSION(glBlendEquationSeparateOES),
+		EXTENSION(glBlendFuncSeparateOES),
+		EXTENSION(glPointSizePointerOES),
+
+		#undef EXTENSION
+	};
+
+	for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
+	{
+		if(strcmp(procname, glExtensions[ext].name) == 0)
+		{
+			return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
+		}
+	}
+
+	return nullptr;
+}
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
index eddcd75..5c9657b 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.hpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #ifndef libGLES_CM_hpp
 #define libGLES_CM_hpp
 
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.rc b/src/OpenGL/libGLES_CM/libGLES_CM.rc
index cdbb35c..174d7b5 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.rc
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.rc
@@ -28,18 +28,18 @@
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE 
+1 TEXTINCLUDE
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE 
+2 TEXTINCLUDE
 BEGIN
     "#include ""afxres.h""\r\n"
     "#include ""../common/version.h""\0"
 END
 
-3 TEXTINCLUDE 
+3 TEXTINCLUDE
 BEGIN
     "\r\n"
     "\0"
@@ -77,7 +77,7 @@
 			#endif
             VALUE "FileVersion", VERSION_STRING
             VALUE "InternalName", "libGLES_CM"
-            VALUE "LegalCopyright", "Copyright (C) 2012 TransGaming Inc."
+            VALUE "LegalCopyright", "Copyright (C) 2016 Google Inc."
             VALUE "OriginalFilename", "libGLES_CM.dll"
             VALUE "PrivateBuild", VERSION_STRING
             VALUE "ProductName", "SwiftShader libGLES_CM Dynamic Link Library"
diff --git a/src/OpenGL/libGLES_CM/main.cpp b/src/OpenGL/libGLES_CM/main.cpp
index 8b91578..be2462a 100644
--- a/src/OpenGL/libGLES_CM/main.cpp
+++ b/src/OpenGL/libGLES_CM/main.cpp
@@ -1,1606 +1,1609 @@
-// 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.

-//

-

-// main.cpp: DLL entry point and management of thread-local data.

-

-#include "main.h"

-

-#include "libGLES_CM.hpp"

-#include "Framebuffer.h"

-#include "libEGL/Surface.h"

-#include "Common/Thread.hpp"

-#include "Common/SharedLibrary.hpp"

-#include "common/debug.h"

-

-#include <GLES/glext.h>

-

-#if !defined(_MSC_VER)

-#define CONSTRUCTOR __attribute__((constructor))

-#define DESTRUCTOR __attribute__((destructor))

-#else

-#define CONSTRUCTOR

-#define DESTRUCTOR

-#endif

-

-static void glAttachThread()

-{

-    TRACE("()");

-}

-

-static void glDetachThread()

-{

-    TRACE("()");

-}

-

-CONSTRUCTOR static void glAttachProcess()

-{

-    TRACE("()");

-

-    glAttachThread();

-}

-

-DESTRUCTOR static void glDetachProcess()

-{

-    TRACE("()");

-

-	glDetachThread();

-}

-

-#if defined(_WIN32)

-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)

-{

-    switch(reason)

-    {

-    case DLL_PROCESS_ATTACH:

-        glAttachProcess();

-        break;

-    case DLL_THREAD_ATTACH:

-        glAttachThread();

-        break;

-    case DLL_THREAD_DETACH:

-        glDetachThread();

-        break;

-    case DLL_PROCESS_DETACH:

-        glDetachProcess();

-        break;

-    default:

-        break;

-    }

-

-    return TRUE;

-}

-#endif

-

-namespace es1

-{

-es1::Context *getContext()

-{

-	egl::Context *context = libEGL->clientGetCurrentContext();

-

-	if(context && context->getClientVersion() == 1)

-	{

-		return static_cast<es1::Context*>(context);

-	}

-

-	return 0;

-}

-

-Device *getDevice()

-{

-    Context *context = getContext();

-

-    return context ? context->getDevice() : 0;

-}

-

-// Records an error code

-void error(GLenum errorCode)

-{

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

-

-    if(context)

-    {

-        switch(errorCode)

-        {

-        case GL_INVALID_ENUM:

-            context->recordInvalidEnum();

-            TRACE("\t! Error generated: invalid enum\n");

-            break;

-        case GL_INVALID_VALUE:

-            context->recordInvalidValue();

-            TRACE("\t! Error generated: invalid value\n");

-            break;

-        case GL_INVALID_OPERATION:

-            context->recordInvalidOperation();

-            TRACE("\t! Error generated: invalid operation\n");

-            break;

-        case GL_OUT_OF_MEMORY:

-            context->recordOutOfMemory();

-            TRACE("\t! Error generated: out of memory\n");

-            break;

-        case GL_INVALID_FRAMEBUFFER_OPERATION_OES:

-            context->recordInvalidFramebufferOperation();

-            TRACE("\t! Error generated: invalid framebuffer operation\n");

-            break;

-		case GL_STACK_OVERFLOW:

-			context->recordMatrixStackOverflow();

-            TRACE("\t! Error generated: matrix stack overflow\n");

-            break;

-		case GL_STACK_UNDERFLOW:

-			context->recordMatrixStackUnderflow();

-            TRACE("\t! Error generated: matrix stack underflow\n");

-            break;

-        default: UNREACHABLE(errorCode);

-        }

-    }

-}

-}

-

-namespace es1

-{

-void ActiveTexture(GLenum texture);

-void AlphaFunc(GLenum func, GLclampf ref);

-void AlphaFuncx(GLenum func, GLclampx ref);

-void BindBuffer(GLenum target, GLuint buffer);

-void BindFramebuffer(GLenum target, GLuint framebuffer);

-void BindFramebufferOES(GLenum target, GLuint framebuffer);

-void BindRenderbufferOES(GLenum target, GLuint renderbuffer);

-void BindTexture(GLenum target, GLuint texture);

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);

-void BlendEquationOES(GLenum mode);

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);

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

-void BlendFunc(GLenum sfactor, GLenum dfactor);

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

-void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);

-void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);

-GLenum CheckFramebufferStatusOES(GLenum target);

-void Clear(GLbitfield mask);

-void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

-void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);

-void ClearDepthf(GLclampf depth);

-void ClearDepthx(GLclampx depth);

-void ClearStencil(GLint s);

-void ClientActiveTexture(GLenum texture);

-void ClipPlanef(GLenum plane, const GLfloat *equation);

-void ClipPlanex(GLenum plane, const GLfixed *equation);

-void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);

-void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);

-void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);

-void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);

-void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);

-void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                          GLint border, GLsizei imageSize, const GLvoid* data);

-void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                             GLenum format, GLsizei imageSize, const GLvoid* data);

-void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);

-void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);

-void CullFace(GLenum mode);

-void DeleteBuffers(GLsizei n, const GLuint* buffers);

-void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);

-void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);

-void DeleteTextures(GLsizei n, const GLuint* textures);

-void DepthFunc(GLenum func);

-void DepthMask(GLboolean flag);

-void DepthRangex(GLclampx zNear, GLclampx zFar);

-void DepthRangef(GLclampf zNear, GLclampf zFar);

-void Disable(GLenum cap);

-void DisableClientState(GLenum array);

-void DrawArrays(GLenum mode, GLint first, GLsizei count);

-void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);

-void Enable(GLenum cap);

-void EnableClientState(GLenum array);

-void Finish(void);

-void Flush(void);

-void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);

-void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);

-void Fogf(GLenum pname, GLfloat param);

-void Fogfv(GLenum pname, const GLfloat *params);

-void Fogx(GLenum pname, GLfixed param);

-void Fogxv(GLenum pname, const GLfixed *params);

-void FrontFace(GLenum mode);

-void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);

-void GenerateMipmapOES(GLenum target);

-void GenBuffers(GLsizei n, GLuint* buffers);

-void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);

-void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);

-void GenTextures(GLsizei n, GLuint* textures);

-void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);

-void GetBooleanv(GLenum pname, GLboolean* params);

-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);

-void GetClipPlanef(GLenum pname, GLfloat eqn[4]);

-void GetClipPlanex(GLenum pname, GLfixed eqn[4]);

-GLenum GetError(void);

-void GetFixedv(GLenum pname, GLfixed *params);

-void GetFloatv(GLenum pname, GLfloat* params);

-void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);

-void GetIntegerv(GLenum pname, GLint* params);

-void GetLightfv(GLenum light, GLenum pname, GLfloat *params);

-void GetLightxv(GLenum light, GLenum pname, GLfixed *params);

-void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params);

-void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params);

-void GetPointerv(GLenum pname, GLvoid **params);

-const GLubyte* GetString(GLenum name);

-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);

-void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);

-void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params);

-void GetTexEnviv(GLenum env, GLenum pname, GLint *params);

-void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params);

-void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);

-void Hint(GLenum target, GLenum mode);

-GLboolean IsBuffer(GLuint buffer);

-GLboolean IsEnabled(GLenum cap);

-GLboolean IsFramebufferOES(GLuint framebuffer);

-GLboolean IsTexture(GLuint texture);

-GLboolean IsRenderbufferOES(GLuint renderbuffer);

-void LightModelf(GLenum pname, GLfloat param);

-void LightModelfv(GLenum pname, const GLfloat *params);

-void LightModelx(GLenum pname, GLfixed param);

-void LightModelxv(GLenum pname, const GLfixed *params);

-void Lightf(GLenum light, GLenum pname, GLfloat param);

-void Lightfv(GLenum light, GLenum pname, const GLfloat *params);

-void Lightx(GLenum light, GLenum pname, GLfixed param);

-void Lightxv(GLenum light, GLenum pname, const GLfixed *params);

-void LineWidth(GLfloat width);

-void LineWidthx(GLfixed width);

-void LoadIdentity(void);

-void LoadMatrixf(const GLfloat *m);

-void LoadMatrixx(const GLfixed *m);

-void LogicOp(GLenum opcode);

-void Materialf(GLenum face, GLenum pname, GLfloat param);

-void Materialfv(GLenum face, GLenum pname, const GLfloat *params);

-void Materialx(GLenum face, GLenum pname, GLfixed param);

-void Materialxv(GLenum face, GLenum pname, const GLfixed *params);

-void MatrixMode(GLenum mode);

-void MultMatrixf(const GLfloat *m);

-void MultMatrixx(const GLfixed *m);

-void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);

-void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);

-void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz);

-void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz);

-void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);

-void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);

-void PixelStorei(GLenum pname, GLint param);

-void PointParameterf(GLenum pname, GLfloat param);

-void PointParameterfv(GLenum pname, const GLfloat *params);

-void PointParameterx(GLenum pname, GLfixed param);

-void PointParameterxv(GLenum pname, const GLfixed *params);

-void PointSize(GLfloat size);

-void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer);

-void PointSizex(GLfixed size);

-void PolygonOffset(GLfloat factor, GLfloat units);

-void PolygonOffsetx(GLfixed factor, GLfixed units);

-void PopMatrix(void);

-void PushMatrix(void);

-void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);

-void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);

-void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

-void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);

-void SampleCoverage(GLclampf value, GLboolean invert);

-void SampleCoveragex(GLclampx value, GLboolean invert);

-void Scalef(GLfloat x, GLfloat y, GLfloat z);

-void Scalex(GLfixed x, GLfixed y, GLfixed z);

-void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);

-void ShadeModel(GLenum mode);

-void StencilFunc(GLenum func, GLint ref, GLuint mask);

-void StencilMask(GLuint mask);

-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);

-void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);

-void TexEnvf(GLenum target, GLenum pname, GLfloat param);

-void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params);

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

-void TexEnvx(GLenum target, GLenum pname, GLfixed param);

-void TexEnviv(GLenum target, GLenum pname, const GLint *params);

-void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params);

-void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                GLint border, GLenum format, GLenum type, const GLvoid* pixels);

-void TexParameterf(GLenum target, GLenum pname, GLfloat param);

-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);

-void TexParameteri(GLenum target, GLenum pname, GLint param);

-void TexParameteriv(GLenum target, GLenum pname, const GLint* params);

-void TexParameterx(GLenum target, GLenum pname, GLfixed param);

-void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params);

-void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                   GLenum format, GLenum type, const GLvoid* pixels);

-void Translatef(GLfloat x, GLfloat y, GLfloat z);

-void Translatex(GLfixed x, GLfixed y, GLfixed z);

-void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);

-void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);

-void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);

-void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);

-void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);

-void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height);

-void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);

-void DrawTexsvOES(const GLshort *coords);

-void DrawTexivOES(const GLint *coords);

-void DrawTexxvOES(const GLfixed *coords);

-void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);

-void DrawTexfvOES(const GLfloat *coords);

-}

-

-egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext);

-extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname);

-egl::Image *createBackBuffer(int width, int height, const egl::Config *config);

-egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType window, int width, int height);

-

-extern "C"

-{

-EGLAPI EGLint EGLAPIENTRY eglGetError(void)

-{

-	return libEGL->eglGetError();

-}

-

-EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)

-{

-	return libEGL->eglGetDisplay(display_id);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)

-{

-	return libEGL->eglInitialize(dpy, major, minor);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)

-{

-	return libEGL->eglTerminate(dpy);

-}

-

-EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)

-{

-	return libEGL->eglQueryString(dpy, name);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	return libEGL->eglGetConfigs(dpy, configs, config_size, num_config);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	return libEGL->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglGetConfigAttrib(dpy, config, attribute, value);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateWindowSurface(dpy, config, window, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)

-{

-	return libEGL->eglCreatePbufferSurface(dpy, config, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)

-{

-	return libEGL->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)

-{

-	return libEGL->eglDestroySurface(dpy, surface);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglQuerySurface(dpy, surface, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)

-{

-	return libEGL->eglBindAPI(api);

-}

-

-EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)

-{

-	return libEGL->eglQueryAPI();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)

-{

-	return libEGL->eglWaitClient();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)

-{

-	return libEGL->eglReleaseThread();

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)

-{

-	return libEGL->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)

-{

-	return libEGL->eglSurfaceAttrib(dpy, surface, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	return libEGL->eglBindTexImage(dpy, surface, buffer);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	return libEGL->eglReleaseTexImage(dpy, surface, buffer);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)

-{

-	return libEGL->eglSwapInterval(dpy, interval);

-}

-

-EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateContext(dpy, config, share_context, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)

-{

-	return libEGL->eglDestroyContext(dpy, ctx);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)

-{

-	return libEGL->eglMakeCurrent(dpy, draw, read, ctx);

-}

-

-EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)

-{

-	return libEGL->eglGetCurrentContext();

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)

-{

-	return libEGL->eglGetCurrentSurface(readdraw);

-}

-

-EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)

-{

-	return libEGL->eglGetCurrentDisplay();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglQueryContext(dpy, ctx, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)

-{

-	return libEGL->eglWaitGL();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)

-{

-	return libEGL->eglWaitNative(engine);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)

-{

-	return libEGL->eglSwapBuffers(dpy, surface);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)

-{

-	return libEGL->eglCopyBuffers(dpy, surface, target);

-}

-

-EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)

-{

-	return libEGL->eglDestroyImageKHR(dpy, image);

-}

-

-EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)

-{

-	return libEGL->eglGetProcAddress(procname);

-}

-

-EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateSyncKHR(dpy, type, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)

-{

-	return libEGL->eglDestroySyncKHR(dpy, sync);

-}

-

-EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)

-{

-	return libEGL->eglClientWaitSyncKHR(dpy, sync, flags, timeout);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglGetSyncAttribKHR(dpy, sync, attribute, value);

-}

-

-GL_API void GL_APIENTRY glActiveTexture(GLenum texture)

-{

-	return es1::ActiveTexture(texture);

-}

-

-GL_API void GL_APIENTRY glAlphaFunc(GLenum func, GLclampf ref)

-{

-	return es1::AlphaFunc(func, ref);

-}

-

-GL_API void GL_APIENTRY glAlphaFuncx(GLenum func, GLclampx ref)

-{

-	return es1::AlphaFuncx(func, ref);

-}

-

-GL_API void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)

-{

-	return es1::BindBuffer(target, buffer);

-}

-

-GL_API void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)

-{

-	return es1::BindFramebuffer(target, framebuffer);

-}

-

-GL_API void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)

-{

-	return es1::BindFramebufferOES(target, framebuffer);

-}

-

-GL_API void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)

-{

-	return es1::BindRenderbufferOES(target, renderbuffer);

-}

-

-GL_API void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)

-{

-	return es1::BindTexture(target, texture);

-}

-

-GL_API void GL_APIENTRY glBlendEquationOES(GLenum mode)

-{

-	return es1::BlendEquationSeparateOES(mode, mode);

-}

-

-GL_API void GL_APIENTRY glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)

-{

-	return es1::BlendEquationSeparateOES(modeRGB, modeAlpha);

-}

-

-GL_API void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)

-{

-	return es1::BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);

-}

-

-GL_API void GL_APIENTRY glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)

-{

-	return es1::BlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);

-}

-

-GL_API void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)

-{

-	return es1::BufferData(target, size, data, usage);

-}

-

-GL_API void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)

-{

-	return es1::BufferSubData(target, offset, size, data);

-}

-

-GL_API GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)

-{

-	return es1::CheckFramebufferStatusOES(target);

-}

-

-GL_API void GL_APIENTRY glClear(GLbitfield mask)

-{

-	return es1::Clear(mask);

-}

-

-GL_API void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	return es1::ClearColor(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)

-{

-	return es1::ClearColorx(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glClearDepthf(GLclampf depth)

-{

-	return es1::ClearDepthf(depth);

-}

-

-GL_API void GL_APIENTRY glClearDepthx(GLclampx depth)

-{

-	return es1::ClearDepthx(depth);

-}

-

-GL_API void GL_APIENTRY glClearStencil(GLint s)

-{

-	return es1::ClearStencil(s);

-}

-

-GL_API void GL_APIENTRY glClientActiveTexture(GLenum texture)

-{

-	return es1::ClientActiveTexture(texture);

-}

-

-GL_API void GL_APIENTRY glClipPlanef(GLenum plane, const GLfloat *equation)

-{

-	return es1::ClipPlanef(plane, equation);

-}

-

-GL_API void GL_APIENTRY glClipPlanex(GLenum plane, const GLfixed *equation)

-{

-	return es1::ClipPlanex(plane, equation);

-}

-

-GL_API void GL_APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)

-{

-	return es1::Color4f(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)

-{

-	return es1::Color4ub(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)

-{

-	return es1::Color4x(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)

-{

-	return es1::ColorMask(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::ColorPointer(size, type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                                               GLint border, GLsizei imageSize, const GLvoid* data)

-{

-	return es1::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);

-}

-

-GL_API void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                                                  GLenum format, GLsizei imageSize, const GLvoid* data)

-{

-	return es1::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);

-}

-

-GL_API void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)

-{

-	return es1::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);

-}

-

-GL_API void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es1::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);

-}

-

-GL_API void GL_APIENTRY glCullFace(GLenum mode)

-{

-	return es1::CullFace(mode);

-}

-

-GL_API void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)

-{

-	return es1::DeleteBuffers(n, buffers);

-}

-

-GL_API void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)

-{

-	return es1::DeleteFramebuffersOES(n, framebuffers);

-}

-

-GL_API void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)

-{

-	return es1::DeleteRenderbuffersOES(n, renderbuffers);

-}

-

-GL_API void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)

-{

-	return es1::DeleteTextures(n, textures);

-}

-

-GL_API void GL_APIENTRY glDepthFunc(GLenum func)

-{

-	return es1::DepthFunc(func);

-}

-

-GL_API void GL_APIENTRY glDepthMask(GLboolean flag)

-{

-	return es1::DepthMask(flag);

-}

-

-GL_API void GL_APIENTRY glDepthRangex(GLclampx zNear, GLclampx zFar)

-{

-	return es1::DepthRangex(zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)

-{

-	return es1::DepthRangef(zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glDisable(GLenum cap)

-{

-	return es1::Disable(cap);

-}

-

-GL_API void GL_APIENTRY glDisableClientState(GLenum array)

-{

-	return es1::DisableClientState(array);

-}

-

-GL_API void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)

-{

-	return es1::DrawArrays(mode, first, count);

-}

-

-GL_API void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)

-{

-	return es1::DrawElements(mode, count, type, indices);

-}

-

-GL_API void GL_APIENTRY glEnable(GLenum cap)

-{

-	return es1::Enable(cap);

-}

-

-GL_API void GL_APIENTRY glEnableClientState(GLenum array)

-{

-	return es1::EnableClientState(array);

-}

-

-GL_API void GL_APIENTRY glFinish(void)

-{

-	return es1::Finish();

-}

-

-GL_API void GL_APIENTRY glFlush(void)

-{

-	return es1::Flush();

-}

-

-GL_API void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	return es1::FramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);

-}

-

-GL_API void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	return es1::FramebufferTexture2DOES(target, attachment, textarget, texture, level);

-}

-

-GL_API void GL_APIENTRY glFogf(GLenum pname, GLfloat param)

-{

-	return es1::Fogf(pname, param);

-}

-

-GL_API void GL_APIENTRY glFogfv(GLenum pname, const GLfloat *params)

-{

-	return es1::Fogfv(pname, params);

-}

-

-GL_API void GL_APIENTRY glFogx(GLenum pname, GLfixed param)

-{

-	return es1::Fogx(pname, param);

-}

-

-GL_API void GL_APIENTRY glFogxv(GLenum pname, const GLfixed *params)

-{

-	return es1::Fogxv(pname, params);

-}

-

-GL_API void GL_APIENTRY glFrontFace(GLenum mode)

-{

-	return es1::FrontFace(mode);

-}

-

-GL_API void GL_APIENTRY glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	return es1::Frustumf(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	return es1::Frustumx(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glGenerateMipmapOES(GLenum target)

-{

-	return es1::GenerateMipmapOES(target);

-}

-

-GL_API void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)

-{

-	return es1::GenBuffers(n, buffers);

-}

-

-GL_API void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)

-{

-	return es1::GenFramebuffersOES(n, framebuffers);

-}

-

-GL_API void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)

-{

-	return es1::GenRenderbuffersOES(n, renderbuffers);

-}

-

-GL_API void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)

-{

-	return es1::GenTextures(n, textures);

-}

-

-GL_API void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)

-{

-	return es1::GetRenderbufferParameterivOES(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)

-{

-	return es1::GetBooleanv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

-	return es1::GetBufferParameteriv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetClipPlanef(GLenum pname, GLfloat eqn[4])

-{

-	return es1::GetClipPlanef(pname, eqn);

-}

-

-GL_API void GL_APIENTRY glGetClipPlanex(GLenum pname, GLfixed eqn[4])

-{

-	return es1::GetClipPlanex(pname, eqn);

-}

-

-GL_API GLenum GL_APIENTRY glGetError(void)

-{

-	return es1::GetError();

-}

-

-GL_API void GL_APIENTRY glGetFixedv(GLenum pname, GLfixed *params)

-{

-	return es1::GetFixedv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)

-{

-	return es1::GetFloatv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	return es1::GetFramebufferAttachmentParameterivOES(target, attachment, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)

-{

-	return es1::GetIntegerv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)

-{

-	return es1::GetLightfv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetLightxv(GLenum light, GLenum pname, GLfixed *params)

-{

-	return es1::GetLightxv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)

-{

-	return es1::GetMaterialfv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)

-{

-	return es1::GetMaterialxv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetPointerv(GLenum pname, GLvoid **params)

-{

-	return es1::GetPointerv(pname, params);

-}

-

-GL_API const GLubyte* GL_APIENTRY glGetString(GLenum name)

-{

-	return es1::GetString(name);

-}

-

-GL_API void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)

-{

-	return es1::GetTexParameterfv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)

-{

-	return es1::GetTexParameteriv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)

-{

-	return es1::GetTexEnvfv(env, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexEnviv(GLenum env, GLenum pname, GLint *params)

-{

-	return es1::GetTexEnviv(env, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)

-{

-	return es1::GetTexEnvxv(env, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)

-{

-	return es1::GetTexParameterxv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glHint(GLenum target, GLenum mode)

-{

-	return es1::Hint(target, mode);

-}

-

-GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)

-{

-	return es1::IsBuffer(buffer);

-}

-

-GL_API GLboolean GL_APIENTRY glIsEnabled(GLenum cap)

-{

-	return es1::IsEnabled(cap);

-}

-

-GL_API GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)

-{

-	return es1::IsFramebufferOES(framebuffer);

-}

-

-GL_API GLboolean GL_APIENTRY glIsTexture(GLuint texture)

-{

-	return es1::IsTexture(texture);

-}

-

-GL_API GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)

-{

-	return es1::IsRenderbufferOES(renderbuffer);

-}

-

-GL_API void GL_APIENTRY glLightModelf(GLenum pname, GLfloat param)

-{

-	return es1::LightModelf(pname, param);

-}

-

-GL_API void GL_APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)

-{

-	return es1::LightModelfv(pname, params);

-}

-

-GL_API void GL_APIENTRY glLightModelx(GLenum pname, GLfixed param)

-{

-	return es1::LightModelx(pname, param);

-}

-

-GL_API void GL_APIENTRY glLightModelxv(GLenum pname, const GLfixed *params)

-{

-	return es1::LightModelxv(pname, params);

-}

-

-GL_API void GL_APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)

-{

-	return es1::Lightf(light, pname, param);

-}

-

-GL_API void GL_APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)

-{

-	return es1::Lightfv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glLightx(GLenum light, GLenum pname, GLfixed param)

-{

-	return es1::Lightx(light, pname, param);

-}

-

-GL_API void GL_APIENTRY glLightxv(GLenum light, GLenum pname, const GLfixed *params)

-{

-	return es1::Lightxv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glLineWidth(GLfloat width)

-{

-	return es1::LineWidth(width);

-}

-

-GL_API void GL_APIENTRY glLineWidthx(GLfixed width)

-{

-	return es1::LineWidthx(width);

-}

-

-GL_API void GL_APIENTRY glLoadIdentity(void)

-{

-	return es1::LoadIdentity();

-}

-

-GL_API void GL_APIENTRY glLoadMatrixf(const GLfloat *m)

-{

-	return es1::LoadMatrixf(m);

-}

-

-GL_API void GL_APIENTRY glLoadMatrixx(const GLfixed *m)

-{

-	return es1::LoadMatrixx(m);

-}

-

-GL_API void GL_APIENTRY glLogicOp(GLenum opcode)

-{

-	return es1::LogicOp(opcode);

-}

-

-GL_API void GL_APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)

-{

-	return es1::Materialf(face, pname, param);

-}

-

-GL_API void GL_APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)

-{

-	return es1::Materialfv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glMaterialx(GLenum face, GLenum pname, GLfixed param)

-{

-	return es1::Materialx(face, pname, param);

-}

-

-GL_API void GL_APIENTRY glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)

-{

-	return es1::Materialxv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glMatrixMode(GLenum mode)

-{

-	return es1::MatrixMode(mode);

-}

-

-GL_API void GL_APIENTRY glMultMatrixf(const GLfloat *m)

-{

-	return es1::MultMatrixf(m);

-}

-

-GL_API void GL_APIENTRY glMultMatrixx(const GLfixed *m)

-{

-	return es1::MultMatrixx(m);

-}

-

-GL_API void GL_APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)

-{

-	return es1::MultiTexCoord4f(target, s, t, r, q);

-}

-

-GL_API void GL_APIENTRY glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)

-{

-	return es1::MultiTexCoord4x(target, s, t, r, q);

-}

-

-GL_API void GL_APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)

-{

-	return es1::Normal3f(nx, ny, nz);

-}

-

-GL_API void GL_APIENTRY glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)

-{

-	return es1::Normal3x(nx, ny, nz);

-}

-

-GL_API void GL_APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::NormalPointer(type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	return es1::Orthof(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	return es1::Orthox(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)

-{

-	return es1::PixelStorei(pname, param);

-}

-

-GL_API void GL_APIENTRY glPointParameterf(GLenum pname, GLfloat param)

-{

-	return es1::PointParameterf(pname, param);

-}

-

-GL_API void GL_APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params)

-{

-	return es1::PointParameterfv(pname, params);

-}

-

-GL_API void GL_APIENTRY glPointParameterx(GLenum pname, GLfixed param)

-{

-	return es1::PointParameterx(pname, param);

-}

-

-GL_API void GL_APIENTRY glPointParameterxv(GLenum pname, const GLfixed *params)

-{

-	return es1::PointParameterxv(pname, params);

-}

-

-GL_API void GL_APIENTRY glPointSize(GLfloat size)

-{

-	return es1::PointSize(size);

-}

-

-GL_API void GL_APIENTRY glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::PointSizePointerOES(type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glPointSizex(GLfixed size)

-{

-	return es1::PointSizex(size);

-}

-

-GL_API void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)

-{

-	return es1::PolygonOffset(factor, units);

-}

-

-GL_API void GL_APIENTRY glPolygonOffsetx(GLfixed factor, GLfixed units)

-{

-	return es1::PolygonOffsetx(factor, units);

-}

-

-GL_API void GL_APIENTRY glPopMatrix(void)

-{

-	return es1::PopMatrix();

-}

-

-GL_API void GL_APIENTRY glPushMatrix(void)

-{

-	return es1::PushMatrix();

-}

-

-GL_API void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)

-{

-	return es1::ReadPixels(x, y, width, height, format, type, pixels);

-}

-

-GL_API void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	return es1::RenderbufferStorageOES(target, internalformat, width, height);

-}

-

-GL_API void GL_APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-	return es1::Rotatef(angle, x, y, z);

-}

-

-GL_API void GL_APIENTRY glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)

-{

-	return es1::Rotatex(angle, x, y, z);

-}

-

-GL_API void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)

-{

-	return es1::SampleCoverage(value, invert);

-}

-

-GL_API void GL_APIENTRY glSampleCoveragex(GLclampx value, GLboolean invert)

-{

-	return es1::SampleCoveragex(value, invert);

-}

-

-GL_API void GL_APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)

-{

-	return es1::Scalef(x, y, z);

-}

-

-GL_API void GL_APIENTRY glScalex(GLfixed x, GLfixed y, GLfixed z)

-{

-	return es1::Scalex(x, y, z);

-}

-

-GL_API void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es1::Scissor(x, y, width, height);

-}

-

-GL_API void GL_APIENTRY glShadeModel(GLenum mode)

-{

-	return es1::ShadeModel(mode);

-}

-

-GL_API void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)

-{

-	return es1::StencilFunc(func, ref, mask);

-}

-

-GL_API void GL_APIENTRY glStencilMask(GLuint mask)

-{

-	return es1::StencilMask(mask);

-}

-

-GL_API void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)

-{

-	return es1::StencilOp(fail, zfail, zpass);

-}

-

-GL_API void GL_APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::TexCoordPointer(size, type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)

-{

-	return es1::TexEnvf(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)

-{

-	return es1::TexEnvfv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)

-{

-	return es1::TexEnvi(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexEnvx(GLenum target, GLenum pname, GLfixed param)

-{

-	return es1::TexEnvx(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)

-{

-	return es1::TexEnviv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	return es1::TexEnvxv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                                     GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	return es1::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);

-}

-

-GL_API void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)

-{

-	return es1::TexParameterf(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)

-{

-	return es1::TexParameterfv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)

-{

-	return es1::TexParameteri(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)

-{

-	return es1::TexParameteriv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexParameterx(GLenum target, GLenum pname, GLfixed param)

-{

-	return es1::TexParameterx(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	return es1::TexParameterxv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                                        GLenum format, GLenum type, const GLvoid* pixels)

-{

-	return es1::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);

-}

-

-GL_API void GL_APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)

-{

-	return es1::Translatef(x, y, z);

-}

-

-GL_API void GL_APIENTRY glTranslatex(GLfixed x, GLfixed y, GLfixed z)

-{

-	return es1::Translatex(x, y, z);

-}

-

-GL_API void GL_APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::VertexPointer(size, type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es1::Viewport(x, y, width, height);

-}

-

-GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)

-{

-	return es1::EGLImageTargetTexture2DOES(target, image);

-}

-

-GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)

-{

-	return es1::EGLImageTargetRenderbufferStorageOES(target, image);

-}

-

-GL_API void GL_APIENTRY glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)

-{

-	return es1::DrawTexsOES(x,y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)

-{

-	return es1::DrawTexiOES(x,y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)

-{

-	return es1::DrawTexxOES(x,y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexsvOES(const GLshort *coords)

-{

-	return es1::DrawTexsvOES(coords);

-}

-

-GL_API void GL_APIENTRY glDrawTexivOES(const GLint *coords)

-{

-	return es1::DrawTexivOES(coords);

-}

-

-GL_API void GL_APIENTRY glDrawTexxvOES(const GLfixed *coords)

-{

-	return es1::DrawTexxvOES(coords);

-}

-

-GL_API void GL_APIENTRY glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)

-{

-	return es1::DrawTexfOES(x, y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexfvOES(const GLfloat *coords)

-{

-	return es1::DrawTexfvOES(coords);

-}

-

-}

-

-LibGLES_CMexports::LibGLES_CMexports()

-{

-	this->glActiveTexture = es1::ActiveTexture;

-	this->glAlphaFunc = es1::AlphaFunc;

-	this->glAlphaFuncx = es1::AlphaFuncx;

-	this->glBindBuffer = es1::BindBuffer;

-	this->glBindFramebuffer = es1::BindFramebuffer;

-	this->glBindFramebufferOES = es1::BindFramebufferOES;

-	this->glBindRenderbufferOES = es1::BindRenderbufferOES;

-	this->glBindTexture = es1::BindTexture;

-	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;

-	this->glBlendEquationOES = es1::BlendEquationOES;

-	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;

-	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;

-	this->glBlendFunc = es1::BlendFunc;

-	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;

-	this->glBufferData = es1::BufferData;

-	this->glBufferSubData = es1::BufferSubData;

-	this->glCheckFramebufferStatusOES = es1::CheckFramebufferStatusOES;

-	this->glClear = es1::Clear;

-	this->glClearColor = es1::ClearColor;

-	this->glClearColorx = es1::ClearColorx;

-	this->glClearDepthf = es1::ClearDepthf;

-	this->glClearDepthx = es1::ClearDepthx;

-	this->glClearStencil = es1::ClearStencil;

-	this->glClientActiveTexture = es1::ClientActiveTexture;

-	this->glClipPlanef = es1::ClipPlanef;

-	this->glClipPlanex = es1::ClipPlanex;

-	this->glColor4f = es1::Color4f;

-	this->glColor4ub = es1::Color4ub;

-	this->glColor4x = es1::Color4x;

-	this->glColorMask = es1::ColorMask;

-	this->glColorPointer = es1::ColorPointer;

-	this->glCompressedTexImage2D = es1::CompressedTexImage2D;

-	this->glCompressedTexSubImage2D = es1::CompressedTexSubImage2D;

-	this->glCopyTexImage2D = es1::CopyTexImage2D;

-	this->glCopyTexSubImage2D = es1::CopyTexSubImage2D;

-	this->glCullFace = es1::CullFace;

-	this->glDeleteBuffers = es1::DeleteBuffers;

-	this->glDeleteFramebuffersOES = es1::DeleteFramebuffersOES;

-	this->glDeleteRenderbuffersOES = es1::DeleteRenderbuffersOES;

-	this->glDeleteTextures = es1::DeleteTextures;

-	this->glDepthFunc = es1::DepthFunc;

-	this->glDepthMask = es1::DepthMask;

-	this->glDepthRangex = es1::DepthRangex;

-	this->glDepthRangef = es1::DepthRangef;

-	this->glDisable = es1::Disable;

-	this->glDisableClientState = es1::DisableClientState;

-	this->glDrawArrays = es1::DrawArrays;

-	this->glDrawElements = es1::DrawElements;

-	this->glEnable = es1::Enable;

-	this->glEnableClientState = es1::EnableClientState;

-	this->glFinish = es1::Finish;

-	this->glFlush = es1::Flush;

-	this->glFramebufferRenderbufferOES = es1::FramebufferRenderbufferOES;

-	this->glFramebufferTexture2DOES = es1::FramebufferTexture2DOES;

-	this->glFogf = es1::Fogf;

-	this->glFogfv = es1::Fogfv;

-	this->glFogx = es1::Fogx;

-	this->glFogxv = es1::Fogxv;

-	this->glFrontFace = es1::FrontFace;

-	this->glFrustumf = es1::Frustumf;

-	this->glFrustumx = es1::Frustumx;

-	this->glGenerateMipmapOES = es1::GenerateMipmapOES;

-	this->glGenBuffers = es1::GenBuffers;

-	this->glGenFramebuffersOES = es1::GenFramebuffersOES;

-	this->glGenRenderbuffersOES = es1::GenRenderbuffersOES;

-	this->glGenTextures = es1::GenTextures;

-	this->glGetRenderbufferParameterivOES = es1::GetRenderbufferParameterivOES;

-	this->glGetBooleanv = es1::GetBooleanv;

-	this->glGetBufferParameteriv = es1::GetBufferParameteriv;

-	this->glGetClipPlanef = es1::GetClipPlanef;

-	this->glGetClipPlanex = es1::GetClipPlanex;

-	this->glGetError = es1::GetError;

-	this->glGetFixedv = es1::GetFixedv;

-	this->glGetFloatv = es1::GetFloatv;

-	this->glGetFramebufferAttachmentParameterivOES = es1::GetFramebufferAttachmentParameterivOES;

-	this->glGetIntegerv = es1::GetIntegerv;

-	this->glGetLightfv = es1::GetLightfv;

-	this->glGetLightxv = es1::GetLightxv;

-	this->glGetMaterialfv = es1::GetMaterialfv;

-	this->glGetMaterialxv = es1::GetMaterialxv;

-	this->glGetPointerv = es1::GetPointerv;

-	this->glGetString = es1::GetString;

-	this->glGetTexParameterfv = es1::GetTexParameterfv;

-	this->glGetTexParameteriv = es1::GetTexParameteriv;

-	this->glGetTexEnvfv = es1::GetTexEnvfv;

-	this->glGetTexEnviv = es1::GetTexEnviv;

-	this->glGetTexEnvxv = es1::GetTexEnvxv;

-	this->glGetTexParameterxv = es1::GetTexParameterxv;

-	this->glHint = es1::Hint;

-	this->glIsBuffer = es1::IsBuffer;

-	this->glIsEnabled = es1::IsEnabled;

-	this->glIsFramebufferOES = es1::IsFramebufferOES;

-	this->glIsTexture = es1::IsTexture;

-	this->glIsRenderbufferOES = es1::IsRenderbufferOES;

-	this->glLightModelf = es1::LightModelf;

-	this->glLightModelfv = es1::LightModelfv;

-	this->glLightModelx = es1::LightModelx;

-	this->glLightModelxv = es1::LightModelxv;

-	this->glLightf = es1::Lightf;

-	this->glLightfv = es1::Lightfv;

-	this->glLightx = es1::Lightx;

-	this->glLightxv = es1::Lightxv;

-	this->glLineWidth = es1::LineWidth;

-	this->glLineWidthx = es1::LineWidthx;

-	this->glLoadIdentity = es1::LoadIdentity;

-	this->glLoadMatrixf = es1::LoadMatrixf;

-	this->glLoadMatrixx = es1::LoadMatrixx;

-	this->glLogicOp = es1::LogicOp;

-	this->glMaterialf = es1::Materialf;

-	this->glMaterialfv = es1::Materialfv;

-	this->glMaterialx = es1::Materialx;

-	this->glMaterialxv = es1::Materialxv;

-	this->glMatrixMode = es1::MatrixMode;

-	this->glMultMatrixf = es1::MultMatrixf;

-	this->glMultMatrixx = es1::MultMatrixx;

-	this->glMultiTexCoord4f = es1::MultiTexCoord4f;

-	this->glMultiTexCoord4x = es1::MultiTexCoord4x;

-	this->glNormal3f = es1::Normal3f;

-	this->glNormal3x = es1::Normal3x;

-	this->glNormalPointer = es1::NormalPointer;

-	this->glOrthof = es1::Orthof;

-	this->glOrthox = es1::Orthox;

-	this->glPixelStorei = es1::PixelStorei;

-	this->glPointParameterf = es1::PointParameterf;

-	this->glPointParameterfv = es1::PointParameterfv;

-	this->glPointParameterx = es1::PointParameterx;

-	this->glPointParameterxv = es1::PointParameterxv;

-	this->glPointSize = es1::PointSize;

-	this->glPointSizePointerOES = es1::PointSizePointerOES;

-	this->glPointSizex = es1::PointSizex;

-	this->glPolygonOffset = es1::PolygonOffset;

-	this->glPolygonOffsetx = es1::PolygonOffsetx;

-	this->glPopMatrix = es1::PopMatrix;

-	this->glPushMatrix = es1::PushMatrix;

-	this->glReadPixels = es1::ReadPixels;

-	this->glRenderbufferStorageOES = es1::RenderbufferStorageOES;

-	this->glRotatef = es1::Rotatef;

-	this->glRotatex = es1::Rotatex;

-	this->glSampleCoverage = es1::SampleCoverage;

-	this->glSampleCoveragex = es1::SampleCoveragex;

-	this->glScalef = es1::Scalef;

-	this->glScalex = es1::Scalex;

-	this->glScissor = es1::Scissor;

-	this->glShadeModel = es1::ShadeModel;

-	this->glStencilFunc = es1::StencilFunc;

-	this->glStencilMask = es1::StencilMask;

-	this->glStencilOp = es1::StencilOp;

-	this->glTexCoordPointer = es1::TexCoordPointer;

-	this->glTexEnvf = es1::TexEnvf;

-	this->glTexEnvfv = es1::TexEnvfv;

-	this->glTexEnvi = es1::TexEnvi;

-	this->glTexEnvx = es1::TexEnvx;

-	this->glTexEnviv = es1::TexEnviv;

-	this->glTexEnvxv = es1::TexEnvxv;

-	this->glTexImage2D = es1::TexImage2D;

-	this->glTexParameterf = es1::TexParameterf;

-	this->glTexParameterfv = es1::TexParameterfv;

-	this->glTexParameteri = es1::TexParameteri;

-	this->glTexParameteriv = es1::TexParameteriv;

-	this->glTexParameterx = es1::TexParameterx;

-	this->glTexParameterxv = es1::TexParameterxv;

-	this->glTexSubImage2D = es1::TexSubImage2D;

-	this->glTranslatef = es1::Translatef;

-	this->glTranslatex = es1::Translatex;

-	this->glVertexPointer = es1::VertexPointer;

-	this->glViewport = es1::Viewport;

-	this->glEGLImageTargetTexture2DOES = es1::EGLImageTargetTexture2DOES;

-	this->glEGLImageTargetRenderbufferStorageOES = es1::EGLImageTargetRenderbufferStorageOES;

-	this->glDrawTexsOES = es1::DrawTexsOES;

-	this->glDrawTexiOES = es1::DrawTexiOES;

-	this->glDrawTexxOES = es1::DrawTexxOES;

-	this->glDrawTexsvOES = es1::DrawTexsvOES;

-	this->glDrawTexivOES = es1::DrawTexivOES;

-	this->glDrawTexxvOES = es1::DrawTexxvOES;

-	this->glDrawTexfOES = es1::DrawTexfOES;

-	this->glDrawTexfvOES = es1::DrawTexfvOES;

-

-	this->es1CreateContext = ::es1CreateContext;

-	this->es1GetProcAddress = ::es1GetProcAddress;

-	this->createBackBuffer = ::createBackBuffer;

-	this->createDepthStencil = ::createDepthStencil;

-	this->createFrameBuffer = ::createFrameBuffer;

-}

-

-extern "C" GL_API LibGLES_CMexports *libGLES_CM_swiftshader()

-{

-	static LibGLES_CMexports libGLES_CM;

-	return &libGLES_CM;

-}

-

-LibEGL libEGL;

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// main.cpp: DLL entry point and management of thread-local data.
+
+#include "main.h"
+
+#include "libGLES_CM.hpp"
+#include "Framebuffer.h"
+#include "libEGL/Surface.h"
+#include "Common/Thread.hpp"
+#include "Common/SharedLibrary.hpp"
+#include "common/debug.h"
+
+#include <GLES/glext.h>
+
+#if !defined(_MSC_VER)
+#define CONSTRUCTOR __attribute__((constructor))
+#define DESTRUCTOR __attribute__((destructor))
+#else
+#define CONSTRUCTOR
+#define DESTRUCTOR
+#endif
+
+static void glAttachThread()
+{
+	TRACE("()");
+}
+
+static void glDetachThread()
+{
+	TRACE("()");
+}
+
+CONSTRUCTOR static void glAttachProcess()
+{
+	TRACE("()");
+
+	glAttachThread();
+}
+
+DESTRUCTOR static void glDetachProcess()
+{
+	TRACE("()");
+
+	glDetachThread();
+}
+
+#if defined(_WIN32)
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+	switch(reason)
+	{
+	case DLL_PROCESS_ATTACH:
+		glAttachProcess();
+		break;
+	case DLL_THREAD_ATTACH:
+		glAttachThread();
+		break;
+	case DLL_THREAD_DETACH:
+		glDetachThread();
+		break;
+	case DLL_PROCESS_DETACH:
+		glDetachProcess();
+		break;
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+#endif
+
+namespace es1
+{
+es1::Context *getContext()
+{
+	egl::Context *context = libEGL->clientGetCurrentContext();
+
+	if(context && context->getClientVersion() == 1)
+	{
+		return static_cast<es1::Context*>(context);
+	}
+
+	return 0;
+}
+
+Device *getDevice()
+{
+	Context *context = getContext();
+
+	return context ? context->getDevice() : 0;
+}
+
+// Records an error code
+void error(GLenum errorCode)
+{
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(errorCode)
+		{
+		case GL_INVALID_ENUM:
+			context->recordInvalidEnum();
+			TRACE("\t! Error generated: invalid enum\n");
+			break;
+		case GL_INVALID_VALUE:
+			context->recordInvalidValue();
+			TRACE("\t! Error generated: invalid value\n");
+			break;
+		case GL_INVALID_OPERATION:
+			context->recordInvalidOperation();
+			TRACE("\t! Error generated: invalid operation\n");
+			break;
+		case GL_OUT_OF_MEMORY:
+			context->recordOutOfMemory();
+			TRACE("\t! Error generated: out of memory\n");
+			break;
+		case GL_INVALID_FRAMEBUFFER_OPERATION_OES:
+			context->recordInvalidFramebufferOperation();
+			TRACE("\t! Error generated: invalid framebuffer operation\n");
+			break;
+		case GL_STACK_OVERFLOW:
+			context->recordMatrixStackOverflow();
+			TRACE("\t! Error generated: matrix stack overflow\n");
+			break;
+		case GL_STACK_UNDERFLOW:
+			context->recordMatrixStackUnderflow();
+			TRACE("\t! Error generated: matrix stack underflow\n");
+			break;
+		default: UNREACHABLE(errorCode);
+		}
+	}
+}
+}
+
+namespace es1
+{
+void ActiveTexture(GLenum texture);
+void AlphaFunc(GLenum func, GLclampf ref);
+void AlphaFuncx(GLenum func, GLclampx ref);
+void BindBuffer(GLenum target, GLuint buffer);
+void BindFramebuffer(GLenum target, GLuint framebuffer);
+void BindFramebufferOES(GLenum target, GLuint framebuffer);
+void BindRenderbufferOES(GLenum target, GLuint renderbuffer);
+void BindTexture(GLenum target, GLuint texture);
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+void BlendEquationOES(GLenum mode);
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void BlendFunc(GLenum sfactor, GLenum dfactor);
+void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+GLenum CheckFramebufferStatusOES(GLenum target);
+void Clear(GLbitfield mask);
+void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+void ClearDepthf(GLclampf depth);
+void ClearDepthx(GLclampx depth);
+void ClearStencil(GLint s);
+void ClientActiveTexture(GLenum texture);
+void ClipPlanef(GLenum plane, const GLfloat *equation);
+void ClipPlanex(GLenum plane, const GLfixed *equation);
+void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                          GLint border, GLsizei imageSize, const GLvoid* data);
+void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                             GLenum format, GLsizei imageSize, const GLvoid* data);
+void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+void CullFace(GLenum mode);
+void DeleteBuffers(GLsizei n, const GLuint* buffers);
+void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);
+void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);
+void DeleteTextures(GLsizei n, const GLuint* textures);
+void DepthFunc(GLenum func);
+void DepthMask(GLboolean flag);
+void DepthRangex(GLclampx zNear, GLclampx zFar);
+void DepthRangef(GLclampf zNear, GLclampf zFar);
+void Disable(GLenum cap);
+void DisableClientState(GLenum array);
+void DrawArrays(GLenum mode, GLint first, GLsizei count);
+void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+void Enable(GLenum cap);
+void EnableClientState(GLenum array);
+void Finish(void);
+void Flush(void);
+void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void Fogf(GLenum pname, GLfloat param);
+void Fogfv(GLenum pname, const GLfloat *params);
+void Fogx(GLenum pname, GLfixed param);
+void Fogxv(GLenum pname, const GLfixed *params);
+void FrontFace(GLenum mode);
+void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void GenerateMipmapOES(GLenum target);
+void GenBuffers(GLsizei n, GLuint* buffers);
+void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);
+void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);
+void GenTextures(GLsizei n, GLuint* textures);
+void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);
+void GetBooleanv(GLenum pname, GLboolean* params);
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetClipPlanef(GLenum pname, GLfloat eqn[4]);
+void GetClipPlanex(GLenum pname, GLfixed eqn[4]);
+GLenum GetError(void);
+void GetFixedv(GLenum pname, GLfixed *params);
+void GetFloatv(GLenum pname, GLfloat* params);
+void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+void GetIntegerv(GLenum pname, GLint* params);
+void GetLightfv(GLenum light, GLenum pname, GLfloat *params);
+void GetLightxv(GLenum light, GLenum pname, GLfixed *params);
+void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
+void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params);
+void GetPointerv(GLenum pname, GLvoid **params);
+const GLubyte* GetString(GLenum name);
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params);
+void GetTexEnviv(GLenum env, GLenum pname, GLint *params);
+void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params);
+void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
+void Hint(GLenum target, GLenum mode);
+GLboolean IsBuffer(GLuint buffer);
+GLboolean IsEnabled(GLenum cap);
+GLboolean IsFramebufferOES(GLuint framebuffer);
+GLboolean IsTexture(GLuint texture);
+GLboolean IsRenderbufferOES(GLuint renderbuffer);
+void LightModelf(GLenum pname, GLfloat param);
+void LightModelfv(GLenum pname, const GLfloat *params);
+void LightModelx(GLenum pname, GLfixed param);
+void LightModelxv(GLenum pname, const GLfixed *params);
+void Lightf(GLenum light, GLenum pname, GLfloat param);
+void Lightfv(GLenum light, GLenum pname, const GLfloat *params);
+void Lightx(GLenum light, GLenum pname, GLfixed param);
+void Lightxv(GLenum light, GLenum pname, const GLfixed *params);
+void LineWidth(GLfloat width);
+void LineWidthx(GLfixed width);
+void LoadIdentity(void);
+void LoadMatrixf(const GLfloat *m);
+void LoadMatrixx(const GLfixed *m);
+void LogicOp(GLenum opcode);
+void Materialf(GLenum face, GLenum pname, GLfloat param);
+void Materialfv(GLenum face, GLenum pname, const GLfloat *params);
+void Materialx(GLenum face, GLenum pname, GLfixed param);
+void Materialxv(GLenum face, GLenum pname, const GLfixed *params);
+void MatrixMode(GLenum mode);
+void MultMatrixf(const GLfloat *m);
+void MultMatrixx(const GLfixed *m);
+void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz);
+void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz);
+void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
+void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void PixelStorei(GLenum pname, GLint param);
+void PointParameterf(GLenum pname, GLfloat param);
+void PointParameterfv(GLenum pname, const GLfloat *params);
+void PointParameterx(GLenum pname, GLfixed param);
+void PointParameterxv(GLenum pname, const GLfixed *params);
+void PointSize(GLfloat size);
+void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer);
+void PointSizex(GLfixed size);
+void PolygonOffset(GLfloat factor, GLfloat units);
+void PolygonOffsetx(GLfixed factor, GLfixed units);
+void PopMatrix(void);
+void PushMatrix(void);
+void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+void SampleCoverage(GLclampf value, GLboolean invert);
+void SampleCoveragex(GLclampx value, GLboolean invert);
+void Scalef(GLfloat x, GLfloat y, GLfloat z);
+void Scalex(GLfixed x, GLfixed y, GLfixed z);
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+void ShadeModel(GLenum mode);
+void StencilFunc(GLenum func, GLint ref, GLuint mask);
+void StencilMask(GLuint mask);
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void TexEnvf(GLenum target, GLenum pname, GLfloat param);
+void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params);
+void TexEnvi(GLenum target, GLenum pname, GLint param);
+void TexEnvx(GLenum target, GLenum pname, GLfixed param);
+void TexEnviv(GLenum target, GLenum pname, const GLint *params);
+void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params);
+void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+void TexParameterf(GLenum target, GLenum pname, GLfloat param);
+void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+void TexParameteri(GLenum target, GLenum pname, GLint param);
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params);
+void TexParameterx(GLenum target, GLenum pname, GLfixed param);
+void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params);
+void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                   GLenum format, GLenum type, const GLvoid* pixels);
+void Translatef(GLfloat x, GLfloat y, GLfloat z);
+void Translatex(GLfixed x, GLfixed y, GLfixed z);
+void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height);
+void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+void DrawTexsvOES(const GLshort *coords);
+void DrawTexivOES(const GLint *coords);
+void DrawTexxvOES(const GLfixed *coords);
+void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+void DrawTexfvOES(const GLfloat *coords);
+}
+
+egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext);
+extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname);
+egl::Image *createBackBuffer(int width, int height, const egl::Config *config);
+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType window, int width, int height);
+
+extern "C"
+{
+EGLAPI EGLint EGLAPIENTRY eglGetError(void)
+{
+	return libEGL->eglGetError();
+}
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
+{
+	return libEGL->eglGetDisplay(display_id);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+	return libEGL->eglInitialize(dpy, major, minor);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
+{
+	return libEGL->eglTerminate(dpy);
+}
+
+EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
+{
+	return libEGL->eglQueryString(dpy, name);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	return libEGL->eglGetConfigs(dpy, configs, config_size, num_config);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	return libEGL->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglGetConfigAttrib(dpy, config, attribute, value);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateWindowSurface(dpy, config, window, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+	return libEGL->eglCreatePbufferSurface(dpy, config, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+	return libEGL->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+	return libEGL->eglDestroySurface(dpy, surface);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglQuerySurface(dpy, surface, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
+{
+	return libEGL->eglBindAPI(api);
+}
+
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)
+{
+	return libEGL->eglQueryAPI();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)
+{
+	return libEGL->eglWaitClient();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)
+{
+	return libEGL->eglReleaseThread();
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+	return libEGL->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+	return libEGL->eglSurfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	return libEGL->eglBindTexImage(dpy, surface, buffer);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	return libEGL->eglReleaseTexImage(dpy, surface, buffer);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+	return libEGL->eglSwapInterval(dpy, interval);
+}
+
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateContext(dpy, config, share_context, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+	return libEGL->eglDestroyContext(dpy, ctx);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+	return libEGL->eglMakeCurrent(dpy, draw, read, ctx);
+}
+
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)
+{
+	return libEGL->eglGetCurrentContext();
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
+{
+	return libEGL->eglGetCurrentSurface(readdraw);
+}
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
+{
+	return libEGL->eglGetCurrentDisplay();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglQueryContext(dpy, ctx, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
+{
+	return libEGL->eglWaitGL();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
+{
+	return libEGL->eglWaitNative(engine);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+	return libEGL->eglSwapBuffers(dpy, surface);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+	return libEGL->eglCopyBuffers(dpy, surface, target);
+}
+
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+	return libEGL->eglDestroyImageKHR(dpy, image);
+}
+
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
+{
+	return libEGL->eglGetProcAddress(procname);
+}
+
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+	return libEGL->eglDestroySyncKHR(dpy, sync);
+}
+
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+	return libEGL->eglClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglGetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+GL_API void GL_APIENTRY glActiveTexture(GLenum texture)
+{
+	return es1::ActiveTexture(texture);
+}
+
+GL_API void GL_APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
+{
+	return es1::AlphaFunc(func, ref);
+}
+
+GL_API void GL_APIENTRY glAlphaFuncx(GLenum func, GLclampx ref)
+{
+	return es1::AlphaFuncx(func, ref);
+}
+
+GL_API void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+	return es1::BindBuffer(target, buffer);
+}
+
+GL_API void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+	return es1::BindFramebuffer(target, framebuffer);
+}
+
+GL_API void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+	return es1::BindFramebufferOES(target, framebuffer);
+}
+
+GL_API void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+	return es1::BindRenderbufferOES(target, renderbuffer);
+}
+
+GL_API void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+	return es1::BindTexture(target, texture);
+}
+
+GL_API void GL_APIENTRY glBlendEquationOES(GLenum mode)
+{
+	return es1::BlendEquationSeparateOES(mode, mode);
+}
+
+GL_API void GL_APIENTRY glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
+{
+	return es1::BlendEquationSeparateOES(modeRGB, modeAlpha);
+}
+
+GL_API void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	return es1::BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
+}
+
+GL_API void GL_APIENTRY glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	return es1::BlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+GL_API void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	return es1::BufferData(target, size, data, usage);
+}
+
+GL_API void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	return es1::BufferSubData(target, offset, size, data);
+}
+
+GL_API GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)
+{
+	return es1::CheckFramebufferStatusOES(target);
+}
+
+GL_API void GL_APIENTRY glClear(GLbitfield mask)
+{
+	return es1::Clear(mask);
+}
+
+GL_API void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	return es1::ClearColor(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+	return es1::ClearColorx(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glClearDepthf(GLclampf depth)
+{
+	return es1::ClearDepthf(depth);
+}
+
+GL_API void GL_APIENTRY glClearDepthx(GLclampx depth)
+{
+	return es1::ClearDepthx(depth);
+}
+
+GL_API void GL_APIENTRY glClearStencil(GLint s)
+{
+	return es1::ClearStencil(s);
+}
+
+GL_API void GL_APIENTRY glClientActiveTexture(GLenum texture)
+{
+	return es1::ClientActiveTexture(texture);
+}
+
+GL_API void GL_APIENTRY glClipPlanef(GLenum plane, const GLfloat *equation)
+{
+	return es1::ClipPlanef(plane, equation);
+}
+
+GL_API void GL_APIENTRY glClipPlanex(GLenum plane, const GLfixed *equation)
+{
+	return es1::ClipPlanex(plane, equation);
+}
+
+GL_API void GL_APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+	return es1::Color4f(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+	return es1::Color4ub(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+	return es1::Color4x(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	return es1::ColorMask(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::ColorPointer(size, type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                                               GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	return es1::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+GL_API void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                                  GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	return es1::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+GL_API void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	return es1::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+GL_API void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es1::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+GL_API void GL_APIENTRY glCullFace(GLenum mode)
+{
+	return es1::CullFace(mode);
+}
+
+GL_API void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	return es1::DeleteBuffers(n, buffers);
+}
+
+GL_API void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+	return es1::DeleteFramebuffersOES(n, framebuffers);
+}
+
+GL_API void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+	return es1::DeleteRenderbuffersOES(n, renderbuffers);
+}
+
+GL_API void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+	return es1::DeleteTextures(n, textures);
+}
+
+GL_API void GL_APIENTRY glDepthFunc(GLenum func)
+{
+	return es1::DepthFunc(func);
+}
+
+GL_API void GL_APIENTRY glDepthMask(GLboolean flag)
+{
+	return es1::DepthMask(flag);
+}
+
+GL_API void GL_APIENTRY glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+	return es1::DepthRangex(zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	return es1::DepthRangef(zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glDisable(GLenum cap)
+{
+	return es1::Disable(cap);
+}
+
+GL_API void GL_APIENTRY glDisableClientState(GLenum array)
+{
+	return es1::DisableClientState(array);
+}
+
+GL_API void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	return es1::DrawArrays(mode, first, count);
+}
+
+GL_API void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	return es1::DrawElements(mode, count, type, indices);
+}
+
+GL_API void GL_APIENTRY glEnable(GLenum cap)
+{
+	return es1::Enable(cap);
+}
+
+GL_API void GL_APIENTRY glEnableClientState(GLenum array)
+{
+	return es1::EnableClientState(array);
+}
+
+GL_API void GL_APIENTRY glFinish(void)
+{
+	return es1::Finish();
+}
+
+GL_API void GL_APIENTRY glFlush(void)
+{
+	return es1::Flush();
+}
+
+GL_API void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	return es1::FramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+GL_API void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	return es1::FramebufferTexture2DOES(target, attachment, textarget, texture, level);
+}
+
+GL_API void GL_APIENTRY glFogf(GLenum pname, GLfloat param)
+{
+	return es1::Fogf(pname, param);
+}
+
+GL_API void GL_APIENTRY glFogfv(GLenum pname, const GLfloat *params)
+{
+	return es1::Fogfv(pname, params);
+}
+
+GL_API void GL_APIENTRY glFogx(GLenum pname, GLfixed param)
+{
+	return es1::Fogx(pname, param);
+}
+
+GL_API void GL_APIENTRY glFogxv(GLenum pname, const GLfixed *params)
+{
+	return es1::Fogxv(pname, params);
+}
+
+GL_API void GL_APIENTRY glFrontFace(GLenum mode)
+{
+	return es1::FrontFace(mode);
+}
+
+GL_API void GL_APIENTRY glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	return es1::Frustumf(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	return es1::Frustumx(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glGenerateMipmapOES(GLenum target)
+{
+	return es1::GenerateMipmapOES(target);
+}
+
+GL_API void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
+{
+	return es1::GenBuffers(n, buffers);
+}
+
+GL_API void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+	return es1::GenFramebuffersOES(n, framebuffers);
+}
+
+GL_API void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+	return es1::GenRenderbuffersOES(n, renderbuffers);
+}
+
+GL_API void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
+{
+	return es1::GenTextures(n, textures);
+}
+
+GL_API void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+	return es1::GetRenderbufferParameterivOES(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
+{
+	return es1::GetBooleanv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	return es1::GetBufferParameteriv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+	return es1::GetClipPlanef(pname, eqn);
+}
+
+GL_API void GL_APIENTRY glGetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+	return es1::GetClipPlanex(pname, eqn);
+}
+
+GL_API GLenum GL_APIENTRY glGetError(void)
+{
+	return es1::GetError();
+}
+
+GL_API void GL_APIENTRY glGetFixedv(GLenum pname, GLfixed *params)
+{
+	return es1::GetFixedv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
+{
+	return es1::GetFloatv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	return es1::GetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
+{
+	return es1::GetIntegerv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+	return es1::GetLightfv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+	return es1::GetLightxv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+	return es1::GetMaterialfv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+	return es1::GetMaterialxv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetPointerv(GLenum pname, GLvoid **params)
+{
+	return es1::GetPointerv(pname, params);
+}
+
+GL_API const GLubyte* GL_APIENTRY glGetString(GLenum name)
+{
+	return es1::GetString(name);
+}
+
+GL_API void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	return es1::GetTexParameterfv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	return es1::GetTexParameteriv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+	return es1::GetTexEnvfv(env, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+	return es1::GetTexEnviv(env, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+	return es1::GetTexEnvxv(env, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+	return es1::GetTexParameterxv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glHint(GLenum target, GLenum mode)
+{
+	return es1::Hint(target, mode);
+}
+
+GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
+{
+	return es1::IsBuffer(buffer);
+}
+
+GL_API GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
+{
+	return es1::IsEnabled(cap);
+}
+
+GL_API GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)
+{
+	return es1::IsFramebufferOES(framebuffer);
+}
+
+GL_API GLboolean GL_APIENTRY glIsTexture(GLuint texture)
+{
+	return es1::IsTexture(texture);
+}
+
+GL_API GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)
+{
+	return es1::IsRenderbufferOES(renderbuffer);
+}
+
+GL_API void GL_APIENTRY glLightModelf(GLenum pname, GLfloat param)
+{
+	return es1::LightModelf(pname, param);
+}
+
+GL_API void GL_APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
+{
+	return es1::LightModelfv(pname, params);
+}
+
+GL_API void GL_APIENTRY glLightModelx(GLenum pname, GLfixed param)
+{
+	return es1::LightModelx(pname, param);
+}
+
+GL_API void GL_APIENTRY glLightModelxv(GLenum pname, const GLfixed *params)
+{
+	return es1::LightModelxv(pname, params);
+}
+
+GL_API void GL_APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+	return es1::Lightf(light, pname, param);
+}
+
+GL_API void GL_APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+	return es1::Lightfv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+	return es1::Lightx(light, pname, param);
+}
+
+GL_API void GL_APIENTRY glLightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+	return es1::Lightxv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glLineWidth(GLfloat width)
+{
+	return es1::LineWidth(width);
+}
+
+GL_API void GL_APIENTRY glLineWidthx(GLfixed width)
+{
+	return es1::LineWidthx(width);
+}
+
+GL_API void GL_APIENTRY glLoadIdentity(void)
+{
+	return es1::LoadIdentity();
+}
+
+GL_API void GL_APIENTRY glLoadMatrixf(const GLfloat *m)
+{
+	return es1::LoadMatrixf(m);
+}
+
+GL_API void GL_APIENTRY glLoadMatrixx(const GLfixed *m)
+{
+	return es1::LoadMatrixx(m);
+}
+
+GL_API void GL_APIENTRY glLogicOp(GLenum opcode)
+{
+	return es1::LogicOp(opcode);
+}
+
+GL_API void GL_APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+	return es1::Materialf(face, pname, param);
+}
+
+GL_API void GL_APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+	return es1::Materialfv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+	return es1::Materialx(face, pname, param);
+}
+
+GL_API void GL_APIENTRY glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+	return es1::Materialxv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glMatrixMode(GLenum mode)
+{
+	return es1::MatrixMode(mode);
+}
+
+GL_API void GL_APIENTRY glMultMatrixf(const GLfloat *m)
+{
+	return es1::MultMatrixf(m);
+}
+
+GL_API void GL_APIENTRY glMultMatrixx(const GLfixed *m)
+{
+	return es1::MultMatrixx(m);
+}
+
+GL_API void GL_APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+	return es1::MultiTexCoord4f(target, s, t, r, q);
+}
+
+GL_API void GL_APIENTRY glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+	return es1::MultiTexCoord4x(target, s, t, r, q);
+}
+
+GL_API void GL_APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+	return es1::Normal3f(nx, ny, nz);
+}
+
+GL_API void GL_APIENTRY glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+	return es1::Normal3x(nx, ny, nz);
+}
+
+GL_API void GL_APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::NormalPointer(type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	return es1::Orthof(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	return es1::Orthox(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+	return es1::PixelStorei(pname, param);
+}
+
+GL_API void GL_APIENTRY glPointParameterf(GLenum pname, GLfloat param)
+{
+	return es1::PointParameterf(pname, param);
+}
+
+GL_API void GL_APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params)
+{
+	return es1::PointParameterfv(pname, params);
+}
+
+GL_API void GL_APIENTRY glPointParameterx(GLenum pname, GLfixed param)
+{
+	return es1::PointParameterx(pname, param);
+}
+
+GL_API void GL_APIENTRY glPointParameterxv(GLenum pname, const GLfixed *params)
+{
+	return es1::PointParameterxv(pname, params);
+}
+
+GL_API void GL_APIENTRY glPointSize(GLfloat size)
+{
+	return es1::PointSize(size);
+}
+
+GL_API void GL_APIENTRY glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::PointSizePointerOES(type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glPointSizex(GLfixed size)
+{
+	return es1::PointSizex(size);
+}
+
+GL_API void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+	return es1::PolygonOffset(factor, units);
+}
+
+GL_API void GL_APIENTRY glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+	return es1::PolygonOffsetx(factor, units);
+}
+
+GL_API void GL_APIENTRY glPopMatrix(void)
+{
+	return es1::PopMatrix();
+}
+
+GL_API void GL_APIENTRY glPushMatrix(void)
+{
+	return es1::PushMatrix();
+}
+
+GL_API void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	return es1::ReadPixels(x, y, width, height, format, type, pixels);
+}
+
+GL_API void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	return es1::RenderbufferStorageOES(target, internalformat, width, height);
+}
+
+GL_API void GL_APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	return es1::Rotatef(angle, x, y, z);
+}
+
+GL_API void GL_APIENTRY glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+	return es1::Rotatex(angle, x, y, z);
+}
+
+GL_API void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+{
+	return es1::SampleCoverage(value, invert);
+}
+
+GL_API void GL_APIENTRY glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+	return es1::SampleCoveragex(value, invert);
+}
+
+GL_API void GL_APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+	return es1::Scalef(x, y, z);
+}
+
+GL_API void GL_APIENTRY glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+	return es1::Scalex(x, y, z);
+}
+
+GL_API void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es1::Scissor(x, y, width, height);
+}
+
+GL_API void GL_APIENTRY glShadeModel(GLenum mode)
+{
+	return es1::ShadeModel(mode);
+}
+
+GL_API void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	return es1::StencilFunc(func, ref, mask);
+}
+
+GL_API void GL_APIENTRY glStencilMask(GLuint mask)
+{
+	return es1::StencilMask(mask);
+}
+
+GL_API void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	return es1::StencilOp(fail, zfail, zpass);
+}
+
+GL_API void GL_APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::TexCoordPointer(size, type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+	return es1::TexEnvf(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+	return es1::TexEnvfv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+	return es1::TexEnvi(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+	return es1::TexEnvx(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+	return es1::TexEnviv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	return es1::TexEnvxv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                                     GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	return es1::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+GL_API void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	return es1::TexParameterf(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	return es1::TexParameterfv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	return es1::TexParameteri(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	return es1::TexParameteriv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+	return es1::TexParameterx(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	return es1::TexParameterxv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                        GLenum format, GLenum type, const GLvoid* pixels)
+{
+	return es1::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+GL_API void GL_APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+	return es1::Translatef(x, y, z);
+}
+
+GL_API void GL_APIENTRY glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+	return es1::Translatex(x, y, z);
+}
+
+GL_API void GL_APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::VertexPointer(size, type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es1::Viewport(x, y, width, height);
+}
+
+GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	return es1::EGLImageTargetTexture2DOES(target, image);
+}
+
+GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	return es1::EGLImageTargetRenderbufferStorageOES(target, image);
+}
+
+GL_API void GL_APIENTRY glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+	return es1::DrawTexsOES(x,y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+	return es1::DrawTexiOES(x,y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+	return es1::DrawTexxOES(x,y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexsvOES(const GLshort *coords)
+{
+	return es1::DrawTexsvOES(coords);
+}
+
+GL_API void GL_APIENTRY glDrawTexivOES(const GLint *coords)
+{
+	return es1::DrawTexivOES(coords);
+}
+
+GL_API void GL_APIENTRY glDrawTexxvOES(const GLfixed *coords)
+{
+	return es1::DrawTexxvOES(coords);
+}
+
+GL_API void GL_APIENTRY glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+	return es1::DrawTexfOES(x, y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexfvOES(const GLfloat *coords)
+{
+	return es1::DrawTexfvOES(coords);
+}
+
+}
+
+LibGLES_CMexports::LibGLES_CMexports()
+{
+	this->glActiveTexture = es1::ActiveTexture;
+	this->glAlphaFunc = es1::AlphaFunc;
+	this->glAlphaFuncx = es1::AlphaFuncx;
+	this->glBindBuffer = es1::BindBuffer;
+	this->glBindFramebuffer = es1::BindFramebuffer;
+	this->glBindFramebufferOES = es1::BindFramebufferOES;
+	this->glBindRenderbufferOES = es1::BindRenderbufferOES;
+	this->glBindTexture = es1::BindTexture;
+	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;
+	this->glBlendEquationOES = es1::BlendEquationOES;
+	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;
+	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;
+	this->glBlendFunc = es1::BlendFunc;
+	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;
+	this->glBufferData = es1::BufferData;
+	this->glBufferSubData = es1::BufferSubData;
+	this->glCheckFramebufferStatusOES = es1::CheckFramebufferStatusOES;
+	this->glClear = es1::Clear;
+	this->glClearColor = es1::ClearColor;
+	this->glClearColorx = es1::ClearColorx;
+	this->glClearDepthf = es1::ClearDepthf;
+	this->glClearDepthx = es1::ClearDepthx;
+	this->glClearStencil = es1::ClearStencil;
+	this->glClientActiveTexture = es1::ClientActiveTexture;
+	this->glClipPlanef = es1::ClipPlanef;
+	this->glClipPlanex = es1::ClipPlanex;
+	this->glColor4f = es1::Color4f;
+	this->glColor4ub = es1::Color4ub;
+	this->glColor4x = es1::Color4x;
+	this->glColorMask = es1::ColorMask;
+	this->glColorPointer = es1::ColorPointer;
+	this->glCompressedTexImage2D = es1::CompressedTexImage2D;
+	this->glCompressedTexSubImage2D = es1::CompressedTexSubImage2D;
+	this->glCopyTexImage2D = es1::CopyTexImage2D;
+	this->glCopyTexSubImage2D = es1::CopyTexSubImage2D;
+	this->glCullFace = es1::CullFace;
+	this->glDeleteBuffers = es1::DeleteBuffers;
+	this->glDeleteFramebuffersOES = es1::DeleteFramebuffersOES;
+	this->glDeleteRenderbuffersOES = es1::DeleteRenderbuffersOES;
+	this->glDeleteTextures = es1::DeleteTextures;
+	this->glDepthFunc = es1::DepthFunc;
+	this->glDepthMask = es1::DepthMask;
+	this->glDepthRangex = es1::DepthRangex;
+	this->glDepthRangef = es1::DepthRangef;
+	this->glDisable = es1::Disable;
+	this->glDisableClientState = es1::DisableClientState;
+	this->glDrawArrays = es1::DrawArrays;
+	this->glDrawElements = es1::DrawElements;
+	this->glEnable = es1::Enable;
+	this->glEnableClientState = es1::EnableClientState;
+	this->glFinish = es1::Finish;
+	this->glFlush = es1::Flush;
+	this->glFramebufferRenderbufferOES = es1::FramebufferRenderbufferOES;
+	this->glFramebufferTexture2DOES = es1::FramebufferTexture2DOES;
+	this->glFogf = es1::Fogf;
+	this->glFogfv = es1::Fogfv;
+	this->glFogx = es1::Fogx;
+	this->glFogxv = es1::Fogxv;
+	this->glFrontFace = es1::FrontFace;
+	this->glFrustumf = es1::Frustumf;
+	this->glFrustumx = es1::Frustumx;
+	this->glGenerateMipmapOES = es1::GenerateMipmapOES;
+	this->glGenBuffers = es1::GenBuffers;
+	this->glGenFramebuffersOES = es1::GenFramebuffersOES;
+	this->glGenRenderbuffersOES = es1::GenRenderbuffersOES;
+	this->glGenTextures = es1::GenTextures;
+	this->glGetRenderbufferParameterivOES = es1::GetRenderbufferParameterivOES;
+	this->glGetBooleanv = es1::GetBooleanv;
+	this->glGetBufferParameteriv = es1::GetBufferParameteriv;
+	this->glGetClipPlanef = es1::GetClipPlanef;
+	this->glGetClipPlanex = es1::GetClipPlanex;
+	this->glGetError = es1::GetError;
+	this->glGetFixedv = es1::GetFixedv;
+	this->glGetFloatv = es1::GetFloatv;
+	this->glGetFramebufferAttachmentParameterivOES = es1::GetFramebufferAttachmentParameterivOES;
+	this->glGetIntegerv = es1::GetIntegerv;
+	this->glGetLightfv = es1::GetLightfv;
+	this->glGetLightxv = es1::GetLightxv;
+	this->glGetMaterialfv = es1::GetMaterialfv;
+	this->glGetMaterialxv = es1::GetMaterialxv;
+	this->glGetPointerv = es1::GetPointerv;
+	this->glGetString = es1::GetString;
+	this->glGetTexParameterfv = es1::GetTexParameterfv;
+	this->glGetTexParameteriv = es1::GetTexParameteriv;
+	this->glGetTexEnvfv = es1::GetTexEnvfv;
+	this->glGetTexEnviv = es1::GetTexEnviv;
+	this->glGetTexEnvxv = es1::GetTexEnvxv;
+	this->glGetTexParameterxv = es1::GetTexParameterxv;
+	this->glHint = es1::Hint;
+	this->glIsBuffer = es1::IsBuffer;
+	this->glIsEnabled = es1::IsEnabled;
+	this->glIsFramebufferOES = es1::IsFramebufferOES;
+	this->glIsTexture = es1::IsTexture;
+	this->glIsRenderbufferOES = es1::IsRenderbufferOES;
+	this->glLightModelf = es1::LightModelf;
+	this->glLightModelfv = es1::LightModelfv;
+	this->glLightModelx = es1::LightModelx;
+	this->glLightModelxv = es1::LightModelxv;
+	this->glLightf = es1::Lightf;
+	this->glLightfv = es1::Lightfv;
+	this->glLightx = es1::Lightx;
+	this->glLightxv = es1::Lightxv;
+	this->glLineWidth = es1::LineWidth;
+	this->glLineWidthx = es1::LineWidthx;
+	this->glLoadIdentity = es1::LoadIdentity;
+	this->glLoadMatrixf = es1::LoadMatrixf;
+	this->glLoadMatrixx = es1::LoadMatrixx;
+	this->glLogicOp = es1::LogicOp;
+	this->glMaterialf = es1::Materialf;
+	this->glMaterialfv = es1::Materialfv;
+	this->glMaterialx = es1::Materialx;
+	this->glMaterialxv = es1::Materialxv;
+	this->glMatrixMode = es1::MatrixMode;
+	this->glMultMatrixf = es1::MultMatrixf;
+	this->glMultMatrixx = es1::MultMatrixx;
+	this->glMultiTexCoord4f = es1::MultiTexCoord4f;
+	this->glMultiTexCoord4x = es1::MultiTexCoord4x;
+	this->glNormal3f = es1::Normal3f;
+	this->glNormal3x = es1::Normal3x;
+	this->glNormalPointer = es1::NormalPointer;
+	this->glOrthof = es1::Orthof;
+	this->glOrthox = es1::Orthox;
+	this->glPixelStorei = es1::PixelStorei;
+	this->glPointParameterf = es1::PointParameterf;
+	this->glPointParameterfv = es1::PointParameterfv;
+	this->glPointParameterx = es1::PointParameterx;
+	this->glPointParameterxv = es1::PointParameterxv;
+	this->glPointSize = es1::PointSize;
+	this->glPointSizePointerOES = es1::PointSizePointerOES;
+	this->glPointSizex = es1::PointSizex;
+	this->glPolygonOffset = es1::PolygonOffset;
+	this->glPolygonOffsetx = es1::PolygonOffsetx;
+	this->glPopMatrix = es1::PopMatrix;
+	this->glPushMatrix = es1::PushMatrix;
+	this->glReadPixels = es1::ReadPixels;
+	this->glRenderbufferStorageOES = es1::RenderbufferStorageOES;
+	this->glRotatef = es1::Rotatef;
+	this->glRotatex = es1::Rotatex;
+	this->glSampleCoverage = es1::SampleCoverage;
+	this->glSampleCoveragex = es1::SampleCoveragex;
+	this->glScalef = es1::Scalef;
+	this->glScalex = es1::Scalex;
+	this->glScissor = es1::Scissor;
+	this->glShadeModel = es1::ShadeModel;
+	this->glStencilFunc = es1::StencilFunc;
+	this->glStencilMask = es1::StencilMask;
+	this->glStencilOp = es1::StencilOp;
+	this->glTexCoordPointer = es1::TexCoordPointer;
+	this->glTexEnvf = es1::TexEnvf;
+	this->glTexEnvfv = es1::TexEnvfv;
+	this->glTexEnvi = es1::TexEnvi;
+	this->glTexEnvx = es1::TexEnvx;
+	this->glTexEnviv = es1::TexEnviv;
+	this->glTexEnvxv = es1::TexEnvxv;
+	this->glTexImage2D = es1::TexImage2D;
+	this->glTexParameterf = es1::TexParameterf;
+	this->glTexParameterfv = es1::TexParameterfv;
+	this->glTexParameteri = es1::TexParameteri;
+	this->glTexParameteriv = es1::TexParameteriv;
+	this->glTexParameterx = es1::TexParameterx;
+	this->glTexParameterxv = es1::TexParameterxv;
+	this->glTexSubImage2D = es1::TexSubImage2D;
+	this->glTranslatef = es1::Translatef;
+	this->glTranslatex = es1::Translatex;
+	this->glVertexPointer = es1::VertexPointer;
+	this->glViewport = es1::Viewport;
+	this->glEGLImageTargetTexture2DOES = es1::EGLImageTargetTexture2DOES;
+	this->glEGLImageTargetRenderbufferStorageOES = es1::EGLImageTargetRenderbufferStorageOES;
+	this->glDrawTexsOES = es1::DrawTexsOES;
+	this->glDrawTexiOES = es1::DrawTexiOES;
+	this->glDrawTexxOES = es1::DrawTexxOES;
+	this->glDrawTexsvOES = es1::DrawTexsvOES;
+	this->glDrawTexivOES = es1::DrawTexivOES;
+	this->glDrawTexxvOES = es1::DrawTexxvOES;
+	this->glDrawTexfOES = es1::DrawTexfOES;
+	this->glDrawTexfvOES = es1::DrawTexfvOES;
+
+	this->es1CreateContext = ::es1CreateContext;
+	this->es1GetProcAddress = ::es1GetProcAddress;
+	this->createBackBuffer = ::createBackBuffer;
+	this->createDepthStencil = ::createDepthStencil;
+	this->createFrameBuffer = ::createFrameBuffer;
+}
+
+extern "C" GL_API LibGLES_CMexports *libGLES_CM_swiftshader()
+{
+	static LibGLES_CMexports libGLES_CM;
+	return &libGLES_CM;
+}
+
+LibEGL libEGL;
diff --git a/src/OpenGL/libGLES_CM/main.h b/src/OpenGL/libGLES_CM/main.h
index da8fed6..34092b0 100644
--- a/src/OpenGL/libGLES_CM/main.h
+++ b/src/OpenGL/libGLES_CM/main.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // main.h: Management of thread-local data.
 
diff --git a/src/OpenGL/libGLES_CM/mathutil.h b/src/OpenGL/libGLES_CM/mathutil.h
index 89c2e54..7f62c5b 100644
--- a/src/OpenGL/libGLES_CM/mathutil.h
+++ b/src/OpenGL/libGLES_CM/mathutil.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // mathutil.h: Math and bit manipulation functions.
 
@@ -21,27 +24,27 @@
 {
 inline bool isPow2(int x)
 {
-    return (x & (x - 1)) == 0 && (x != 0);
+	return (x & (x - 1)) == 0 && (x != 0);
 }
 
 inline int log2(int x)
 {
-    int r = 0;
-    while((x >> r) > 1) r++;
-    return r;
+	int r = 0;
+	while((x >> r) > 1) r++;
+	return r;
 }
 
 inline unsigned int ceilPow2(unsigned int x)
 {
-    if(x != 0) x--;
-    x |= x >> 1;
-    x |= x >> 2;
-    x |= x >> 4;
-    x |= x >> 8;
-    x |= x >> 16;
-    x++;
+	if(x != 0) x--;
+	x |= x >> 1;
+	x |= x >> 2;
+	x |= x >> 4;
+	x |= x >> 8;
+	x |= x >> 16;
+	x++;
 
-    return x;
+	return x;
 }
 
 using sw::clamp;
@@ -50,20 +53,20 @@
 template<const int n>
 inline unsigned int unorm(float x)
 {
-    const unsigned int max = 0xFFFFFFFF >> (32 - n);
+	const unsigned int max = 0xFFFFFFFF >> (32 - n);
 
-    if(x > 1)
-    {
-        return max;
-    }
-    else if(x < 0)
-    {
-        return 0;
-    }
-    else
-    {
-        return (unsigned int)(max * x + 0.5f);
-    }
+	if(x > 1)
+	{
+		return max;
+	}
+	else if(x < 0)
+	{
+		return 0;
+	}
+	else
+	{
+		return (unsigned int)(max * x + 0.5f);
+	}
 }
 }
 
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;
+	}
+}
diff --git a/src/OpenGL/libGLES_CM/utilities.h b/src/OpenGL/libGLES_CM/utilities.h
index ef1d6ff..ec2a257 100644
--- a/src/OpenGL/libGLES_CM/utilities.h
+++ b/src/OpenGL/libGLES_CM/utilities.h
@@ -1,82 +1,85 @@
-// 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.h: Conversion functions and other utility routines.

-

-#ifndef LIBGLES_CM_UTILITIES_H

-#define LIBGLES_CM_UTILITIES_H

-

-#include "Device.hpp"

-#include "common/Image.hpp"

-#include "Texture.h"

-

-#include <GLES/gl.h>

-#include <GLES/glext.h>

-

-#include <string>

-

-namespace es1

-{

-	struct Color;

-

-	bool IsCompressed(GLenum format);

-	bool IsDepthTexture(GLenum format);

-	bool IsStencilTexture(GLenum format);

-	bool IsCubemapTextureTarget(GLenum target);

-	int CubeFaceIndex(GLenum cubeTarget);

-	bool IsTextureTarget(GLenum target);

-	bool CheckTextureFormatType(GLenum format, GLenum type);

-

-	bool IsColorRenderable(GLenum internalformat);

-	bool IsDepthRenderable(GLenum internalformat);

-	bool IsStencilRenderable(GLenum internalformat);

-

-	bool IsAlpha(GLenum texFormat);

-	bool IsRGB(GLenum texFormat);

-	bool IsRGBA(GLenum texFormat);

-}

-

-namespace es2sw

-{

-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);

-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);

-	sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison);

-	sw::Color<float> ConvertColor(es1::Color color);

-	sw::BlendFactor ConvertBlendFunc(GLenum blend);

-	sw::BlendOperation ConvertBlendOp(GLenum blendOp);

-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);

-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap);

-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);

-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);

-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);

-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);

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

-	sw::Format ConvertRenderbufferFormat(GLenum format);

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

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

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

-}

-

-namespace sw2es

-{

-	GLuint GetAlphaSize(sw::Format colorFormat);

-	GLuint GetRedSize(sw::Format colorFormat);

-	GLuint GetGreenSize(sw::Format colorFormat);

-	GLuint GetBlueSize(sw::Format colorFormat);

-	GLuint GetDepthSize(sw::Format depthFormat);

-	GLuint GetStencilSize(sw::Format stencilFormat);

-

-	GLenum ConvertBackBufferFormat(sw::Format format);

-	GLenum ConvertDepthStencilFormat(sw::Format format);

-}

-

-#endif  // LIBGLES_CM_UTILITIES_H

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// utilities.h: Conversion functions and other utility routines.
+
+#ifndef LIBGLES_CM_UTILITIES_H
+#define LIBGLES_CM_UTILITIES_H
+
+#include "Device.hpp"
+#include "common/Image.hpp"
+#include "Texture.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <string>
+
+namespace es1
+{
+	struct Color;
+
+	bool IsCompressed(GLenum format);
+	bool IsDepthTexture(GLenum format);
+	bool IsStencilTexture(GLenum format);
+	bool IsCubemapTextureTarget(GLenum target);
+	int CubeFaceIndex(GLenum cubeTarget);
+	bool IsTextureTarget(GLenum target);
+	bool CheckTextureFormatType(GLenum format, GLenum type);
+
+	bool IsColorRenderable(GLenum internalformat);
+	bool IsDepthRenderable(GLenum internalformat);
+	bool IsStencilRenderable(GLenum internalformat);
+
+	bool IsAlpha(GLenum texFormat);
+	bool IsRGB(GLenum texFormat);
+	bool IsRGBA(GLenum texFormat);
+}
+
+namespace es2sw
+{
+	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);
+	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);
+	sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison);
+	sw::Color<float> ConvertColor(es1::Color color);
+	sw::BlendFactor ConvertBlendFunc(GLenum blend);
+	sw::BlendOperation ConvertBlendOp(GLenum blendOp);
+	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
+	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap);
+	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
+	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);
+	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
+	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
+	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount);
+	sw::Format ConvertRenderbufferFormat(GLenum format);
+	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation);
+	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument);
+	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand);
+}
+
+namespace sw2es
+{
+	GLuint GetAlphaSize(sw::Format colorFormat);
+	GLuint GetRedSize(sw::Format colorFormat);
+	GLuint GetGreenSize(sw::Format colorFormat);
+	GLuint GetBlueSize(sw::Format colorFormat);
+	GLuint GetDepthSize(sw::Format depthFormat);
+	GLuint GetStencilSize(sw::Format stencilFormat);
+
+	GLenum ConvertBackBufferFormat(sw::Format format);
+	GLenum ConvertDepthStencilFormat(sw::Format format);
+}
+
+#endif  // LIBGLES_CM_UTILITIES_H
diff --git a/src/OpenGL/libGLESv2/Buffer.cpp b/src/OpenGL/libGLESv2/Buffer.cpp
index d89ae76..69182d9 100644
--- a/src/OpenGL/libGLESv2/Buffer.cpp
+++ b/src/OpenGL/libGLESv2/Buffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Buffer.cpp: Implements the Buffer class, representing storage of vertex and/or
 // index data. Implements GL buffer objects and related functionality.
@@ -24,9 +27,9 @@
 
 Buffer::Buffer(GLuint name) : NamedObject(name)
 {
-    mContents = 0;
-    mSize = 0;
-    mUsage = GL_STATIC_DRAW;
+	mContents = 0;
+	mSize = 0;
+	mUsage = GL_STATIC_DRAW;
 	mIsMapped = false;
 	mOffset = 0;
 	mLength = 0;
@@ -35,7 +38,7 @@
 
 Buffer::~Buffer()
 {
-    if(mContents)
+	if(mContents)
 	{
 		mContents->destruct();
 	}
diff --git a/src/OpenGL/libGLESv2/Buffer.h b/src/OpenGL/libGLESv2/Buffer.h
index 0dfc71e..4a792f1 100644
--- a/src/OpenGL/libGLESv2/Buffer.h
+++ b/src/OpenGL/libGLESv2/Buffer.h
@@ -1,87 +1,90 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Buffer.h: Defines the Buffer class, representing storage of vertex and/or

-// index data. Implements GL buffer objects and related functionality.

-// [OpenGL ES 2.0.24] section 2.9 page 21.

-

-#ifndef LIBGLESV2_BUFFER_H_

-#define LIBGLESV2_BUFFER_H_

-

-#include "common/Object.hpp"

-#include "Common/Resource.hpp"

-

-#include <GLES2/gl2.h>

-

-#include <cstddef>

-#include <vector>

-

-namespace es2

-{

-class Buffer : public gl::NamedObject

-{

-  public:

-    explicit Buffer(GLuint name);

-

-    virtual ~Buffer();

-

-    void bufferData(const void *data, GLsizeiptr size, GLenum usage);

-    void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);

-

-	const void *data() const { return mContents ? mContents->data() : 0; }

-    size_t size() const { return mSize; }

-    GLenum usage() const { return mUsage; }

-	bool isMapped() const { return mIsMapped; }

-	GLintptr offset() const { return mOffset; }

-	GLsizeiptr length() const { return mLength; }

-	GLbitfield access() const { return mAccess; }

-

-	void* mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);

-	bool unmap();

-	void flushMappedRange(GLintptr offset, GLsizeiptr length) {}

-

-	sw::Resource *getResource();

-

-  private:

-    sw::Resource *mContents;

-    size_t mSize;

-    GLenum mUsage;

-	bool mIsMapped;

-	GLintptr mOffset;

-	GLsizeiptr mLength;

-	GLbitfield mAccess;

-};

-

-class BufferBinding

-{

-public:

-	BufferBinding() : offset(0), size(0) { }

-

-	void set(Buffer *newBuffer, int newOffset = 0, int newSize = 0)

-	{

-		buffer = newBuffer;

-		offset = newOffset;

-		size = newSize;

-	}

-

-	int getOffset() const { return offset; }

-	int getSize() const { return size; }

-	const gl::BindingPointer<Buffer>& get() const { return buffer; }

-

-private:

-	gl::BindingPointer<Buffer> buffer;

-	int offset;

-	int size;

-};

-

-}

-

-#endif   // LIBGLESV2_BUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Buffer.h: Defines the Buffer class, representing storage of vertex and/or
+// index data. Implements GL buffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 2.9 page 21.
+
+#ifndef LIBGLESV2_BUFFER_H_
+#define LIBGLESV2_BUFFER_H_
+
+#include "common/Object.hpp"
+#include "Common/Resource.hpp"
+
+#include <GLES2/gl2.h>
+
+#include <cstddef>
+#include <vector>
+
+namespace es2
+{
+class Buffer : public gl::NamedObject
+{
+public:
+	explicit Buffer(GLuint name);
+
+	virtual ~Buffer();
+
+	void bufferData(const void *data, GLsizeiptr size, GLenum usage);
+	void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
+
+	const void *data() const { return mContents ? mContents->data() : 0; }
+	size_t size() const { return mSize; }
+	GLenum usage() const { return mUsage; }
+	bool isMapped() const { return mIsMapped; }
+	GLintptr offset() const { return mOffset; }
+	GLsizeiptr length() const { return mLength; }
+	GLbitfield access() const { return mAccess; }
+
+	void* mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
+	bool unmap();
+	void flushMappedRange(GLintptr offset, GLsizeiptr length) {}
+
+	sw::Resource *getResource();
+
+private:
+	sw::Resource *mContents;
+	size_t mSize;
+	GLenum mUsage;
+	bool mIsMapped;
+	GLintptr mOffset;
+	GLsizeiptr mLength;
+	GLbitfield mAccess;
+};
+
+class BufferBinding
+{
+public:
+	BufferBinding() : offset(0), size(0) { }
+
+	void set(Buffer *newBuffer, int newOffset = 0, int newSize = 0)
+	{
+		buffer = newBuffer;
+		offset = newOffset;
+		size = newSize;
+	}
+
+	int getOffset() const { return offset; }
+	int getSize() const { return size; }
+	const gl::BindingPointer<Buffer>& get() const { return buffer; }
+
+private:
+	gl::BindingPointer<Buffer> buffer;
+	int offset;
+	int size;
+};
+
+}
+
+#endif   // LIBGLESV2_BUFFER_H_
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 6b01e45..da9aedd 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -1,4344 +1,4347 @@
-// 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.

-//

-

-// Context.cpp: Implements the es2::Context class, managing all GL state and performing

-// rendering operations. It is the GLES2 specific implementation of EGLContext.

-

-#include "Context.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "ResourceManager.h"

-#include "Buffer.h"

-#include "Fence.h"

-#include "Framebuffer.h"

-#include "Program.h"

-#include "Query.h"

-#include "Renderbuffer.h"

-#include "Sampler.h"

-#include "Shader.h"

-#include "Texture.h"

-#include "TransformFeedback.h"

-#include "VertexArray.h"

-#include "VertexDataManager.h"

-#include "IndexDataManager.h"

-#include "libEGL/Display.h"

-#include "libEGL/Surface.h"

-#include "Common/Half.hpp"

-

-#include <EGL/eglext.h>

-

-namespace es2

-{

-Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion)

-	: clientVersion(clientVersion), mConfig(config)

-{

-	sw::Context *context = new sw::Context();

-	device = new es2::Device(context);

-

-    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);

-

-    mState.depthClearValue = 1.0f;

-    mState.stencilClearValue = 0;

-

-    mState.cullFaceEnabled = false;

-    mState.cullMode = GL_BACK;

-    mState.frontFace = GL_CCW;

-    mState.depthTestEnabled = false;

-    mState.depthFunc = GL_LESS;

-    mState.blendEnabled = false;

-    mState.sourceBlendRGB = GL_ONE;

-    mState.sourceBlendAlpha = GL_ONE;

-    mState.destBlendRGB = GL_ZERO;

-    mState.destBlendAlpha = GL_ZERO;

-    mState.blendEquationRGB = GL_FUNC_ADD;

-    mState.blendEquationAlpha = GL_FUNC_ADD;

-    mState.blendColor.red = 0;

-    mState.blendColor.green = 0;

-    mState.blendColor.blue = 0;

-    mState.blendColor.alpha = 0;

-    mState.stencilTestEnabled = false;

-    mState.stencilFunc = GL_ALWAYS;

-    mState.stencilRef = 0;

-    mState.stencilMask = -1;

-    mState.stencilWritemask = -1;

-    mState.stencilBackFunc = GL_ALWAYS;

-    mState.stencilBackRef = 0;

-    mState.stencilBackMask = - 1;

-    mState.stencilBackWritemask = -1;

-    mState.stencilFail = GL_KEEP;

-    mState.stencilPassDepthFail = GL_KEEP;

-    mState.stencilPassDepthPass = GL_KEEP;

-    mState.stencilBackFail = GL_KEEP;

-    mState.stencilBackPassDepthFail = GL_KEEP;

-    mState.stencilBackPassDepthPass = GL_KEEP;

-    mState.polygonOffsetFillEnabled = false;

-    mState.polygonOffsetFactor = 0.0f;

-    mState.polygonOffsetUnits = 0.0f;

-    mState.sampleAlphaToCoverageEnabled = false;

-    mState.sampleCoverageEnabled = false;

-    mState.sampleCoverageValue = 1.0f;

-    mState.sampleCoverageInvert = false;

-    mState.scissorTestEnabled = false;

-    mState.ditherEnabled = true;

-    mState.primitiveRestartFixedIndexEnabled = false;

-    mState.rasterizerDiscardEnabled = false;

-    mState.generateMipmapHint = GL_DONT_CARE;

-    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;

-

-    mState.lineWidth = 1.0f;

-

-    mState.viewportX = 0;

-    mState.viewportY = 0;

-    mState.viewportWidth = 0;

-    mState.viewportHeight = 0;

-    mState.zNear = 0.0f;

-    mState.zFar = 1.0f;

-

-    mState.scissorX = 0;

-    mState.scissorY = 0;

-    mState.scissorWidth = 0;

-    mState.scissorHeight = 0;

-

-    mState.colorMaskRed = true;

-    mState.colorMaskGreen = true;

-    mState.colorMaskBlue = true;

-    mState.colorMaskAlpha = true;

-    mState.depthMask = true;

-

-    if(shareContext)

-    {

-        mResourceManager = shareContext->mResourceManager;

-        mResourceManager->addRef();

-    }

-    else

-    {

-        mResourceManager = new ResourceManager();

-    }

-

-    // [OpenGL ES 2.0.24] section 3.7 page 83:

-    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional

-    // and cube map texture state vectors respectively associated with them.

-    // In order that access to these initial textures not be lost, they are treated as texture

-    // objects all of whose names are 0.

-

-    mTexture2DZero = new Texture2D(0);

-	mTexture3DZero = new Texture3D(0);

-	mTexture2DArrayZero = new Texture2DArray(0);

-    mTextureCubeMapZero = new TextureCubeMap(0);

-    mTextureExternalZero = new TextureExternal(0);

-

-    mState.activeSampler = 0;

-	bindVertexArray(0);

-    bindArrayBuffer(0);

-    bindElementArrayBuffer(0);

-    bindTextureCubeMap(0);

-    bindTexture2D(0);

-    bindReadFramebuffer(0);

-    bindDrawFramebuffer(0);

-    bindRenderbuffer(0);

-    bindGenericUniformBuffer(0);

-    bindTransformFeedback(0);

-

-    mState.currentProgram = 0;

-

-    mState.packAlignment = 4;

-	mState.unpackInfo.alignment = 4;

-	mState.packRowLength = 0;

-	mState.packImageHeight = 0;

-	mState.packSkipPixels = 0;

-	mState.packSkipRows = 0;

-	mState.packSkipImages = 0;

-	mState.unpackInfo.rowLength = 0;

-	mState.unpackInfo.imageHeight = 0;

-	mState.unpackInfo.skipPixels = 0;

-	mState.unpackInfo.skipRows = 0;

-	mState.unpackInfo.skipImages = 0;

-

-    mVertexDataManager = nullptr;

-    mIndexDataManager = nullptr;

-

-    mInvalidEnum = false;

-    mInvalidValue = false;

-    mInvalidOperation = false;

-    mOutOfMemory = false;

-    mInvalidFramebufferOperation = false;

-

-    mHasBeenCurrent = false;

-

-    markAllStateDirty();

-}

-

-Context::~Context()

-{

-	if(mState.currentProgram != 0)

-	{

-		Program *programObject = mResourceManager->getProgram(mState.currentProgram);

-		if(programObject)

-		{

-			programObject->release();

-		}

-		mState.currentProgram = 0;

-	}

-

-	while(!mFramebufferNameSpace.empty())

-	{

-		deleteFramebuffer(mFramebufferNameSpace.firstName());

-	}

-

-	while(!mFenceNameSpace.empty())

-	{

-		deleteFence(mFenceNameSpace.firstName());

-	}

-

-	while(!mQueryNameSpace.empty())

-	{

-		deleteQuery(mQueryNameSpace.firstName());

-	}

-

-	while(!mVertexArrayNameSpace.empty())

-	{

-		deleteVertexArray(mVertexArrayNameSpace.firstName());

-	}

-

-	while(!mTransformFeedbackNameSpace.empty())

-	{

-		deleteTransformFeedback(mTransformFeedbackNameSpace.firstName());

-	}

-

-	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-	{

-		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)

-		{

-			mState.samplerTexture[type][sampler] = nullptr;

-		}

-	}

-

-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-	{

-		mState.vertexAttribute[i].mBoundBuffer = nullptr;

-	}

-

-	for(int i = 0; i < QUERY_TYPE_COUNT; i++)

-	{

-		mState.activeQuery[i] = nullptr;

-	}

-

-	mState.arrayBuffer = nullptr;

-	mState.copyReadBuffer = nullptr;

-	mState.copyWriteBuffer = nullptr;

-	mState.pixelPackBuffer = nullptr;

-	mState.pixelUnpackBuffer = nullptr;

-	mState.genericUniformBuffer = nullptr;

-	mState.renderbuffer = nullptr;

-

-	for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)

-	{

-		mState.sampler[i] = nullptr;

-	}

-

-    mTexture2DZero = nullptr;

-	mTexture3DZero = nullptr;

-	mTexture2DArrayZero = nullptr;

-    mTextureCubeMapZero = nullptr;

-    mTextureExternalZero = nullptr;

-

-    delete mVertexDataManager;

-    delete mIndexDataManager;

-

-    mResourceManager->release();

-	delete device;

-}

-

-void Context::makeCurrent(egl::Surface *surface)

-{

-    if(!mHasBeenCurrent)

-    {

-        mVertexDataManager = new VertexDataManager(this);

-        mIndexDataManager = new IndexDataManager();

-

-        mState.viewportX = 0;

-        mState.viewportY = 0;

-        mState.viewportWidth = surface->getWidth();

-        mState.viewportHeight = surface->getHeight();

-

-        mState.scissorX = 0;

-        mState.scissorY = 0;

-        mState.scissorWidth = surface->getWidth();

-        mState.scissorHeight = surface->getHeight();

-

-        mHasBeenCurrent = true;

-    }

-

-    // Wrap the existing resources into GL objects and assign them to the '0' names

-    egl::Image *defaultRenderTarget = surface->getRenderTarget();

-    egl::Image *depthStencil = surface->getDepthStencil();

-

-    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);

-    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);

-    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);

-

-    setFramebufferZero(framebufferZero);

-

-    if(defaultRenderTarget)

-    {

-        defaultRenderTarget->release();

-    }

-

-    if(depthStencil)

-    {

-        depthStencil->release();

-    }

-

-    markAllStateDirty();

-}

-

-EGLint Context::getClientVersion() const

-{

-	return clientVersion;

-}

-

-// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.

-void Context::markAllStateDirty()

-{

-    mAppliedProgramSerial = 0;

-

-    mDepthStateDirty = true;

-    mMaskStateDirty = true;

-    mBlendStateDirty = true;

-    mStencilStateDirty = true;

-    mPolygonOffsetStateDirty = true;

-    mSampleStateDirty = true;

-    mDitherStateDirty = true;

-    mFrontFaceDirty = true;

-}

-

-void Context::setClearColor(float red, float green, float blue, float alpha)

-{

-    mState.colorClearValue.red = red;

-    mState.colorClearValue.green = green;

-    mState.colorClearValue.blue = blue;

-    mState.colorClearValue.alpha = alpha;

-}

-

-void Context::setClearDepth(float depth)

-{

-    mState.depthClearValue = depth;

-}

-

-void Context::setClearStencil(int stencil)

-{

-    mState.stencilClearValue = stencil;

-}

-

-void Context::setCullFaceEnabled(bool enabled)

-{

-    mState.cullFaceEnabled = enabled;

-}

-

-bool Context::isCullFaceEnabled() const

-{

-    return mState.cullFaceEnabled;

-}

-

-void Context::setCullMode(GLenum mode)

-{

-   mState.cullMode = mode;

-}

-

-void Context::setFrontFace(GLenum front)

-{

-    if(mState.frontFace != front)

-    {

-        mState.frontFace = front;

-        mFrontFaceDirty = true;

-    }

-}

-

-void Context::setDepthTestEnabled(bool enabled)

-{

-    if(mState.depthTestEnabled != enabled)

-    {

-        mState.depthTestEnabled = enabled;

-        mDepthStateDirty = true;

-    }

-}

-

-bool Context::isDepthTestEnabled() const

-{

-    return mState.depthTestEnabled;

-}

-

-void Context::setDepthFunc(GLenum depthFunc)

-{

-    if(mState.depthFunc != depthFunc)

-    {

-        mState.depthFunc = depthFunc;

-        mDepthStateDirty = true;

-    }

-}

-

-void Context::setDepthRange(float zNear, float zFar)

-{

-    mState.zNear = zNear;

-    mState.zFar = zFar;

-}

-

-void Context::setBlendEnabled(bool enabled)

-{

-    if(mState.blendEnabled != enabled)

-    {

-        mState.blendEnabled = enabled;

-        mBlendStateDirty = true;

-    }

-}

-

-bool Context::isBlendEnabled() const

-{

-    return mState.blendEnabled;

-}

-

-void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)

-{

-    if(mState.sourceBlendRGB != sourceRGB ||

-       mState.sourceBlendAlpha != sourceAlpha ||

-       mState.destBlendRGB != destRGB ||

-       mState.destBlendAlpha != destAlpha)

-    {

-        mState.sourceBlendRGB = sourceRGB;

-        mState.destBlendRGB = destRGB;

-        mState.sourceBlendAlpha = sourceAlpha;

-        mState.destBlendAlpha = destAlpha;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setBlendColor(float red, float green, float blue, float alpha)

-{

-    if(mState.blendColor.red != red ||

-       mState.blendColor.green != green ||

-       mState.blendColor.blue != blue ||

-       mState.blendColor.alpha != alpha)

-    {

-        mState.blendColor.red = red;

-        mState.blendColor.green = green;

-        mState.blendColor.blue = blue;

-        mState.blendColor.alpha = alpha;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)

-{

-    if(mState.blendEquationRGB != rgbEquation ||

-       mState.blendEquationAlpha != alphaEquation)

-    {

-        mState.blendEquationRGB = rgbEquation;

-        mState.blendEquationAlpha = alphaEquation;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setStencilTestEnabled(bool enabled)

-{

-    if(mState.stencilTestEnabled != enabled)

-    {

-        mState.stencilTestEnabled = enabled;

-        mStencilStateDirty = true;

-    }

-}

-

-bool Context::isStencilTestEnabled() const

-{

-    return mState.stencilTestEnabled;

-}

-

-void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)

-{

-    if(mState.stencilFunc != stencilFunc ||

-       mState.stencilRef != stencilRef ||

-       mState.stencilMask != stencilMask)

-    {

-        mState.stencilFunc = stencilFunc;

-        mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;

-        mState.stencilMask = stencilMask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)

-{

-    if(mState.stencilBackFunc != stencilBackFunc ||

-       mState.stencilBackRef != stencilBackRef ||

-       mState.stencilBackMask != stencilBackMask)

-    {

-        mState.stencilBackFunc = stencilBackFunc;

-        mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;

-        mState.stencilBackMask = stencilBackMask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilWritemask(GLuint stencilWritemask)

-{

-    if(mState.stencilWritemask != stencilWritemask)

-    {

-        mState.stencilWritemask = stencilWritemask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilBackWritemask(GLuint stencilBackWritemask)

-{

-    if(mState.stencilBackWritemask != stencilBackWritemask)

-    {

-        mState.stencilBackWritemask = stencilBackWritemask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)

-{

-    if(mState.stencilFail != stencilFail ||

-       mState.stencilPassDepthFail != stencilPassDepthFail ||

-       mState.stencilPassDepthPass != stencilPassDepthPass)

-    {

-        mState.stencilFail = stencilFail;

-        mState.stencilPassDepthFail = stencilPassDepthFail;

-        mState.stencilPassDepthPass = stencilPassDepthPass;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)

-{

-    if(mState.stencilBackFail != stencilBackFail ||

-       mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||

-       mState.stencilBackPassDepthPass != stencilBackPassDepthPass)

-    {

-        mState.stencilBackFail = stencilBackFail;

-        mState.stencilBackPassDepthFail = stencilBackPassDepthFail;

-        mState.stencilBackPassDepthPass = stencilBackPassDepthPass;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setPolygonOffsetFillEnabled(bool enabled)

-{

-    if(mState.polygonOffsetFillEnabled != enabled)

-    {

-        mState.polygonOffsetFillEnabled = enabled;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-bool Context::isPolygonOffsetFillEnabled() const

-{

-    return mState.polygonOffsetFillEnabled;

-}

-

-void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)

-{

-    if(mState.polygonOffsetFactor != factor ||

-       mState.polygonOffsetUnits != units)

-    {

-        mState.polygonOffsetFactor = factor;

-        mState.polygonOffsetUnits = units;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-void Context::setSampleAlphaToCoverageEnabled(bool enabled)

-{

-    if(mState.sampleAlphaToCoverageEnabled != enabled)

-    {

-        mState.sampleAlphaToCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleAlphaToCoverageEnabled() const

-{

-    return mState.sampleAlphaToCoverageEnabled;

-}

-

-void Context::setSampleCoverageEnabled(bool enabled)

-{

-    if(mState.sampleCoverageEnabled != enabled)

-    {

-        mState.sampleCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleCoverageEnabled() const

-{

-    return mState.sampleCoverageEnabled;

-}

-

-void Context::setSampleCoverageParams(GLclampf value, bool invert)

-{

-    if(mState.sampleCoverageValue != value ||

-       mState.sampleCoverageInvert != invert)

-    {

-        mState.sampleCoverageValue = value;

-        mState.sampleCoverageInvert = invert;

-        mSampleStateDirty = true;

-    }

-}

-

-void Context::setScissorTestEnabled(bool enabled)

-{

-    mState.scissorTestEnabled = enabled;

-}

-

-bool Context::isScissorTestEnabled() const

-{

-    return mState.scissorTestEnabled;

-}

-

-void Context::setDitherEnabled(bool enabled)

-{

-    if(mState.ditherEnabled != enabled)

-    {

-        mState.ditherEnabled = enabled;

-        mDitherStateDirty = true;

-    }

-}

-

-bool Context::isDitherEnabled() const

-{

-    return mState.ditherEnabled;

-}

-

-void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)

-{

-    UNIMPLEMENTED();

-    mState.primitiveRestartFixedIndexEnabled = enabled;

-}

-

-bool Context::isPrimitiveRestartFixedIndexEnabled() const

-{

-    return mState.primitiveRestartFixedIndexEnabled;

-}

-

-void Context::setRasterizerDiscardEnabled(bool enabled)

-{

-    mState.rasterizerDiscardEnabled = enabled;

-}

-

-bool Context::isRasterizerDiscardEnabled() const

-{

-    return mState.rasterizerDiscardEnabled;

-}

-

-void Context::setLineWidth(GLfloat width)

-{

-    mState.lineWidth = width;

-	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

-}

-

-void Context::setGenerateMipmapHint(GLenum hint)

-{

-    mState.generateMipmapHint = hint;

-}

-

-void Context::setFragmentShaderDerivativeHint(GLenum hint)

-{

-    mState.fragmentShaderDerivativeHint = hint;

-    // TODO: Propagate the hint to shader translator so we can write

-    // ddx, ddx_coarse, or ddx_fine depending on the hint.

-    // Ignore for now. It is valid for implementations to ignore hint.

-}

-

-void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.viewportX = x;

-    mState.viewportY = y;

-    mState.viewportWidth = width;

-    mState.viewportHeight = height;

-}

-

-void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.scissorX = x;

-    mState.scissorY = y;

-    mState.scissorWidth = width;

-    mState.scissorHeight = height;

-}

-

-void Context::setColorMask(bool red, bool green, bool blue, bool alpha)

-{

-    if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||

-       mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)

-    {

-        mState.colorMaskRed = red;

-        mState.colorMaskGreen = green;

-        mState.colorMaskBlue = blue;

-        mState.colorMaskAlpha = alpha;

-        mMaskStateDirty = true;

-    }

-}

-

-unsigned int Context::getColorMask() const

-{

-	return (mState.colorMaskRed ? 0x1 : 0) |

-	       (mState.colorMaskGreen ? 0x2 : 0) |

-	       (mState.colorMaskBlue ? 0x4 : 0) |

-	       (mState.colorMaskAlpha ? 0x8 : 0);

-}

-

-void Context::setDepthMask(bool mask)

-{

-    if(mState.depthMask != mask)

-    {

-        mState.depthMask = mask;

-        mMaskStateDirty = true;

-    }

-}

-

-void Context::setActiveSampler(unsigned int active)

-{

-    mState.activeSampler = active;

-}

-

-GLuint Context::getReadFramebufferName() const

-{

-    return mState.readFramebuffer;

-}

-

-GLuint Context::getDrawFramebufferName() const

-{

-    return mState.drawFramebuffer;

-}

-

-GLuint Context::getRenderbufferName() const

-{

-    return mState.renderbuffer.name();

-}

-

-void Context::setFramebufferReadBuffer(GLuint buf)

-{

-	getReadFramebuffer()->setReadBuffer(buf);

-}

-

-void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)

-{

-	Framebuffer *drawFramebuffer = getDrawFramebuffer();

-

-	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)

-	{

-		drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);

-	}

-}

-

-GLuint Context::getReadFramebufferColorIndex() const

-{

-	GLenum buf = getReadFramebuffer()->getReadBuffer();

-	switch(buf)

-	{

-	case GL_BACK:

-		return 0;

-	case GL_NONE:

-		return GL_INVALID_INDEX;

-	default:

-		return buf - GL_COLOR_ATTACHMENT0;

-}

-}

-

-GLuint Context::getArrayBufferName() const

-{

-    return mState.arrayBuffer.name();

-}

-

-GLuint Context::getElementArrayBufferName() const

-{

-	Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();

-	return elementArrayBuffer ? elementArrayBuffer->name : 0;

-}

-

-GLuint Context::getActiveQuery(GLenum target) const

-{

-    Query *queryObject = nullptr;

-

-    switch(target)

-    {

-    case GL_ANY_SAMPLES_PASSED_EXT:

-        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];

-        break;

-    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];

-        break;

-    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:

-        queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];

-        break;

-    default:

-        ASSERT(false);

-    }

-

-    if(queryObject)

-    {

-        return queryObject->name;

-    }

-

-	return 0;

-}

-

-void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)

-{

-	getCurrentVertexArray()->enableAttribute(attribNum, enabled);

-}

-

-void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)

-{

-	getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);

-}

-

-const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const

-{

-	return getCurrentVertexArray()->getVertexAttribute(attribNum);

-}

-

-void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,

-                                   GLsizei stride, const void *pointer)

-{

-	getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, stride, pointer);

-}

-

-const void *Context::getVertexAttribPointer(unsigned int attribNum) const

-{

-	return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;

-}

-

-const VertexAttributeArray &Context::getVertexArrayAttributes()

-{

-	return getCurrentVertexArray()->getVertexAttributes();

-}

-

-const VertexAttributeArray &Context::getCurrentVertexAttributes()

-{

-	return mState.vertexAttribute;

-}

-

-void Context::setPackAlignment(GLint alignment)

-{

-    mState.packAlignment = alignment;

-}

-

-void Context::setUnpackAlignment(GLint alignment)

-{

-	mState.unpackInfo.alignment = alignment;

-}

-

-const egl::Image::UnpackInfo& Context::getUnpackInfo() const

-{

-	return mState.unpackInfo;

-}

-

-void Context::setPackRowLength(GLint rowLength)

-{

-	mState.packRowLength = rowLength;

-}

-

-void Context::setPackImageHeight(GLint imageHeight)

-{

-	mState.packImageHeight = imageHeight;

-}

-

-void Context::setPackSkipPixels(GLint skipPixels)

-{

-	mState.packSkipPixels = skipPixels;

-}

-

-void Context::setPackSkipRows(GLint skipRows)

-{

-	mState.packSkipRows = skipRows;

-}

-

-void Context::setPackSkipImages(GLint skipImages)

-{

-	mState.packSkipImages = skipImages;

-}

-

-void Context::setUnpackRowLength(GLint rowLength)

-{

-	mState.unpackInfo.rowLength = rowLength;

-}

-

-void Context::setUnpackImageHeight(GLint imageHeight)

-{

-	mState.unpackInfo.imageHeight = imageHeight;

-}

-

-void Context::setUnpackSkipPixels(GLint skipPixels)

-{

-	mState.unpackInfo.skipPixels = skipPixels;

-}

-

-void Context::setUnpackSkipRows(GLint skipRows)

-{

-	mState.unpackInfo.skipRows = skipRows;

-}

-

-void Context::setUnpackSkipImages(GLint skipImages)

-{

-	mState.unpackInfo.skipImages = skipImages;

-}

-

-GLuint Context::createBuffer()

-{

-    return mResourceManager->createBuffer();

-}

-

-GLuint Context::createProgram()

-{

-    return mResourceManager->createProgram();

-}

-

-GLuint Context::createShader(GLenum type)

-{

-    return mResourceManager->createShader(type);

-}

-

-GLuint Context::createTexture()

-{

-    return mResourceManager->createTexture();

-}

-

-GLuint Context::createRenderbuffer()

-{

-    return mResourceManager->createRenderbuffer();

-}

-

-// Returns an unused framebuffer name

-GLuint Context::createFramebuffer()

-{

-    return mFramebufferNameSpace.allocate();

-}

-

-GLuint Context::createFence()

-{

-	return mFenceNameSpace.allocate(new Fence());

-}

-

-// Returns an unused query name

-GLuint Context::createQuery()

-{

-	return mQueryNameSpace.allocate();

-}

-

-// Returns an unused vertex array name

-GLuint Context::createVertexArray()

-{

-	return mVertexArrayNameSpace.allocate();

-}

-

-GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)

-{

-	GLuint handle = mResourceManager->createFenceSync(condition, flags);

-

-	return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));

-}

-

-// Returns an unused transform feedback name

-GLuint Context::createTransformFeedback()

-{

-	return mTransformFeedbackNameSpace.allocate();

-}

-

-// Returns an unused sampler name

-GLuint Context::createSampler()

-{

-	return mResourceManager->createSampler();

-}

-

-void Context::deleteBuffer(GLuint buffer)

-{

-	detachBuffer(buffer);

-

-    mResourceManager->deleteBuffer(buffer);

-}

-

-void Context::deleteShader(GLuint shader)

-{

-    mResourceManager->deleteShader(shader);

-}

-

-void Context::deleteProgram(GLuint program)

-{

-    mResourceManager->deleteProgram(program);

-}

-

-void Context::deleteTexture(GLuint texture)

-{

-	detachTexture(texture);

-

-    mResourceManager->deleteTexture(texture);

-}

-

-void Context::deleteRenderbuffer(GLuint renderbuffer)

-{

-	if(mResourceManager->getRenderbuffer(renderbuffer))

-	{

-		detachRenderbuffer(renderbuffer);

-	}

-

-    mResourceManager->deleteRenderbuffer(renderbuffer);

-}

-

-void Context::deleteFramebuffer(GLuint framebuffer)

-{

-	detachFramebuffer(framebuffer);

-

-    Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);

-

-    if(framebufferObject)

-    {

-		delete framebufferObject;

-    }

-}

-

-void Context::deleteFence(GLuint fence)

-{

-    Fence *fenceObject = mFenceNameSpace.remove(fence);

-

-    if(fenceObject)

-    {

-		delete fenceObject;

-    }

-}

-

-void Context::deleteQuery(GLuint query)

-{

-    Query *queryObject = mQueryNameSpace.remove(query);

-

-	if(queryObject)

-    {

-		queryObject->release();

-    }

-}

-

-void Context::deleteVertexArray(GLuint vertexArray)

-{

-	// [OpenGL ES 3.0.2] section 2.10 page 43:

-	// If a vertex array object that is currently bound is deleted, the binding

-	// for that object reverts to zero and the default vertex array becomes current.

-	if(getCurrentVertexArray()->name == vertexArray)

-	{

-		bindVertexArray(0);

-	}

-

-	VertexArray *vertexArrayObject = mVertexArrayNameSpace.remove(vertexArray);

-

-	if(vertexArrayObject)

-	{

-		delete vertexArrayObject;

-	}

-}

-

-void Context::deleteFenceSync(GLsync fenceSync)

-{

-	// The spec specifies the underlying Fence object is not deleted until all current

-	// wait commands finish. However, since the name becomes invalid, we cannot query the fence,

-	// and since our API is currently designed for being called from a single thread, we can delete

-	// the fence immediately.

-	mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));

-}

-

-void Context::deleteTransformFeedback(GLuint transformFeedback)

-{

-	TransformFeedback *transformFeedbackObject = mTransformFeedbackNameSpace.remove(transformFeedback);

-

-	if(transformFeedbackObject)

-	{

-		delete transformFeedbackObject;

-	}

-}

-

-void Context::deleteSampler(GLuint sampler)

-{

-	detachSampler(sampler);

-

-	mResourceManager->deleteSampler(sampler);

-}

-

-Buffer *Context::getBuffer(GLuint handle) const

-{

-    return mResourceManager->getBuffer(handle);

-}

-

-Shader *Context::getShader(GLuint handle) const

-{

-    return mResourceManager->getShader(handle);

-}

-

-Program *Context::getProgram(GLuint handle) const

-{

-    return mResourceManager->getProgram(handle);

-}

-

-Texture *Context::getTexture(GLuint handle) const

-{

-    return mResourceManager->getTexture(handle);

-}

-

-Renderbuffer *Context::getRenderbuffer(GLuint handle) const

-{

-    return mResourceManager->getRenderbuffer(handle);

-}

-

-Framebuffer *Context::getReadFramebuffer() const

-{

-    return getFramebuffer(mState.readFramebuffer);

-}

-

-Framebuffer *Context::getDrawFramebuffer() const

-{

-    return getFramebuffer(mState.drawFramebuffer);

-}

-

-void Context::bindArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-    mState.arrayBuffer = getBuffer(buffer);

-}

-

-void Context::bindElementArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-	getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));

-}

-

-void Context::bindCopyReadBuffer(GLuint buffer)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	mState.copyReadBuffer = getBuffer(buffer);

-}

-

-void Context::bindCopyWriteBuffer(GLuint buffer)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	mState.copyWriteBuffer = getBuffer(buffer);

-}

-

-void Context::bindPixelPackBuffer(GLuint buffer)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	mState.pixelPackBuffer = getBuffer(buffer);

-}

-

-void Context::bindPixelUnpackBuffer(GLuint buffer)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	mState.pixelUnpackBuffer = getBuffer(buffer);

-}

-

-void Context::bindTransformFeedbackBuffer(GLuint buffer)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);

-

-	if(transformFeedback)

-	{

-		transformFeedback->setGenericBuffer(getBuffer(buffer));

-	}

-}

-

-void Context::bindTexture2D(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);

-

-    mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindTextureCubeMap(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);

-

-    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindTextureExternal(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);

-

-    mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindTexture3D(GLuint texture)

-{

-	mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);

-

-	mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindTexture2DArray(GLuint texture)

-{

-	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);

-

-	mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindReadFramebuffer(GLuint framebuffer)

-{

-    if(!getFramebuffer(framebuffer))

-    {

-        mFramebufferNameSpace.insert(framebuffer, new Framebuffer());

-    }

-

-    mState.readFramebuffer = framebuffer;

-}

-

-void Context::bindDrawFramebuffer(GLuint framebuffer)

-{

-    if(!getFramebuffer(framebuffer))

-    {

-        mFramebufferNameSpace.insert(framebuffer, new Framebuffer());

-    }

-

-    mState.drawFramebuffer = framebuffer;

-}

-

-void Context::bindRenderbuffer(GLuint renderbuffer)

-{

-	mResourceManager->checkRenderbufferAllocation(renderbuffer);

-

-    mState.renderbuffer = getRenderbuffer(renderbuffer);

-}

-

-void Context::bindVertexArray(GLuint array)

-{

-	VertexArray *vertexArray = getVertexArray(array);

-

-	if(!vertexArray)

-	{

-		vertexArray = new VertexArray(array);

-		mVertexArrayNameSpace.insert(array, vertexArray);

-	}

-

-	mState.vertexArray = array;

-}

-

-void Context::bindGenericUniformBuffer(GLuint buffer)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	mState.genericUniformBuffer = getBuffer(buffer);

-}

-

-void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	Buffer* bufferObject = getBuffer(buffer);

-	mState.uniformBuffers[index].set(bufferObject, offset, size);

-}

-

-void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	getTransformFeedback()->setGenericBuffer(getBuffer(buffer));

-}

-

-void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)

-{

-	mResourceManager->checkBufferAllocation(buffer);

-

-	Buffer* bufferObject = getBuffer(buffer);

-	getTransformFeedback()->setBuffer(index, bufferObject, offset, size);

-}

-

-void Context::bindTransformFeedback(GLuint id)

-{

-	if(!getTransformFeedback(id))

-	{

-		mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));

-	}

-

-	mState.transformFeedback = id;

-}

-

-bool Context::bindSampler(GLuint unit, GLuint sampler)

-{

-	mResourceManager->checkSamplerAllocation(sampler);

-

-	Sampler* samplerObject = getSampler(sampler);

-

-	if(sampler)

-	{

-		mState.sampler[unit] = samplerObject;

-	}

-

-	return !!samplerObject;

-}

-

-void Context::useProgram(GLuint program)

-{

-    GLuint priorProgram = mState.currentProgram;

-    mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.

-

-    if(priorProgram != program)

-    {

-        Program *newProgram = mResourceManager->getProgram(program);

-        Program *oldProgram = mResourceManager->getProgram(priorProgram);

-

-        if(newProgram)

-        {

-            newProgram->addRef();

-        }

-

-        if(oldProgram)

-        {

-            oldProgram->release();

-        }

-    }

-}

-

-void Context::beginQuery(GLenum target, GLuint query)

-{

-    // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>

-    // of zero, if the active query object name for <target> is non-zero (for the

-    // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if

-    // the active query for either target is non-zero), if <id> is the name of an

-    // existing query object whose type does not match <target>, or if <id> is the

-    // active query object name for any query type, the error INVALID_OPERATION is

-    // generated.

-

-    // Ensure no other queries are active

-    // NOTE: If other queries than occlusion are supported, we will need to check

-    // separately that:

-    //    a) The query ID passed is not the current active query for any target/type

-    //    b) There are no active queries for the requested target (and in the case

-    //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,

-    //       no query may be active for either if glBeginQuery targets either.

-    for(int i = 0; i < QUERY_TYPE_COUNT; i++)

-    {

-        if(mState.activeQuery[i])

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-    }

-

-    QueryType qType;

-    switch(target)

-    {

-    case GL_ANY_SAMPLES_PASSED_EXT:

-        qType = QUERY_ANY_SAMPLES_PASSED;

-        break;

-    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;

-        break;

-    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:

-        qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;

-        break;

-    default:

-        ASSERT(false);

-    }

-

-    Query *queryObject = createQuery(query, target);

-

-    // Check that name was obtained with glGenQueries

-    if(!queryObject)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    // Check for type mismatch

-    if(queryObject->getType() != target)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    // Set query as active for specified target

-    mState.activeQuery[qType] = queryObject;

-

-    // Begin query

-    queryObject->begin();

-}

-

-void Context::endQuery(GLenum target)

-{

-    QueryType qType;

-

-    switch(target)

-    {

-    case GL_ANY_SAMPLES_PASSED_EXT:                qType = QUERY_ANY_SAMPLES_PASSED;                    break;

-    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;       break;

-    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;

-    default: UNREACHABLE(target); return;

-    }

-

-    Query *queryObject = mState.activeQuery[qType];

-

-    if(!queryObject)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    queryObject->end();

-

-    mState.activeQuery[qType] = nullptr;

-}

-

-void Context::setFramebufferZero(Framebuffer *buffer)

-{

-    delete mFramebufferNameSpace.remove(0);

-    mFramebufferNameSpace.insert(0, buffer);

-}

-

-void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)

-{

-    Renderbuffer *renderbufferObject = mState.renderbuffer;

-    renderbufferObject->setStorage(renderbuffer);

-}

-

-Framebuffer *Context::getFramebuffer(unsigned int handle) const

-{

-	return mFramebufferNameSpace.find(handle);

-}

-

-Fence *Context::getFence(unsigned int handle) const

-{

-	return mFenceNameSpace.find(handle);

-}

-

-FenceSync *Context::getFenceSync(GLsync handle) const

-{

-	return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));

-}

-

-Query *Context::getQuery(unsigned int handle) const

-{

-	return mQueryNameSpace.find(handle);

-}

-

-Query *Context::createQuery(unsigned int handle, GLenum type)

-{

-	if(!mQueryNameSpace.isReserved(handle))

-	{

-		return nullptr;

-	}

-	else

-	{

-		Query *query = mQueryNameSpace.find(handle);

-		if(!query)

-		{

-			query = new Query(handle, type);

-			query->addRef();

-			mQueryNameSpace.insert(handle, query);

-		}

-

-		return query;

-	}

-}

-

-VertexArray *Context::getVertexArray(GLuint array) const

-{

-	return mVertexArrayNameSpace.find(array);

-}

-

-VertexArray *Context::getCurrentVertexArray() const

-{

-	return getVertexArray(mState.vertexArray);

-}

-

-bool Context::isVertexArray(GLuint array) const

-{

-	return mVertexArrayNameSpace.isReserved(array);

-}

-

-bool Context::hasZeroDivisor() const

-{

-	// Verify there is at least one active attribute with a divisor of zero

-	es2::Program *programObject = getCurrentProgram();

-	for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)

-	{

-		bool active = (programObject->getAttributeStream(attributeIndex) != -1);

-		if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)

-		{

-			return true;

-		}

-	}

-

-	return false;

-}

-

-TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const

-{

-	return mTransformFeedbackNameSpace.find(transformFeedback);

-}

-

-Sampler *Context::getSampler(GLuint sampler) const

-{

-	return mResourceManager->getSampler(sampler);

-}

-

-bool Context::isSampler(GLuint sampler) const

-{

-	return mResourceManager->isSampler(sampler);

-}

-

-Buffer *Context::getArrayBuffer() const

-{

-    return mState.arrayBuffer;

-}

-

-Buffer *Context::getElementArrayBuffer() const

-{

-	return getCurrentVertexArray()->getElementArrayBuffer();

-}

-

-Buffer *Context::getCopyReadBuffer() const

-{

-	return mState.copyReadBuffer;

-}

-

-Buffer *Context::getCopyWriteBuffer() const

-{

-	return mState.copyWriteBuffer;

-}

-

-Buffer *Context::getPixelPackBuffer() const

-{

-	return mState.pixelPackBuffer;

-}

-

-Buffer *Context::getPixelUnpackBuffer() const

-{

-	return mState.pixelUnpackBuffer;

-}

-

-Buffer *Context::getGenericUniformBuffer() const

-{

-	return mState.genericUniformBuffer;

-}

-

-bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const

-{

-	switch(target)

-	{

-	case GL_ARRAY_BUFFER:

-		*buffer = getArrayBuffer();

-		break;

-	case GL_ELEMENT_ARRAY_BUFFER:

-		*buffer = getElementArrayBuffer();

-		break;

-	case GL_COPY_READ_BUFFER:

-		if(clientVersion >= 3)

-		{

-			*buffer = getCopyReadBuffer();

-			break;

-		}

-		else return false;

-	case GL_COPY_WRITE_BUFFER:

-		if(clientVersion >= 3)

-		{

-			*buffer = getCopyWriteBuffer();

-			break;

-		}

-		else return false;

-	case GL_PIXEL_PACK_BUFFER:

-		if(clientVersion >= 3)

-		{

-			*buffer = getPixelPackBuffer();

-			break;

-		}

-		else return false;

-	case GL_PIXEL_UNPACK_BUFFER:

-		if(clientVersion >= 3)

-		{

-			*buffer = getPixelUnpackBuffer();

-			break;

-		}

-		else return false;

-	case GL_TRANSFORM_FEEDBACK_BUFFER:

-		if(clientVersion >= 3)

-		{

-			TransformFeedback* transformFeedback = getTransformFeedback();

-			*buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr;

-			break;

-		}

-		else return false;

-	case GL_UNIFORM_BUFFER:

-		if(clientVersion >= 3)

-		{

-			*buffer = getGenericUniformBuffer();

-			break;

-		}

-		else return false;

-	default:

-		return false;

-	}

-	return true;

-}

-

-TransformFeedback *Context::getTransformFeedback() const

-{

-	return getTransformFeedback(mState.transformFeedback);

-}

-

-Program *Context::getCurrentProgram() const

-{

-    return mResourceManager->getProgram(mState.currentProgram);

-}

-

-Texture2D *Context::getTexture2D() const

-{

-	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));

-}

-

-Texture3D *Context::getTexture3D() const

-{

-	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));

-}

-

-Texture2DArray *Context::getTexture2DArray() const

-{

-	return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));

-}

-

-TextureCubeMap *Context::getTextureCubeMap() const

-{

-    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));

-}

-

-TextureExternal *Context::getTextureExternal() const

-{

-    return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));

-}

-

-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const

-{

-    GLuint texid = mState.samplerTexture[type][sampler].name();

-

-    if(texid == 0)   // Special case: 0 refers to different initial textures based on the target

-    {

-        switch (type)

-        {

-        case TEXTURE_2D: return mTexture2DZero;

-		case TEXTURE_3D: return mTexture3DZero;

-		case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;

-        case TEXTURE_CUBE: return mTextureCubeMapZero;

-        case TEXTURE_EXTERNAL: return mTextureExternalZero;

-        default: UNREACHABLE(type);

-        }

-    }

-

-    return mState.samplerTexture[type][sampler];

-}

-

-void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)

-{

-	mResourceManager->checkSamplerAllocation(sampler);

-

-	Sampler *samplerObject = getSampler(sampler);

-	ASSERT(samplerObject);

-

-	switch(pname)

-	{

-	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;

-	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;

-	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;

-	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;

-	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;

-	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;

-	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;

-	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;

-	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;

-	default:                       UNREACHABLE(pname); break;

-	}

-}

-

-void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)

-{

-	mResourceManager->checkSamplerAllocation(sampler);

-

-	Sampler *samplerObject = getSampler(sampler);

-	ASSERT(samplerObject);

-

-	switch(pname)

-	{

-	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(roundf(param)));       break;

-	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(roundf(param)));       break;

-	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(roundf(param)));           break;

-	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(roundf(param)));           break;

-	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(roundf(param)));           break;

-	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                                       break;

-	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                                       break;

-	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(roundf(param)));  break;

-	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(roundf(param)));  break;

-	default:                       UNREACHABLE(pname); break;

-	}

-}

-

-GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)

-{

-	mResourceManager->checkSamplerAllocation(sampler);

-

-	Sampler *samplerObject = getSampler(sampler);

-	ASSERT(samplerObject);

-

-	switch(pname)

-	{

-	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());

-	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());

-	case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());

-	case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());

-	case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());

-	case GL_TEXTURE_MIN_LOD:       return static_cast<GLint>(roundf(samplerObject->getMinLod()));

-	case GL_TEXTURE_MAX_LOD:       return static_cast<GLint>(roundf(samplerObject->getMaxLod()));

-	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());

-	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());

-	default:                       UNREACHABLE(pname); return 0;

-	}

-}

-

-GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)

-{

-	mResourceManager->checkSamplerAllocation(sampler);

-

-	Sampler *samplerObject = getSampler(sampler);

-	ASSERT(samplerObject);

-

-	switch(pname)

-	{

-	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());

-	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());

-	case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());

-	case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());

-	case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());

-	case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();

-	case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();

-	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());

-	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());

-	default:                       UNREACHABLE(pname); return 0;

-	}

-}

-

-bool Context::getBooleanv(GLenum pname, GLboolean *params) const

-{

-    switch(pname)

-    {

-    case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;

-    case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;

-    case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;

-    case GL_COLOR_WRITEMASK:

-        params[0] = mState.colorMaskRed;

-        params[1] = mState.colorMaskGreen;

-        params[2] = mState.colorMaskBlue;

-        params[3] = mState.colorMaskAlpha;

-        break;

-    case GL_CULL_FACE:                *params = mState.cullFaceEnabled;                  break;

-    case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;         break;

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled;     break;

-    case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;            break;

-    case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;               break;

-    case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;               break;

-    case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;                 break;

-    case GL_BLEND:                    *params = mState.blendEnabled;                     break;

-    case GL_DITHER:                   *params = mState.ditherEnabled;                    break;

-    case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;

-    case GL_RASTERIZER_DISCARD:       *params = mState.rasterizerDiscardEnabled;         break;

-	case GL_TRANSFORM_FEEDBACK_ACTIVE:

-		{

-			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);

-			if(transformFeedback)

-			{

-				*params = transformFeedback->isActive();

-				break;

-			}

-			else return false;

-		}

-     case GL_TRANSFORM_FEEDBACK_PAUSED:

-		{

-			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);

-			if(transformFeedback)

-			{

-				*params = transformFeedback->isPaused();

-				break;

-			}

-			else return false;

-		}

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getFloatv(GLenum pname, GLfloat *params) const

-{

-    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application.

-    switch(pname)

-    {

-    case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;

-    case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;

-    case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;

-    case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;

-    case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-        params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;

-        params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;

-        break;

-    case GL_ALIASED_POINT_SIZE_RANGE:

-        params[0] = ALIASED_POINT_SIZE_RANGE_MIN;

-        params[1] = ALIASED_POINT_SIZE_RANGE_MAX;

-        break;

-    case GL_DEPTH_RANGE:

-        params[0] = mState.zNear;

-        params[1] = mState.zFar;

-        break;

-    case GL_COLOR_CLEAR_VALUE:

-        params[0] = mState.colorClearValue.red;

-        params[1] = mState.colorClearValue.green;

-        params[2] = mState.colorClearValue.blue;

-        params[3] = mState.colorClearValue.alpha;

-        break;

-    case GL_BLEND_COLOR:

-        params[0] = mState.blendColor.red;

-        params[1] = mState.blendColor.green;

-        params[2] = mState.blendColor.blue;

-        params[3] = mState.blendColor.alpha;

-        break;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-        *params = MAX_TEXTURE_MAX_ANISOTROPY;

-		break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;

-template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;

-

-template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const

-{

-    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application. You may find it in

-    // Context::getFloatv.

-    switch(pname)

-    {

-    case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;

-    case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;

-    case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;

-    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;

-    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;

-    case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;

-	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;

-	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;

-    case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;

-    case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;

-    case GL_ARRAY_BUFFER_BINDING:             *params = getArrayBufferName();                 break;

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = getElementArrayBufferName();          break;

-//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE

-    case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;

-    case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;

-    case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;

-    case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;

-    case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;

-    case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackInfo.alignment;          break;

-    case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;

-    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;

-    case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;

-    case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;

-    case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;

-	case GL_STENCIL_VALUE_MASK:               *params = sw::clampToSignedInt(mState.stencilMask); break;

-    case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;

-    case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;

-	case GL_STENCIL_BACK_VALUE_MASK:          *params = sw::clampToSignedInt(mState.stencilBackMask); break;

-    case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;

-    case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;

-    case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;

-    case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;

-    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;

-    case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;

-    case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;

-    case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;

-    case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;

-    case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;

-    case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;

-    case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;

-    case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;

-	case GL_STENCIL_WRITEMASK:                *params = sw::clampToSignedInt(mState.stencilWritemask); break;

-	case GL_STENCIL_BACK_WRITEMASK:           *params = sw::clampToSignedInt(mState.stencilBackWritemask); break;

-    case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;

-    case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;

-	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;          break;

-	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;

-    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           break;

-	case GL_MAX_SAMPLES_ANGLE:                *params = IMPLEMENTATION_MAX_SAMPLES;               break;

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-			int width, height, samples;

-

-            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)

-            {

-                switch(pname)

-                {

-                case GL_SAMPLE_BUFFERS:

-                    if(samples > 1)

-                    {

-                        *params = 1;

-                    }

-                    else

-                    {

-                        *params = 0;

-                    }

-                    break;

-                case GL_SAMPLES:

-                    *params = samples;

-                    break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE:

-		{

-			Framebuffer *framebuffer = getReadFramebuffer();

-			*params = framebuffer->getImplementationColorReadType();

-		}

-		break;

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT:

-		{

-			Framebuffer *framebuffer = getReadFramebuffer();

-			*params = framebuffer->getImplementationColorReadFormat();

-		}

-		break;

-    case GL_MAX_VIEWPORT_DIMS:

-        {

-			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;

-            params[0] = maxDimension;

-            params[1] = maxDimension;

-        }

-        break;

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-        {

-			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)

-            {

-                params[i] = compressedTextureFormats[i];

-            }

-        }

-        break;

-    case GL_VIEWPORT:

-        params[0] = mState.viewportX;

-        params[1] = mState.viewportY;

-        params[2] = mState.viewportWidth;

-        params[3] = mState.viewportHeight;

-        break;

-    case GL_SCISSOR_BOX:

-        params[0] = mState.scissorX;

-        params[1] = mState.scissorY;

-        params[2] = mState.scissorWidth;

-        params[3] = mState.scissorHeight;

-        break;

-    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;

-    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-            Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);

-

-            if(colorbuffer)

-            {

-                switch (pname)

-                {

-                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;

-                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;

-                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;

-                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_DEPTH_BITS:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-

-            if(depthbuffer)

-            {

-                *params = depthbuffer->getDepthSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_STENCIL_BITS:

-        {

-            Framebuffer *framebuffer = getDrawFramebuffer();

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-

-            if(stencilbuffer)

-            {

-                *params = stencilbuffer->getStencilSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-	case GL_TEXTURE_BINDING_2D:

-		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-		{

-			error(GL_INVALID_OPERATION);

-			return false;

-		}

-

-		*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();

-		break;

-	case GL_TEXTURE_BINDING_CUBE_MAP:

-		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-		{

-			error(GL_INVALID_OPERATION);

-			return false;

-		}

-

-		*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();

-		break;

-	case GL_TEXTURE_BINDING_EXTERNAL_OES:

-		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-		{

-			error(GL_INVALID_OPERATION);

-			return false;

-		}

-

-		*params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();

-		break;

-	case GL_TEXTURE_BINDING_3D_OES:

-		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-		{

-			error(GL_INVALID_OPERATION);

-			return false;

-		}

-

-		*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();

-		break;

-	case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0

-		if(clientVersion < 3)

-		{

-			return false;

-		}

-		else if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-		{

-			error(GL_INVALID_OPERATION);

-			return false;

-		}

-

-		*params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();

-		break;

-	case GL_COPY_READ_BUFFER_BINDING: // name, initially 0

-		if(clientVersion >= 3)

-		{

-			*params = mState.copyReadBuffer.name();

-		}

-		else

-		{

-			return false;

-		}

-		break;

-	case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0

-		if(clientVersion >= 3)

-		{

-			*params = mState.copyWriteBuffer.name();

-		}

-		else

-		{

-			return false;

-		}

-		break;

-	case GL_DRAW_BUFFER0:

-	case GL_DRAW_BUFFER1:

-	case GL_DRAW_BUFFER2:

-	case GL_DRAW_BUFFER3:

-	case GL_DRAW_BUFFER4:

-	case GL_DRAW_BUFFER5:

-	case GL_DRAW_BUFFER6:

-	case GL_DRAW_BUFFER7:

-	case GL_DRAW_BUFFER8:

-	case GL_DRAW_BUFFER9:

-	case GL_DRAW_BUFFER10:

-	case GL_DRAW_BUFFER11:

-	case GL_DRAW_BUFFER12:

-	case GL_DRAW_BUFFER13:

-	case GL_DRAW_BUFFER14:

-	case GL_DRAW_BUFFER15:

-		*params = getDrawFramebuffer()->getDrawBuffer(pname - GL_DRAW_BUFFER0);

-		break;

-	case GL_MAJOR_VERSION:

-		if(clientVersion >= 3)

-		{

-			*params = clientVersion;

-		}

-		else

-		{

-			return false;

-		}

-		break;

-	case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048

-		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;

-		break;

-	case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048

-		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;

-		break;

-	case GL_MAX_COLOR_ATTACHMENTS:

-		*params = MAX_COLOR_ATTACHMENTS;

-		break;

-	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048

-		*params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;

-		break;

-	case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70

-		UNIMPLEMENTED();

-		*params = 70;

-		break;

-	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176

-		*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;

-		break;

-	case GL_MAX_DRAW_BUFFERS:

-		*params = MAX_DRAW_BUFFERS;

-		break;

-	case GL_MAX_ELEMENT_INDEX:

-		*params = MAX_ELEMENT_INDEX;

-		break;

-	case GL_MAX_ELEMENTS_INDICES:

-		*params = MAX_ELEMENTS_INDICES;

-		break;

-	case GL_MAX_ELEMENTS_VERTICES:

-		*params = MAX_ELEMENTS_VERTICES;

-		break;

-	case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128

-		UNIMPLEMENTED();

-		*params = 128;

-		break;

-	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12

-		*params = MAX_FRAGMENT_UNIFORM_BLOCKS;

-		break;

-	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 896

-		*params = MAX_FRAGMENT_UNIFORM_COMPONENTS;

-		break;

-	case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7

-		UNIMPLEMENTED();

-		*params = 7;

-		break;

-	case GL_MAX_SERVER_WAIT_TIMEOUT: // integer

-		UNIMPLEMENTED();

-		*params = 0;

-		break;

-	case GL_MAX_TEXTURE_LOD_BIAS: // integer,  at least 2.0

-		UNIMPLEMENTED();

-		*params = 2;

-		break;

-	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64

-		UNIMPLEMENTED();

-		*params = 64;

-		break;

-	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4

-		UNIMPLEMENTED();

-		*params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;

-		break;

-	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4

-		UNIMPLEMENTED();

-		*params = 4;

-		break;

-	case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384

-		*params = MAX_UNIFORM_BLOCK_SIZE;

-		break;

-	case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 24

-		*params = MAX_UNIFORM_BUFFER_BINDINGS;

-		break;

-	case GL_MAX_VARYING_COMPONENTS: // integer, at least 60

-		UNIMPLEMENTED();

-		*params = 60;

-		break;

-	case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer,  at least 64

-		UNIMPLEMENTED();

-		*params = 64;

-		break;

-	case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer,  at least 12

-		*params = MAX_VERTEX_UNIFORM_BLOCKS;

-		break;

-	case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer,  at least 1024

-		*params = MAX_VERTEX_UNIFORM_COMPONENTS;

-		break;

-	case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8

-		UNIMPLEMENTED();

-		*params = -8;

-		break;

-	case GL_MINOR_VERSION: // integer

-		UNIMPLEMENTED();

-		*params = 0;

-		break;

-	case GL_NUM_EXTENSIONS: // integer

-		GLuint numExtensions;

-		getExtensions(0, &numExtensions);

-		*params = numExtensions;

-		break;

-	case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0

-		UNIMPLEMENTED();

-		*params = 0;

-		break;

-	case GL_PACK_ROW_LENGTH: // integer, initially 0

-		*params = mState.packRowLength;

-		break;

-	case GL_PACK_SKIP_PIXELS: // integer, initially 0

-		*params = mState.packSkipPixels;

-		break;

-	case GL_PACK_SKIP_ROWS: // integer, initially 0

-		*params = mState.packSkipRows;

-		break;

-	case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0

-		if(clientVersion >= 3)

-		{

-			*params = mState.pixelPackBuffer.name();

-		}

-		else

-		{

-			return false;

-		}

-		break;

-	case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0

-		if(clientVersion >= 3)

-		{

-			*params = mState.pixelUnpackBuffer.name();

-		}

-		else

-		{

-			return false;

-		}

-		break;

-	case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS​]

-		UNIMPLEMENTED();

-		*params = 0;

-		break;

-	case GL_READ_BUFFER: // symbolic constant,  initial value is GL_BACK​

-		*params = getReadFramebuffer()->getReadBuffer();

-		break;

-	case GL_SAMPLER_BINDING: // GLint, default 0

-		*params = mState.sampler[mState.activeSampler].name();

-		break;

-	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0

-		if(clientVersion >= 3)

-		{

-			*params = mState.genericUniformBuffer.name();

-		}

-		else

-		{

-			return false;

-		}

-		break;

-	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1

-		*params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;

-		break;

-	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0

-		if(clientVersion >= 3)

-		{

-			*params = mState.genericUniformBuffer->size();

-		}

-		else

-		{

-			return false;

-		}

-		break;

-	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0

-		if(clientVersion >= 3)

-		{

-			*params = mState.genericUniformBuffer->offset();

-		}

-		else

-		{

-			return false;

-		}

-		*params = 0;

-		break;

-	case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0

-		*params = mState.unpackInfo.imageHeight;

-		break;

-	case GL_UNPACK_ROW_LENGTH: // integer, initially 0

-		*params = mState.unpackInfo.rowLength;

-		break;

-	case GL_UNPACK_SKIP_IMAGES: // integer, initially 0

-		*params = mState.unpackInfo.skipImages;

-		break;

-	case GL_UNPACK_SKIP_PIXELS: // integer, initially 0

-		*params = mState.unpackInfo.skipPixels;

-		break;

-	case GL_UNPACK_SKIP_ROWS: // integer, initially 0

-		*params = mState.unpackInfo.skipRows;

-		break;

-	case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0

-		*params = getCurrentVertexArray()->name;

-		break;

-	case GL_TRANSFORM_FEEDBACK_BINDING:

-		{

-			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);

-			if(transformFeedback)

-			{

-				*params = transformFeedback->name;

-			}

-			else

-			{

-				return false;

-			}

-		}

-		break;

-	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:

-		{

-			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);

-			if(transformFeedback)

-			{

-				*params = transformFeedback->getGenericBufferName();

-			}

-			else

-			{

-				return false;

-			}

-		}

-		break;

-	default:

-        return false;

-    }

-

-    return true;

-}

-

-template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;

-template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;

-

-template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const

-{

-	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);

-	if(!transformFeedback)

-	{

-		return false;

-	}

-

-	switch(pname)

-	{

-	case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0

-		*param = transformFeedback->name;

-		break;

-	case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE

-		*param = transformFeedback->isActive();

-		break;

-	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0

-		*param = transformFeedback->getBufferName(index);

-		break;

-	case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE

-		*param = transformFeedback->isPaused();

-		break;

-	case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0

-		if(transformFeedback->getBuffer(index))

-		{

-			*param = transformFeedback->getSize(index);

-			break;

-		}

-		else return false;

-	case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0

-		if(transformFeedback->getBuffer(index))

-		{

-			*param = transformFeedback->getOffset(index);

-		break;

-		}

-		else return false;

-	default:

-		return false;

-	}

-

-	return true;

-}

-

-template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;

-template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;

-

-template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const

-{

-	const BufferBinding& uniformBuffer = mState.uniformBuffers[index];

-

-	switch(pname)

-	{

-	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0

-		*param = uniformBuffer.get().name();

-		break;

-	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0

-		*param = uniformBuffer.getSize();

-		break;

-	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0

-		*param = uniformBuffer.getOffset();

-		break;

-	default:

-		return false;

-	}

-

-	return true;

-}

-

-bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-		{

-            *type = GL_INT;

-			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;

-        }

-		break;

-    case GL_SHADER_BINARY_FORMATS:

-        {

-            *type = GL_INT;

-            *numParams = 0;

-        }

-        break;

-    case GL_MAX_VERTEX_ATTRIBS:

-    case GL_MAX_VERTEX_UNIFORM_VECTORS:

-    case GL_MAX_VARYING_VECTORS:

-    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:

-    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:

-    case GL_MAX_TEXTURE_IMAGE_UNITS:

-    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:

-    case GL_MAX_RENDERBUFFER_SIZE:

-    case GL_NUM_SHADER_BINARY_FORMATS:

-    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:

-    case GL_ARRAY_BUFFER_BINDING:

-    case GL_FRAMEBUFFER_BINDING: // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE

-    case GL_READ_FRAMEBUFFER_BINDING_ANGLE:

-    case GL_RENDERBUFFER_BINDING:

-    case GL_CURRENT_PROGRAM:

-    case GL_PACK_ALIGNMENT:

-    case GL_UNPACK_ALIGNMENT:

-    case GL_GENERATE_MIPMAP_HINT:

-    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-    case GL_DEPTH_BITS:

-    case GL_STENCIL_BITS:

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:

-    case GL_CULL_FACE_MODE:

-    case GL_FRONT_FACE:

-    case GL_ACTIVE_TEXTURE:

-    case GL_STENCIL_FUNC:

-    case GL_STENCIL_VALUE_MASK:

-    case GL_STENCIL_REF:

-    case GL_STENCIL_FAIL:

-    case GL_STENCIL_PASS_DEPTH_FAIL:

-    case GL_STENCIL_PASS_DEPTH_PASS:

-    case GL_STENCIL_BACK_FUNC:

-    case GL_STENCIL_BACK_VALUE_MASK:

-    case GL_STENCIL_BACK_REF:

-    case GL_STENCIL_BACK_FAIL:

-    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:

-    case GL_STENCIL_BACK_PASS_DEPTH_PASS:

-    case GL_DEPTH_FUNC:

-    case GL_BLEND_SRC_RGB:

-    case GL_BLEND_SRC_ALPHA:

-    case GL_BLEND_DST_RGB:

-    case GL_BLEND_DST_ALPHA:

-    case GL_BLEND_EQUATION_RGB:

-    case GL_BLEND_EQUATION_ALPHA:

-    case GL_STENCIL_WRITEMASK:

-    case GL_STENCIL_BACK_WRITEMASK:

-    case GL_STENCIL_CLEAR_VALUE:

-    case GL_SUBPIXEL_BITS:

-    case GL_MAX_TEXTURE_SIZE:

-    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE:

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT:

-    case GL_TEXTURE_BINDING_2D:

-    case GL_TEXTURE_BINDING_CUBE_MAP:

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:

-    case GL_TEXTURE_BINDING_3D_OES:

-    case GL_COPY_READ_BUFFER_BINDING:

-    case GL_COPY_WRITE_BUFFER_BINDING:

-    case GL_DRAW_BUFFER0:

-    case GL_DRAW_BUFFER1:

-    case GL_DRAW_BUFFER2:

-    case GL_DRAW_BUFFER3:

-    case GL_DRAW_BUFFER4:

-    case GL_DRAW_BUFFER5:

-    case GL_DRAW_BUFFER6:

-    case GL_DRAW_BUFFER7:

-    case GL_DRAW_BUFFER8:

-    case GL_DRAW_BUFFER9:

-    case GL_DRAW_BUFFER10:

-    case GL_DRAW_BUFFER11:

-    case GL_DRAW_BUFFER12:

-    case GL_DRAW_BUFFER13:

-    case GL_DRAW_BUFFER14:

-    case GL_DRAW_BUFFER15:

-    case GL_MAJOR_VERSION:

-    case GL_MAX_3D_TEXTURE_SIZE:

-    case GL_MAX_ARRAY_TEXTURE_LAYERS:

-    case GL_MAX_COLOR_ATTACHMENTS:

-    case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:

-    case GL_MAX_COMBINED_UNIFORM_BLOCKS:

-    case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:

-    case GL_MAX_DRAW_BUFFERS:

-    case GL_MAX_ELEMENT_INDEX:

-    case GL_MAX_ELEMENTS_INDICES:

-    case GL_MAX_ELEMENTS_VERTICES:

-    case GL_MAX_FRAGMENT_INPUT_COMPONENTS:

-    case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:

-    case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:

-    case GL_MAX_PROGRAM_TEXEL_OFFSET:

-    case GL_MAX_SERVER_WAIT_TIMEOUT:

-    case GL_MAX_TEXTURE_LOD_BIAS:

-    case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:

-    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:

-    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:

-    case GL_MAX_UNIFORM_BLOCK_SIZE:

-    case GL_MAX_UNIFORM_BUFFER_BINDINGS:

-    case GL_MAX_VARYING_COMPONENTS:

-    case GL_MAX_VERTEX_OUTPUT_COMPONENTS:

-    case GL_MAX_VERTEX_UNIFORM_BLOCKS:

-    case GL_MAX_VERTEX_UNIFORM_COMPONENTS:

-    case GL_MIN_PROGRAM_TEXEL_OFFSET:

-    case GL_MINOR_VERSION:

-    case GL_NUM_EXTENSIONS:

-    case GL_NUM_PROGRAM_BINARY_FORMATS:

-    case GL_PACK_ROW_LENGTH:

-    case GL_PACK_SKIP_PIXELS:

-    case GL_PACK_SKIP_ROWS:

-    case GL_PIXEL_PACK_BUFFER_BINDING:

-    case GL_PIXEL_UNPACK_BUFFER_BINDING:

-    case GL_PROGRAM_BINARY_FORMATS:

-    case GL_READ_BUFFER:

-    case GL_SAMPLER_BINDING:

-    case GL_TEXTURE_BINDING_2D_ARRAY:

-    case GL_UNIFORM_BUFFER_BINDING:

-    case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:

-    case GL_UNIFORM_BUFFER_SIZE:

-    case GL_UNIFORM_BUFFER_START:

-    case GL_UNPACK_IMAGE_HEIGHT:

-    case GL_UNPACK_ROW_LENGTH:

-    case GL_UNPACK_SKIP_IMAGES:

-    case GL_UNPACK_SKIP_PIXELS:

-    case GL_UNPACK_SKIP_ROWS:

-    case GL_VERTEX_ARRAY_BINDING:

-	case GL_TRANSFORM_FEEDBACK_BINDING:

-	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:

-        {

-            *type = GL_INT;

-            *numParams = 1;

-        }

-        break;

-    case GL_MAX_SAMPLES_ANGLE:

-        {

-            *type = GL_INT;

-            *numParams = 1;

-        }

-        break;

-    case GL_MAX_VIEWPORT_DIMS:

-        {

-            *type = GL_INT;

-            *numParams = 2;

-        }

-        break;

-    case GL_VIEWPORT:

-    case GL_SCISSOR_BOX:

-        {

-            *type = GL_INT;

-            *numParams = 4;

-        }

-        break;

-    case GL_SHADER_COMPILER:

-    case GL_SAMPLE_COVERAGE_INVERT:

-    case GL_DEPTH_WRITEMASK:

-    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,

-    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural

-    case GL_SAMPLE_COVERAGE:

-    case GL_SCISSOR_TEST:

-    case GL_STENCIL_TEST:

-    case GL_DEPTH_TEST:

-    case GL_BLEND:

-    case GL_DITHER:

-    case GL_PRIMITIVE_RESTART_FIXED_INDEX:

-    case GL_RASTERIZER_DISCARD:

-    case GL_TRANSFORM_FEEDBACK_ACTIVE:

-    case GL_TRANSFORM_FEEDBACK_PAUSED:

-        {

-            *type = GL_BOOL;

-            *numParams = 1;

-        }

-        break;

-    case GL_COLOR_WRITEMASK:

-        {

-            *type = GL_BOOL;

-            *numParams = 4;

-        }

-        break;

-    case GL_POLYGON_OFFSET_FACTOR:

-    case GL_POLYGON_OFFSET_UNITS:

-    case GL_SAMPLE_COVERAGE_VALUE:

-    case GL_DEPTH_CLEAR_VALUE:

-    case GL_LINE_WIDTH:

-        {

-            *type = GL_FLOAT;

-            *numParams = 1;

-        }

-        break;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-    case GL_ALIASED_POINT_SIZE_RANGE:

-    case GL_DEPTH_RANGE:

-        {

-            *type = GL_FLOAT;

-            *numParams = 2;

-        }

-        break;

-    case GL_COLOR_CLEAR_VALUE:

-    case GL_BLEND_COLOR:

-        {

-            *type = GL_FLOAT;

-            *numParams = 4;

-        }

-        break;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-        *type = GL_FLOAT;

-        *numParams = 1;

-        break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-void Context::applyScissor(int width, int height)

-{

-	if(mState.scissorTestEnabled)

-	{

-		sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };

-		scissor.clip(0, 0, width, height);

-

-		device->setScissorRect(scissor);

-		device->setScissorEnable(true);

-	}

-	else

-	{

-		device->setScissorEnable(false);

-	}

-}

-

-// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle

-bool Context::applyRenderTarget()

-{

-    Framebuffer *framebuffer = getDrawFramebuffer();

-	int width, height, samples;

-

-    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);

-    }

-

-	for(int i = 0; i < MAX_DRAW_BUFFERS; i++)

-	{

-		if(framebuffer->getDrawBuffer(i) != GL_NONE)

-		{

-			egl::Image *renderTarget = framebuffer->getRenderTarget(i);

-			device->setRenderTarget(i, renderTarget);

-			if(renderTarget) renderTarget->release();

-		}

-		else

-		{

-			device->setRenderTarget(i, nullptr);

-		}

-	}

-

-    egl::Image *depthBuffer = framebuffer->getDepthBuffer();

-    device->setDepthBuffer(depthBuffer);

-	if(depthBuffer) depthBuffer->release();

-

-	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();

-	device->setStencilBuffer(stencilBuffer);

-	if(stencilBuffer) stencilBuffer->release();

-

-    Viewport viewport;

-    float zNear = clamp01(mState.zNear);

-    float zFar = clamp01(mState.zFar);

-

-    viewport.x0 = mState.viewportX;

-    viewport.y0 = mState.viewportY;

-    viewport.width = mState.viewportWidth;

-    viewport.height = mState.viewportHeight;

-    viewport.minZ = zNear;

-    viewport.maxZ = zFar;

-

-    device->setViewport(viewport);

-

-	applyScissor(width, height);

-

-	Program *program = getCurrentProgram();

-

-	if(program)

-	{

-		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};

-        program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);

-		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);

-		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);

-    }

-

-    return true;

-}

-

-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)

-void Context::applyState(GLenum drawMode)

-{

-    Framebuffer *framebuffer = getDrawFramebuffer();

-

-    if(mState.cullFaceEnabled)

-    {

-        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));

-    }

-    else

-    {

-		device->setCullMode(sw::CULL_NONE);

-    }

-

-    if(mDepthStateDirty)

-    {

-        if(mState.depthTestEnabled)

-        {

-			device->setDepthBufferEnable(true);

-			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));

-        }

-        else

-        {

-            device->setDepthBufferEnable(false);

-        }

-

-        mDepthStateDirty = false;

-    }

-

-    if(mBlendStateDirty)

-    {

-        if(mState.blendEnabled)

-        {

-			device->setAlphaBlendEnable(true);

-			device->setSeparateAlphaBlendEnable(true);

-

-            device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));

-

-			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));

-			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));

-			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));

-

-            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));

-			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));

-			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));

-        }

-        else

-        {

-			device->setAlphaBlendEnable(false);

-        }

-

-        mBlendStateDirty = false;

-    }

-

-    if(mStencilStateDirty || mFrontFaceDirty)

-    {

-        if(mState.stencilTestEnabled && framebuffer->hasStencil())

-        {

-			device->setStencilEnable(true);

-			device->setTwoSidedStencil(true);

-

-            // get the maximum size of the stencil ref

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;

-

-			if(mState.frontFace == GL_CCW)

-			{

-				device->setStencilWriteMask(mState.stencilWritemask);

-				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-				device->setStencilMask(mState.stencilMask);

-

-				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));

-				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-

-				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);

-				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));

-

-				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);

-				device->setStencilMaskCCW(mState.stencilBackMask);

-

-				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));

-				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));

-				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));

-			}

-			else

-			{

-				device->setStencilWriteMaskCCW(mState.stencilWritemask);

-				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-				device->setStencilMaskCCW(mState.stencilMask);

-

-				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));

-				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-

-				device->setStencilWriteMask(mState.stencilBackWritemask);

-				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));

-

-				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);

-				device->setStencilMask(mState.stencilBackMask);

-

-				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));

-				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));

-				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));

-			}

-        }

-        else

-        {

-			device->setStencilEnable(false);

-        }

-

-        mStencilStateDirty = false;

-        mFrontFaceDirty = false;

-    }

-

-    if(mMaskStateDirty)

-    {

-		for(int i = 0; i < MAX_DRAW_BUFFERS; i++)

-		{

-			device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));

-		}

-

-		device->setDepthWriteEnable(mState.depthMask);

-

-        mMaskStateDirty = false;

-    }

-

-    if(mPolygonOffsetStateDirty)

-    {

-        if(mState.polygonOffsetFillEnabled)

-        {

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-            if(depthbuffer)

-            {

-				device->setSlopeDepthBias(mState.polygonOffsetFactor);

-                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));

-				device->setDepthBias(depthBias);

-            }

-        }

-        else

-        {

-            device->setSlopeDepthBias(0);

-            device->setDepthBias(0);

-        }

-

-        mPolygonOffsetStateDirty = false;

-    }

-

-    if(mSampleStateDirty)

-    {

-        if(mState.sampleAlphaToCoverageEnabled)

-        {

-            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);

-        }

-		else

-		{

-			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);

-		}

-

-        if(mState.sampleCoverageEnabled)

-        {

-            unsigned int mask = 0;

-            if(mState.sampleCoverageValue != 0)

-            {

-				int width, height, samples;

-				framebuffer->completeness(width, height, samples);

-

-                float threshold = 0.5f;

-

-                for(int i = 0; i < samples; i++)

-                {

-                    mask <<= 1;

-

-                    if((i + 1) * mState.sampleCoverageValue >= threshold)

-                    {

-                        threshold += 1.0f;

-                        mask |= 1;

-                    }

-                }

-            }

-

-            if(mState.sampleCoverageInvert)

-            {

-                mask = ~mask;

-            }

-

-			device->setMultiSampleMask(mask);

-        }

-        else

-        {

-			device->setMultiSampleMask(0xFFFFFFFF);

-        }

-

-        mSampleStateDirty = false;

-    }

-

-    if(mDitherStateDirty)

-    {

-    //	UNIMPLEMENTED();   // FIXME

-

-        mDitherStateDirty = false;

-    }

-

-	device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);

-}

-

-GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)

-{

-    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];

-

-    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);

-    if(err != GL_NO_ERROR)

-    {

-        return err;

-    }

-

-	Program *program = getCurrentProgram();

-

-	device->resetInputStreams(false);

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-	{

-		if(program->getAttributeStream(i) == -1)

-		{

-			continue;

-		}

-

-		sw::Resource *resource = attributes[i].vertexBuffer;

-		const void *buffer = (char*)resource->data() + attributes[i].offset;

-

-		int stride = attributes[i].stride;

-

-		buffer = (char*)buffer + stride * base;

-

-		sw::Stream attribute(resource, buffer, stride);

-

-		attribute.type = attributes[i].type;

-		attribute.count = attributes[i].count;

-		attribute.normalized = attributes[i].normalized;

-

-		int stream = program->getAttributeStream(i);

-		device->setInputStream(stream, attribute);

-	}

-

-	return GL_NO_ERROR;

-}

-

-// Applies the indices and element array bindings

-GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)

-{

-	GLenum err = mIndexDataManager->prepareIndexData(type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo);

-

-    if(err == GL_NO_ERROR)

-    {

-        device->setIndexBuffer(indexInfo->indexBuffer);

-    }

-

-    return err;

-}

-

-// Applies the shaders and shader constants

-void Context::applyShaders()

-{

-    Program *programObject = getCurrentProgram();

-    sw::VertexShader *vertexShader = programObject->getVertexShader();

-	sw::PixelShader *pixelShader = programObject->getPixelShader();

-

-    device->setVertexShader(vertexShader);

-    device->setPixelShader(pixelShader);

-

-    if(programObject->getSerial() != mAppliedProgramSerial)

-    {

-        programObject->dirtyAllUniforms();

-        mAppliedProgramSerial = programObject->getSerial();

-    }

-

-    programObject->applyUniformBuffers(mState.uniformBuffers);

-    programObject->applyUniforms();

-}

-

-void Context::applyTextures()

-{

-    applyTextures(sw::SAMPLER_PIXEL);

-	applyTextures(sw::SAMPLER_VERTEX);

-}

-

-void Context::applyTextures(sw::SamplerType samplerType)

-{

-    Program *programObject = getCurrentProgram();

-

-    int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type

-

-    for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)

-    {

-        int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index

-

-        if(textureUnit != -1)

-        {

-            TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);

-

-            Texture *texture = getSamplerTexture(textureUnit, textureType);

-

-			if(texture->isSamplerComplete())

-            {

-				GLenum wrapS, wrapT, wrapR, minFilter, magFilter;

-

-				Sampler *samplerObject = mState.sampler[textureUnit];

-				if(samplerObject)

-				{

-					wrapS = samplerObject->getWrapS();

-					wrapT = samplerObject->getWrapT();

-					wrapR = samplerObject->getWrapR();

-					minFilter = samplerObject->getMinFilter();

-					magFilter = samplerObject->getMagFilter();

-				}

-				else

-				{

-					wrapS = texture->getWrapS();

-					wrapT = texture->getWrapT();

-					wrapR = texture->getWrapR();

-					minFilter = texture->getMinFilter();

-					magFilter = texture->getMagFilter();

-				}

-				GLfloat maxAnisotropy = texture->getMaxAnisotropy();

-

-				GLenum swizzleR = texture->getSwizzleR();

-				GLenum swizzleG = texture->getSwizzleG();

-				GLenum swizzleB = texture->getSwizzleB();

-				GLenum swizzleA = texture->getSwizzleA();

-

-				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));

-				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));

-				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));

-				device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));

-				device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));

-				device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));

-				device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));

-

-				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));

-				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));

-				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);

-

-				applyTexture(samplerType, samplerIndex, texture);

-            }

-            else

-            {

-                applyTexture(samplerType, samplerIndex, nullptr);

-            }

-        }

-        else

-        {

-            applyTexture(samplerType, samplerIndex, nullptr);

-        }

-    }

-}

-

-void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)

-{

-	Program *program = getCurrentProgram();

-	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;

-	bool textureUsed = false;

-

-	if(type == sw::SAMPLER_PIXEL)

-	{

-		textureUsed = program->getPixelShader()->usesSampler(index);

-	}

-	else if(type == sw::SAMPLER_VERTEX)

-	{

-		textureUsed = program->getVertexShader()->usesSampler(index);

-	}

-	else UNREACHABLE(type);

-

-	sw::Resource *resource = 0;

-

-	if(baseTexture && textureUsed)

-	{

-		resource = baseTexture->getResource();

-	}

-

-	device->setTextureResource(sampler, resource);

-

-	if(baseTexture && textureUsed)

-	{

-		int levelCount = baseTexture->getLevelCount();

-

-		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)

-		{

-			Texture2D *texture = static_cast<Texture2D*>(baseTexture);

-

-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-			{

-				int surfaceLevel = mipmapLevel;

-

-				if(surfaceLevel < 0)

-				{

-					surfaceLevel = 0;

-				}

-				else if(surfaceLevel >= levelCount)

-				{

-					surfaceLevel = levelCount - 1;

-				}

-

-				egl::Image *surface = texture->getImage(surfaceLevel);

-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);

-			}

-		}

-		else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES)

-		{

-			Texture3D *texture = static_cast<Texture3D*>(baseTexture);

-

-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-			{

-				int surfaceLevel = mipmapLevel;

-

-				if(surfaceLevel < 0)

-				{

-					surfaceLevel = 0;

-				}

-				else if(surfaceLevel >= levelCount)

-				{

-					surfaceLevel = levelCount - 1;

-				}

-

-				egl::Image *surface = texture->getImage(surfaceLevel);

-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);

-			}

-		}

-		else if(baseTexture->getTarget() == GL_TEXTURE_2D_ARRAY)

-		{

-			Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);

-

-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-			{

-				int surfaceLevel = mipmapLevel;

-

-				if(surfaceLevel < 0)

-				{

-					surfaceLevel = 0;

-				}

-				else if(surfaceLevel >= levelCount)

-				{

-					surfaceLevel = levelCount - 1;

-				}

-

-				egl::Image *surface = texture->getImage(surfaceLevel);

-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);

-			}

-		}

-		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)

-		{

-			for(int face = 0; face < 6; face++)

-			{

-				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);

-

-				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-				{

-					int surfaceLevel = mipmapLevel;

-

-					if(surfaceLevel < 0)

-					{

-						surfaceLevel = 0;

-					}

-					else if(surfaceLevel >= levelCount)

-					{

-						surfaceLevel = levelCount - 1;

-					}

-

-					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);

-					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);

-				}

-			}

-		}

-		else UNIMPLEMENTED();

-	}

-	else

-	{

-		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);

-	}

-}

-

-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)

-{

-	Framebuffer *framebuffer = getReadFramebuffer();

-	int framebufferWidth, framebufferHeight, framebufferSamples;

-

-	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)

-	{

-		return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-	}

-

-	if(getReadFramebufferName() != 0 && framebufferSamples != 0)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	GLenum readFormat = GL_NONE;

-	GLenum readType = GL_NONE;

-	switch(format)

-	{

-	case GL_DEPTH_COMPONENT:

-		readFormat = framebuffer->getDepthReadFormat();

-		readType = framebuffer->getDepthReadType();

-		break;

-	default:

-		readFormat = framebuffer->getImplementationColorReadFormat();

-		readType = framebuffer->getImplementationColorReadType();

-		break;

-	}

-

-	if(!(readFormat == format && readType == type) && !ValidReadPixelsFormatType(readFormat, readType, format, type, clientVersion))

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	GLsizei outputWidth = (mState.packRowLength > 0) ? mState.packRowLength : width;

-	GLsizei outputPitch = egl::ComputePitch(outputWidth, format, type, mState.packAlignment);

-	GLsizei outputHeight = (mState.packImageHeight == 0) ? height : mState.packImageHeight;

-	pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;

-	pixels = ((char*)pixels) + egl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packAlignment, mState.packSkipImages, mState.packSkipRows, mState.packSkipPixels);

-

-	// Sized query sanity check

-	if(bufSize)

-	{

-		int requiredSize = outputPitch * height;

-		if(requiredSize > *bufSize)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-

-	egl::Image *renderTarget = nullptr;

-	switch(format)

-	{

-	case GL_DEPTH_COMPONENT:

-		renderTarget = framebuffer->getDepthBuffer();

-		break;

-	default:

-		renderTarget = framebuffer->getReadRenderTarget();

-		break;

-	}

-

-	if(!renderTarget)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	sw::Rect rect = {x, y, x + width, y + height};

-	sw::Rect dstRect = { 0, 0, width, height };

-	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

-

-	sw::Surface externalSurface(width, height, 1, egl::ConvertFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);

-	sw::SliceRect sliceRect(rect);

-	sw::SliceRect dstSliceRect(dstRect);

-	device->blit(renderTarget, sliceRect, &externalSurface, dstSliceRect, false);

-

-	renderTarget->release();

-}

-

-void Context::clear(GLbitfield mask)

-{

-	if(mState.rasterizerDiscardEnabled)

-	{

-		return;

-	}

-

-    Framebuffer *framebuffer = getDrawFramebuffer();

-

-    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-	if(mask & GL_COLOR_BUFFER_BIT)

-	{

-		unsigned int rgbaMask = getColorMask();

-

-		if(rgbaMask != 0)

-		{

-			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);

-		}

-	}

-

-	if(mask & GL_DEPTH_BUFFER_BIT)

-	{

-		if(mState.depthMask != 0)

-		{

-			float depth = clamp01(mState.depthClearValue);

-			device->clearDepth(depth);

-		}

-	}

-

-	if(mask & GL_STENCIL_BUFFER_BIT)

-	{

-		if(mState.stencilWritemask != 0)

-		{

-			int stencil = mState.stencilClearValue & 0x000000FF;

-			device->clearStencil(stencil, mState.stencilWritemask);

-		}

-	}

-}

-

-void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)

-{

-	unsigned int rgbaMask = getColorMask();

-	if(rgbaMask && !mState.rasterizerDiscardEnabled)

-	{

-		Framebuffer *framebuffer = getDrawFramebuffer();

-		egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);

-

-		if(colorbuffer)

-		{

-			sw::SliceRect clearRect = colorbuffer->getRect();

-

-			if(mState.scissorTestEnabled)

-			{

-				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);

-			}

-

-			device->clear(value, format, colorbuffer, clearRect, rgbaMask);

-

-			colorbuffer->release();

-		}

-	}

-}

-

-void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)

-{

-	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);

-}

-

-void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)

-{

-	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);

-}

-

-void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)

-{

-	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);

-}

-

-void Context::clearDepthBuffer(const GLfloat value)

-{

-	if(mState.depthMask && !mState.rasterizerDiscardEnabled)

-	{

-		Framebuffer *framebuffer = getDrawFramebuffer();

-		egl::Image *depthbuffer = framebuffer->getDepthBuffer();

-

-		if(depthbuffer)

-		{

-			float depth = clamp01(value);

-			sw::SliceRect clearRect = depthbuffer->getRect();

-

-			if(mState.scissorTestEnabled)

-			{

-				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);

-			}

-

-			depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-

-			depthbuffer->release();

-		}

-	}

-}

-

-void Context::clearStencilBuffer(const GLint value)

-{

-	if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)

-	{

-		Framebuffer *framebuffer = getDrawFramebuffer();

-		egl::Image *stencilbuffer = framebuffer->getStencilBuffer();

-

-		if(stencilbuffer)

-		{

-			unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);

-			sw::SliceRect clearRect = stencilbuffer->getRect();

-

-			if(mState.scissorTestEnabled)

-			{

-				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);

-			}

-

-			stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-

-			stencilbuffer->release();

-		}

-	}

-}

-

-void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)

-{

-    if(!mState.currentProgram)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    sw::DrawType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-	for(int i = 0; i < instanceCount; ++i)

-	{

-		device->setInstanceID(i);

-

-		GLenum err = applyVertexBuffer(0, first, count, i);

-		if(err != GL_NO_ERROR)

-		{

-			return error(err);

-		}

-

-		applyShaders();

-		applyTextures();

-

-		if(!getCurrentProgram()->validateSamplers(false))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!cullSkipsDraw(mode))

-		{

-			device->drawPrimitive(primitiveType, primitiveCount);

-		}

-	}

-}

-

-void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)

-{

-    if(!mState.currentProgram)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    sw::DrawType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-	for(int i = 0; i < instanceCount; ++i)

-	{

-		device->setInstanceID(i);

-

-		TranslatedIndexData indexInfo;

-		GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);

-		if(err != GL_NO_ERROR)

-		{

-			return error(err);

-		}

-

-		GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;

-		err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);

-		if(err != GL_NO_ERROR)

-		{

-			return error(err);

-		}

-

-		applyShaders();

-		applyTextures();

-

-		if(!getCurrentProgram()->validateSamplers(false))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!cullSkipsDraw(mode))

-		{

-			device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);

-		}

-	}

-}

-

-void Context::finish()

-{

-	device->finish();

-}

-

-void Context::flush()

-{

-    // We don't queue anything without processing it as fast as possible

-}

-

-void Context::recordInvalidEnum()

-{

-    mInvalidEnum = true;

-}

-

-void Context::recordInvalidValue()

-{

-    mInvalidValue = true;

-}

-

-void Context::recordInvalidOperation()

-{

-    mInvalidOperation = true;

-}

-

-void Context::recordOutOfMemory()

-{

-    mOutOfMemory = true;

-}

-

-void Context::recordInvalidFramebufferOperation()

-{

-    mInvalidFramebufferOperation = true;

-}

-

-// Get one of the recorded errors and clear its flag, if any.

-// [OpenGL ES 2.0.24] section 2.5 page 13.

-GLenum Context::getError()

-{

-    if(mInvalidEnum)

-    {

-        mInvalidEnum = false;

-

-        return GL_INVALID_ENUM;

-    }

-

-    if(mInvalidValue)

-    {

-        mInvalidValue = false;

-

-        return GL_INVALID_VALUE;

-    }

-

-    if(mInvalidOperation)

-    {

-        mInvalidOperation = false;

-

-        return GL_INVALID_OPERATION;

-    }

-

-    if(mOutOfMemory)

-    {

-        mOutOfMemory = false;

-

-        return GL_OUT_OF_MEMORY;

-    }

-

-    if(mInvalidFramebufferOperation)

-    {

-        mInvalidFramebufferOperation = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION;

-    }

-

-    return GL_NO_ERROR;

-}

-

-int Context::getSupportedMultisampleCount(int requested)

-{

-	int supported = 0;

-

-	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)

-	{

-		if(supported >= requested)

-		{

-			return supported;

-		}

-

-		supported = multisampleCount[i];

-	}

-

-	return supported;

-}

-

-void Context::detachBuffer(GLuint buffer)

-{

-	// [OpenGL ES 2.0.24] section 2.9 page 22:

-	// If a buffer object is deleted while it is bound, all bindings to that object in the current context

-	// (i.e. in the thread that called Delete-Buffers) are reset to zero.

-

-	if(mState.copyReadBuffer.name() == buffer)

-	{

-		mState.copyReadBuffer = nullptr;

-	}

-

-	if(mState.copyWriteBuffer.name() == buffer)

-	{

-		mState.copyWriteBuffer = nullptr;

-	}

-

-	if(mState.pixelPackBuffer.name() == buffer)

-	{

-		mState.pixelPackBuffer = nullptr;

-	}

-

-	if(mState.pixelUnpackBuffer.name() == buffer)

-	{

-		mState.pixelUnpackBuffer = nullptr;

-	}

-

-	if(mState.genericUniformBuffer.name() == buffer)

-	{

-		mState.genericUniformBuffer = nullptr;

-	}

-

-	if(getArrayBufferName() == buffer)

-	{

-		mState.arrayBuffer = nullptr;

-	}

-

-	// Only detach from the current transform feedback

-	TransformFeedback* currentTransformFeedback = getTransformFeedback();

-	if(currentTransformFeedback)

-	{

-		currentTransformFeedback->detachBuffer(buffer);

-	}

-

-	// Only detach from the current vertex array

-	VertexArray* currentVertexArray = getCurrentVertexArray();

-	if(currentVertexArray)

-	{

-		currentVertexArray->detachBuffer(buffer);

-	}

-

-	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)

-	{

-		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)

-		{

-			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;

-		}

-	}

-}

-

-void Context::detachTexture(GLuint texture)

-{

-    // [OpenGL ES 2.0.24] section 3.8 page 84:

-    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are

-    // rebound to texture object zero

-

-    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-    {

-        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)

-        {

-            if(mState.samplerTexture[type][sampler].name() == texture)

-            {

-                mState.samplerTexture[type][sampler] = nullptr;

-            }

-        }

-    }

-

-    // [OpenGL ES 2.0.24] section 4.4 page 112:

-    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is

-    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this

-    // image was attached in the currently bound framebuffer.

-

-    Framebuffer *readFramebuffer = getReadFramebuffer();

-    Framebuffer *drawFramebuffer = getDrawFramebuffer();

-

-    if(readFramebuffer)

-    {

-        readFramebuffer->detachTexture(texture);

-    }

-

-    if(drawFramebuffer && drawFramebuffer != readFramebuffer)

-    {

-        drawFramebuffer->detachTexture(texture);

-    }

-}

-

-void Context::detachFramebuffer(GLuint framebuffer)

-{

-    // [OpenGL ES 2.0.24] section 4.4 page 107:

-    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though

-    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.

-

-    if(mState.readFramebuffer == framebuffer)

-    {

-        bindReadFramebuffer(0);

-    }

-

-    if(mState.drawFramebuffer == framebuffer)

-    {

-        bindDrawFramebuffer(0);

-    }

-}

-

-void Context::detachRenderbuffer(GLuint renderbuffer)

-{

-    // [OpenGL ES 2.0.24] section 4.4 page 109:

-    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer

-    // had been executed with the target RENDERBUFFER and name of zero.

-

-    if(mState.renderbuffer.name() == renderbuffer)

-    {

-        bindRenderbuffer(0);

-    }

-

-    // [OpenGL ES 2.0.24] section 4.4 page 111:

-    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,

-    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment

-    // point to which this image was attached in the currently bound framebuffer.

-

-    Framebuffer *readFramebuffer = getReadFramebuffer();

-    Framebuffer *drawFramebuffer = getDrawFramebuffer();

-

-    if(readFramebuffer)

-    {

-        readFramebuffer->detachRenderbuffer(renderbuffer);

-    }

-

-    if(drawFramebuffer && drawFramebuffer != readFramebuffer)

-    {

-        drawFramebuffer->detachRenderbuffer(renderbuffer);

-    }

-}

-

-void Context::detachSampler(GLuint sampler)

-{

-	// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:

-	// If a sampler object that is currently bound to one or more texture units is

-	// deleted, it is as though BindSampler is called once for each texture unit to

-	// which the sampler is bound, with unit set to the texture unit and sampler set to zero.

-	for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)

-	{

-		gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];

-		if(samplerBinding.name() == sampler)

-		{

-			samplerBinding = nullptr;

-		}

-	}

-}

-

-bool Context::cullSkipsDraw(GLenum drawMode)

-{

-    return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);

-}

-

-bool Context::isTriangleMode(GLenum drawMode)

-{

-    switch (drawMode)

-    {

-      case GL_TRIANGLES:

-      case GL_TRIANGLE_FAN:

-      case GL_TRIANGLE_STRIP:

-        return true;

-      case GL_POINTS:

-      case GL_LINES:

-      case GL_LINE_LOOP:

-      case GL_LINE_STRIP:

-        return false;

-      default: UNREACHABLE(drawMode);

-    }

-

-    return false;

-}

-

-void Context::setVertexAttrib(GLuint index, const GLfloat *values)

-{

-    ASSERT(index < MAX_VERTEX_ATTRIBS);

-

-    mState.vertexAttribute[index].setCurrentValue(values);

-

-    mVertexDataManager->dirtyCurrentValue(index);

-}

-

-void Context::setVertexAttrib(GLuint index, const GLint *values)

-{

-	ASSERT(index < MAX_VERTEX_ATTRIBS);

-

-	mState.vertexAttribute[index].setCurrentValue(values);

-

-	mVertexDataManager->dirtyCurrentValue(index);

-}

-

-void Context::setVertexAttrib(GLuint index, const GLuint *values)

-{

-	ASSERT(index < MAX_VERTEX_ATTRIBS);

-

-	mState.vertexAttribute[index].setCurrentValue(values);

-

-	mVertexDataManager->dirtyCurrentValue(index);

-}

-

-void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,

-                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                              GLbitfield mask)

-{

-    Framebuffer *readFramebuffer = getReadFramebuffer();

-    Framebuffer *drawFramebuffer = getDrawFramebuffer();

-

-	int readBufferWidth, readBufferHeight, readBufferSamples;

-    int drawBufferWidth, drawBufferHeight, drawBufferSamples;

-

-    if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||

-       !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-    }

-

-    if(drawBufferSamples > 1)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    sw::SliceRect sourceRect;

-    sw::SliceRect destRect;

-	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);

-	bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1);

-

-    if(srcX0 < srcX1)

-    {

-        sourceRect.x0 = srcX0;

-        sourceRect.x1 = srcX1;

-    }

-    else

-    {

-        sourceRect.x0 = srcX1;

-        sourceRect.x1 = srcX0;

-    }

-

-	if(dstX0 < dstX1)

-	{

-		destRect.x0 = dstX0;

-		destRect.x1 = dstX1;

-	}

-	else

-	{

-		destRect.x0 = dstX1;

-		destRect.x1 = dstX0;

-	}

-

-    if(srcY0 < srcY1)

-    {

-        sourceRect.y0 = srcY0;

-        sourceRect.y1 = srcY1;

-    }

-    else

-    {

-        sourceRect.y0 = srcY1;

-        sourceRect.y1 = srcY0;

-    }

-

-	if(dstY0 < dstY1)

-	{

-		destRect.y0 = dstY0;

-		destRect.y1 = dstY1;

-	}

-	else

-	{

-		destRect.y0 = dstY1;

-		destRect.y1 = dstY0;

-	}

-

-	sw::Rect sourceScissoredRect = sourceRect;

-    sw::Rect destScissoredRect = destRect;

-

-    if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test

-    {

-        if(destRect.x0 < mState.scissorX)

-        {

-            int xDiff = mState.scissorX - destRect.x0;

-            destScissoredRect.x0 = mState.scissorX;

-            sourceScissoredRect.x0 += xDiff;

-        }

-

-        if(destRect.x1 > mState.scissorX + mState.scissorWidth)

-        {

-            int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);

-            destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;

-            sourceScissoredRect.x1 -= xDiff;

-        }

-

-        if(destRect.y0 < mState.scissorY)

-        {

-            int yDiff = mState.scissorY - destRect.y0;

-            destScissoredRect.y0 = mState.scissorY;

-            sourceScissoredRect.y0 += yDiff;

-        }

-

-        if(destRect.y1 > mState.scissorY + mState.scissorHeight)

-        {

-            int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);

-            destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;

-            sourceScissoredRect.y1 -= yDiff;

-        }

-    }

-

-    sw::Rect sourceTrimmedRect = sourceScissoredRect;

-    sw::Rect destTrimmedRect = destScissoredRect;

-

-    // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of

-    // the actual draw and read surfaces.

-    if(sourceTrimmedRect.x0 < 0)

-    {

-        int xDiff = 0 - sourceTrimmedRect.x0;

-        sourceTrimmedRect.x0 = 0;

-        destTrimmedRect.x0 += xDiff;

-    }

-

-    if(sourceTrimmedRect.x1 > readBufferWidth)

-    {

-        int xDiff = sourceTrimmedRect.x1 - readBufferWidth;

-        sourceTrimmedRect.x1 = readBufferWidth;

-        destTrimmedRect.x1 -= xDiff;

-    }

-

-    if(sourceTrimmedRect.y0 < 0)

-    {

-        int yDiff = 0 - sourceTrimmedRect.y0;

-        sourceTrimmedRect.y0 = 0;

-        destTrimmedRect.y0 += yDiff;

-    }

-

-    if(sourceTrimmedRect.y1 > readBufferHeight)

-    {

-        int yDiff = sourceTrimmedRect.y1 - readBufferHeight;

-        sourceTrimmedRect.y1 = readBufferHeight;

-        destTrimmedRect.y1 -= yDiff;

-    }

-

-    if(destTrimmedRect.x0 < 0)

-    {

-        int xDiff = 0 - destTrimmedRect.x0;

-        destTrimmedRect.x0 = 0;

-        sourceTrimmedRect.x0 += xDiff;

-    }

-

-    if(destTrimmedRect.x1 > drawBufferWidth)

-    {

-        int xDiff = destTrimmedRect.x1 - drawBufferWidth;

-        destTrimmedRect.x1 = drawBufferWidth;

-        sourceTrimmedRect.x1 -= xDiff;

-    }

-

-    if(destTrimmedRect.y0 < 0)

-    {

-        int yDiff = 0 - destTrimmedRect.y0;

-        destTrimmedRect.y0 = 0;

-        sourceTrimmedRect.y0 += yDiff;

-    }

-

-    if(destTrimmedRect.y1 > drawBufferHeight)

-    {

-        int yDiff = destTrimmedRect.y1 - drawBufferHeight;

-        destTrimmedRect.y1 = drawBufferHeight;

-        sourceTrimmedRect.y1 -= yDiff;

-    }

-

-    bool partialBufferCopy = false;

-

-    if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||

-       sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||

-       destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||

-       destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||

-       sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)

-    {

-        partialBufferCopy = true;

-    }

-

-	bool blitRenderTarget = false;

-    bool blitDepthStencil = false;

-

-    if(mask & GL_COLOR_BUFFER_BIT)

-    {

-		GLenum readColorbufferType = readFramebuffer->getColorbufferType(getReadFramebufferColorIndex());

-		GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);

-		const bool validReadType = readColorbufferType == GL_TEXTURE_2D || Framebuffer::IsRenderbuffer(readColorbufferType);

-		const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || Framebuffer::IsRenderbuffer(drawColorbufferType);

-        if(!validReadType || !validDrawType)

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-

-        if(partialBufferCopy && readBufferSamples > 1)

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-

-        blitRenderTarget = true;

-    }

-

-    if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))

-    {

-        Renderbuffer *readDSBuffer = nullptr;

-        Renderbuffer *drawDSBuffer = nullptr;

-

-        if(mask & GL_DEPTH_BUFFER_BIT)

-        {

-            if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())

-            {

-                if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType())

-                {

-                    return error(GL_INVALID_OPERATION);

-                }

-

-                blitDepthStencil = true;

-                readDSBuffer = readFramebuffer->getDepthbuffer();

-                drawDSBuffer = drawFramebuffer->getDepthbuffer();

-            }

-        }

-

-        if(mask & GL_STENCIL_BUFFER_BIT)

-        {

-            if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())

-            {

-                if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType())

-                {

-                    return error(GL_INVALID_OPERATION);

-                }

-

-                blitDepthStencil = true;

-                readDSBuffer = readFramebuffer->getStencilbuffer();

-                drawDSBuffer = drawFramebuffer->getStencilbuffer();

-            }

-        }

-

-        if(partialBufferCopy)

-        {

-            ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");

-            return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted

-        }

-

-        if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||

-           (readDSBuffer && readDSBuffer->getSamples() > 1))

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-    }

-

-    if(blitRenderTarget || blitDepthStencil)

-    {

-        if(blitRenderTarget)

-        {

-            egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();

-            egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);

-

-			if(flipX)

-			{

-				swap(destRect.x0, destRect.x1);

-			}

-			if(flipy)

-			{

-				swap(destRect.y0, destRect.y1);

-			}

-

-            bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);

-

-            readRenderTarget->release();

-            drawRenderTarget->release();

-

-            if(!success)

-            {

-                ERR("BlitFramebuffer failed.");

-                return;

-            }

-        }

-

-        if(blitDepthStencil)

-        {

-            bool success = device->stretchRect(readFramebuffer->getDepthBuffer(), nullptr, drawFramebuffer->getDepthBuffer(), nullptr, false);

-

-            if(!success)

-            {

-                ERR("BlitFramebuffer failed.");

-                return;

-            }

-        }

-    }

-}

-

-void Context::bindTexImage(egl::Surface *surface)

-{

-	es2::Texture2D *textureObject = getTexture2D();

-

-    if(textureObject)

-    {

-		textureObject->bindTexImage(surface);

-	}

-}

-

-EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)

-{

-    GLenum textureTarget = GL_NONE;

-

-    switch(target)

-    {

-    case EGL_GL_TEXTURE_2D_KHR:

-        textureTarget = GL_TEXTURE_2D;

-        break;

-    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:

-    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:

-    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:

-    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:

-    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:

-    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:

-        textureTarget = GL_TEXTURE_CUBE_MAP;

-        break;

-    case EGL_GL_RENDERBUFFER_KHR:

-        break;

-    default:

-        return EGL_BAD_PARAMETER;

-    }

-

-    if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-    {

-        return EGL_BAD_MATCH;

-    }

-

-    if(textureTarget != GL_NONE)

-    {

-        es2::Texture *texture = getTexture(name);

-

-        if(!texture || texture->getTarget() != textureTarget)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling

-        {

-            return EGL_BAD_ACCESS;

-        }

-

-        if(textureLevel != 0 && !texture->isSamplerComplete())

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))

-        {

-            return EGL_BAD_PARAMETER;

-        }

-    }

-    else if(target == EGL_GL_RENDERBUFFER_KHR)

-    {

-        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);

-

-        if(!renderbuffer)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(renderbuffer->isShared())   // Already an EGLImage sibling

-        {

-            return EGL_BAD_ACCESS;

-        }

-    }

-    else UNREACHABLE(target);

-

-	return EGL_SUCCESS;

-}

-

-egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)

-{

-	GLenum textureTarget = GL_NONE;

-

-    switch(target)

-    {

-    case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;

-    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;

-    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;

-    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;

-    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;

-    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;

-    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;

-    }

-

-    if(textureTarget != GL_NONE)

-    {

-        es2::Texture *texture = getTexture(name);

-

-        return texture->createSharedImage(textureTarget, textureLevel);

-    }

-    else if(target == EGL_GL_RENDERBUFFER_KHR)

-    {

-        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);

-

-        return renderbuffer->createSharedImage();

-    }

-    else UNREACHABLE(target);

-

-	return 0;

-}

-

-Device *Context::getDevice()

-{

-	return device;

-}

-

-const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const

-{

-	// Keep list sorted in following order:

-	// OES extensions

-	// EXT extensions

-	// Vendor extensions

-	static const GLubyte* extensions[] = {

-		(const GLubyte*)"GL_OES_compressed_ETC1_RGB8_texture",

-		(const GLubyte*)"GL_OES_depth24",

-		(const GLubyte*)"GL_OES_depth32",

-		(const GLubyte*)"GL_OES_depth_texture",

-		(const GLubyte*)"GL_OES_depth_texture_cube_map",

-		(const GLubyte*)"GL_OES_EGL_image",

-		(const GLubyte*)"GL_OES_EGL_image_external",

-		(const GLubyte*)"GL_OES_EGL_sync",

-		(const GLubyte*)"GL_OES_element_index_uint",

-		(const GLubyte*)"GL_OES_framebuffer_object",

-		(const GLubyte*)"GL_OES_packed_depth_stencil",

-		(const GLubyte*)"GL_OES_rgb8_rgba8",

-		(const GLubyte*)"GL_OES_standard_derivatives",

-		(const GLubyte*)"GL_OES_texture_float",

-		(const GLubyte*)"GL_OES_texture_float_linear",

-		(const GLubyte*)"GL_OES_texture_half_float",

-		(const GLubyte*)"GL_OES_texture_half_float_linear",

-		(const GLubyte*)"GL_OES_texture_npot",

-		(const GLubyte*)"GL_OES_texture_3D",

-		(const GLubyte*)"GL_EXT_blend_minmax",

-		(const GLubyte*)"GL_EXT_color_buffer_half_float",

-		(const GLubyte*)"GL_EXT_draw_buffers",

-		(const GLubyte*)"GL_EXT_occlusion_query_boolean",

-		(const GLubyte*)"GL_EXT_read_format_bgra",

-#if (S3TC_SUPPORT)

-		(const GLubyte*)"GL_EXT_texture_compression_dxt1",

-#endif

-		(const GLubyte*)"GL_EXT_texture_filter_anisotropic",

-		(const GLubyte*)"GL_EXT_texture_format_BGRA8888",

-		(const GLubyte*)"GL_ANGLE_framebuffer_blit",

-		(const GLubyte*)"GL_NV_framebuffer_blit",

-		(const GLubyte*)"GL_ANGLE_framebuffer_multisample",

-#if (S3TC_SUPPORT)

-		(const GLubyte*)"GL_ANGLE_texture_compression_dxt3",

-		(const GLubyte*)"GL_ANGLE_texture_compression_dxt5",

-#endif

-		(const GLubyte*)"GL_NV_fence",

-		(const GLubyte*)"GL_NV_read_depth",

-		(const GLubyte*)"GL_EXT_instanced_arrays",

-		(const GLubyte*)"GL_ANGLE_instanced_arrays",

-	};

-	static const GLuint numExtensions = sizeof(extensions) / sizeof(*extensions);

-

-	if(numExt)

-	{

-		*numExt = numExtensions;

-		return nullptr;

-	}

-

-	if(index == GL_INVALID_INDEX)

-	{

-		static GLubyte* extensionsCat = nullptr;

-		if(!extensionsCat && (numExtensions > 0))

-		{

-			size_t totalLength = numExtensions; // 1 space between each extension name + terminating null

-			for(unsigned int i = 0; i < numExtensions; i++)

-			{

-				totalLength += strlen(reinterpret_cast<const char*>(extensions[i]));

-			}

-			extensionsCat = new GLubyte[totalLength];

-			extensionsCat[0] = '\0';

-			for(unsigned int i = 0; i < numExtensions; i++)

-			{

-				if(i != 0)

-				{

-					strcat(reinterpret_cast<char*>(extensionsCat), " ");

-				}

-				strcat(reinterpret_cast<char*>(extensionsCat), reinterpret_cast<const char*>(extensions[i]));

-			}

-		}

-		return extensionsCat;

-	}

-

-	if(index >= numExtensions)

-	{

-		return nullptr;

-	}

-

-	return extensions[index];

-}

-

-}

-

-egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion)

-{

-	ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion);   // Should be checked by eglCreateContext

-	return new es2::Context(config, static_cast<const es2::Context*>(shareContext), clientVersion);

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Context.cpp: Implements the es2::Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#include "Context.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "ResourceManager.h"
+#include "Buffer.h"
+#include "Fence.h"
+#include "Framebuffer.h"
+#include "Program.h"
+#include "Query.h"
+#include "Renderbuffer.h"
+#include "Sampler.h"
+#include "Shader.h"
+#include "Texture.h"
+#include "TransformFeedback.h"
+#include "VertexArray.h"
+#include "VertexDataManager.h"
+#include "IndexDataManager.h"
+#include "libEGL/Display.h"
+#include "libEGL/Surface.h"
+#include "Common/Half.hpp"
+
+#include <EGL/eglext.h>
+
+namespace es2
+{
+Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion)
+	: clientVersion(clientVersion), mConfig(config)
+{
+	sw::Context *context = new sw::Context();
+	device = new es2::Device(context);
+
+	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+	mState.depthClearValue = 1.0f;
+	mState.stencilClearValue = 0;
+
+	mState.cullFaceEnabled = false;
+	mState.cullMode = GL_BACK;
+	mState.frontFace = GL_CCW;
+	mState.depthTestEnabled = false;
+	mState.depthFunc = GL_LESS;
+	mState.blendEnabled = false;
+	mState.sourceBlendRGB = GL_ONE;
+	mState.sourceBlendAlpha = GL_ONE;
+	mState.destBlendRGB = GL_ZERO;
+	mState.destBlendAlpha = GL_ZERO;
+	mState.blendEquationRGB = GL_FUNC_ADD;
+	mState.blendEquationAlpha = GL_FUNC_ADD;
+	mState.blendColor.red = 0;
+	mState.blendColor.green = 0;
+	mState.blendColor.blue = 0;
+	mState.blendColor.alpha = 0;
+	mState.stencilTestEnabled = false;
+	mState.stencilFunc = GL_ALWAYS;
+	mState.stencilRef = 0;
+	mState.stencilMask = -1;
+	mState.stencilWritemask = -1;
+	mState.stencilBackFunc = GL_ALWAYS;
+	mState.stencilBackRef = 0;
+	mState.stencilBackMask = - 1;
+	mState.stencilBackWritemask = -1;
+	mState.stencilFail = GL_KEEP;
+	mState.stencilPassDepthFail = GL_KEEP;
+	mState.stencilPassDepthPass = GL_KEEP;
+	mState.stencilBackFail = GL_KEEP;
+	mState.stencilBackPassDepthFail = GL_KEEP;
+	mState.stencilBackPassDepthPass = GL_KEEP;
+	mState.polygonOffsetFillEnabled = false;
+	mState.polygonOffsetFactor = 0.0f;
+	mState.polygonOffsetUnits = 0.0f;
+	mState.sampleAlphaToCoverageEnabled = false;
+	mState.sampleCoverageEnabled = false;
+	mState.sampleCoverageValue = 1.0f;
+	mState.sampleCoverageInvert = false;
+	mState.scissorTestEnabled = false;
+	mState.ditherEnabled = true;
+	mState.primitiveRestartFixedIndexEnabled = false;
+	mState.rasterizerDiscardEnabled = false;
+	mState.generateMipmapHint = GL_DONT_CARE;
+	mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
+
+	mState.lineWidth = 1.0f;
+
+	mState.viewportX = 0;
+	mState.viewportY = 0;
+	mState.viewportWidth = 0;
+	mState.viewportHeight = 0;
+	mState.zNear = 0.0f;
+	mState.zFar = 1.0f;
+
+	mState.scissorX = 0;
+	mState.scissorY = 0;
+	mState.scissorWidth = 0;
+	mState.scissorHeight = 0;
+
+	mState.colorMaskRed = true;
+	mState.colorMaskGreen = true;
+	mState.colorMaskBlue = true;
+	mState.colorMaskAlpha = true;
+	mState.depthMask = true;
+
+	if(shareContext)
+	{
+		mResourceManager = shareContext->mResourceManager;
+		mResourceManager->addRef();
+	}
+	else
+	{
+		mResourceManager = new ResourceManager();
+	}
+
+	// [OpenGL ES 2.0.24] section 3.7 page 83:
+	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
+	// and cube map texture state vectors respectively associated with them.
+	// In order that access to these initial textures not be lost, they are treated as texture
+	// objects all of whose names are 0.
+
+	mTexture2DZero = new Texture2D(0);
+	mTexture3DZero = new Texture3D(0);
+	mTexture2DArrayZero = new Texture2DArray(0);
+	mTextureCubeMapZero = new TextureCubeMap(0);
+	mTextureExternalZero = new TextureExternal(0);
+
+	mState.activeSampler = 0;
+	bindVertexArray(0);
+	bindArrayBuffer(0);
+	bindElementArrayBuffer(0);
+	bindTextureCubeMap(0);
+	bindTexture2D(0);
+	bindReadFramebuffer(0);
+	bindDrawFramebuffer(0);
+	bindRenderbuffer(0);
+	bindGenericUniformBuffer(0);
+	bindTransformFeedback(0);
+
+	mState.currentProgram = 0;
+
+	mState.packAlignment = 4;
+	mState.unpackInfo.alignment = 4;
+	mState.packRowLength = 0;
+	mState.packImageHeight = 0;
+	mState.packSkipPixels = 0;
+	mState.packSkipRows = 0;
+	mState.packSkipImages = 0;
+	mState.unpackInfo.rowLength = 0;
+	mState.unpackInfo.imageHeight = 0;
+	mState.unpackInfo.skipPixels = 0;
+	mState.unpackInfo.skipRows = 0;
+	mState.unpackInfo.skipImages = 0;
+
+	mVertexDataManager = nullptr;
+	mIndexDataManager = nullptr;
+
+	mInvalidEnum = false;
+	mInvalidValue = false;
+	mInvalidOperation = false;
+	mOutOfMemory = false;
+	mInvalidFramebufferOperation = false;
+
+	mHasBeenCurrent = false;
+
+	markAllStateDirty();
+}
+
+Context::~Context()
+{
+	if(mState.currentProgram != 0)
+	{
+		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
+		if(programObject)
+		{
+			programObject->release();
+		}
+		mState.currentProgram = 0;
+	}
+
+	while(!mFramebufferNameSpace.empty())
+	{
+		deleteFramebuffer(mFramebufferNameSpace.firstName());
+	}
+
+	while(!mFenceNameSpace.empty())
+	{
+		deleteFence(mFenceNameSpace.firstName());
+	}
+
+	while(!mQueryNameSpace.empty())
+	{
+		deleteQuery(mQueryNameSpace.firstName());
+	}
+
+	while(!mVertexArrayNameSpace.empty())
+	{
+		deleteVertexArray(mVertexArrayNameSpace.firstName());
+	}
+
+	while(!mTransformFeedbackNameSpace.empty())
+	{
+		deleteTransformFeedback(mTransformFeedbackNameSpace.firstName());
+	}
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+		{
+			mState.samplerTexture[type][sampler] = nullptr;
+		}
+	}
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mState.vertexAttribute[i].mBoundBuffer = nullptr;
+	}
+
+	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
+	{
+		mState.activeQuery[i] = nullptr;
+	}
+
+	mState.arrayBuffer = nullptr;
+	mState.copyReadBuffer = nullptr;
+	mState.copyWriteBuffer = nullptr;
+	mState.pixelPackBuffer = nullptr;
+	mState.pixelUnpackBuffer = nullptr;
+	mState.genericUniformBuffer = nullptr;
+	mState.renderbuffer = nullptr;
+
+	for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
+	{
+		mState.sampler[i] = nullptr;
+	}
+
+	mTexture2DZero = nullptr;
+	mTexture3DZero = nullptr;
+	mTexture2DArrayZero = nullptr;
+	mTextureCubeMapZero = nullptr;
+	mTextureExternalZero = nullptr;
+
+	delete mVertexDataManager;
+	delete mIndexDataManager;
+
+	mResourceManager->release();
+	delete device;
+}
+
+void Context::makeCurrent(egl::Surface *surface)
+{
+	if(!mHasBeenCurrent)
+	{
+		mVertexDataManager = new VertexDataManager(this);
+		mIndexDataManager = new IndexDataManager();
+
+		mState.viewportX = 0;
+		mState.viewportY = 0;
+		mState.viewportWidth = surface->getWidth();
+		mState.viewportHeight = surface->getHeight();
+
+		mState.scissorX = 0;
+		mState.scissorY = 0;
+		mState.scissorWidth = surface->getWidth();
+		mState.scissorHeight = surface->getHeight();
+
+		mHasBeenCurrent = true;
+	}
+
+	// Wrap the existing resources into GL objects and assign them to the '0' names
+	egl::Image *defaultRenderTarget = surface->getRenderTarget();
+	egl::Image *depthStencil = surface->getDepthStencil();
+
+	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
+	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
+	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
+
+	setFramebufferZero(framebufferZero);
+
+	if(defaultRenderTarget)
+	{
+		defaultRenderTarget->release();
+	}
+
+	if(depthStencil)
+	{
+		depthStencil->release();
+	}
+
+	markAllStateDirty();
+}
+
+EGLint Context::getClientVersion() const
+{
+	return clientVersion;
+}
+
+// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
+void Context::markAllStateDirty()
+{
+	mAppliedProgramSerial = 0;
+
+	mDepthStateDirty = true;
+	mMaskStateDirty = true;
+	mBlendStateDirty = true;
+	mStencilStateDirty = true;
+	mPolygonOffsetStateDirty = true;
+	mSampleStateDirty = true;
+	mDitherStateDirty = true;
+	mFrontFaceDirty = true;
+}
+
+void Context::setClearColor(float red, float green, float blue, float alpha)
+{
+	mState.colorClearValue.red = red;
+	mState.colorClearValue.green = green;
+	mState.colorClearValue.blue = blue;
+	mState.colorClearValue.alpha = alpha;
+}
+
+void Context::setClearDepth(float depth)
+{
+	mState.depthClearValue = depth;
+}
+
+void Context::setClearStencil(int stencil)
+{
+	mState.stencilClearValue = stencil;
+}
+
+void Context::setCullFaceEnabled(bool enabled)
+{
+	mState.cullFaceEnabled = enabled;
+}
+
+bool Context::isCullFaceEnabled() const
+{
+	return mState.cullFaceEnabled;
+}
+
+void Context::setCullMode(GLenum mode)
+{
+   mState.cullMode = mode;
+}
+
+void Context::setFrontFace(GLenum front)
+{
+	if(mState.frontFace != front)
+	{
+		mState.frontFace = front;
+		mFrontFaceDirty = true;
+	}
+}
+
+void Context::setDepthTestEnabled(bool enabled)
+{
+	if(mState.depthTestEnabled != enabled)
+	{
+		mState.depthTestEnabled = enabled;
+		mDepthStateDirty = true;
+	}
+}
+
+bool Context::isDepthTestEnabled() const
+{
+	return mState.depthTestEnabled;
+}
+
+void Context::setDepthFunc(GLenum depthFunc)
+{
+	if(mState.depthFunc != depthFunc)
+	{
+		mState.depthFunc = depthFunc;
+		mDepthStateDirty = true;
+	}
+}
+
+void Context::setDepthRange(float zNear, float zFar)
+{
+	mState.zNear = zNear;
+	mState.zFar = zFar;
+}
+
+void Context::setBlendEnabled(bool enabled)
+{
+	if(mState.blendEnabled != enabled)
+	{
+		mState.blendEnabled = enabled;
+		mBlendStateDirty = true;
+	}
+}
+
+bool Context::isBlendEnabled() const
+{
+	return mState.blendEnabled;
+}
+
+void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
+{
+	if(mState.sourceBlendRGB != sourceRGB ||
+	   mState.sourceBlendAlpha != sourceAlpha ||
+	   mState.destBlendRGB != destRGB ||
+	   mState.destBlendAlpha != destAlpha)
+	{
+		mState.sourceBlendRGB = sourceRGB;
+		mState.destBlendRGB = destRGB;
+		mState.sourceBlendAlpha = sourceAlpha;
+		mState.destBlendAlpha = destAlpha;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setBlendColor(float red, float green, float blue, float alpha)
+{
+	if(mState.blendColor.red != red ||
+	   mState.blendColor.green != green ||
+	   mState.blendColor.blue != blue ||
+	   mState.blendColor.alpha != alpha)
+	{
+		mState.blendColor.red = red;
+		mState.blendColor.green = green;
+		mState.blendColor.blue = blue;
+		mState.blendColor.alpha = alpha;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
+{
+	if(mState.blendEquationRGB != rgbEquation ||
+	   mState.blendEquationAlpha != alphaEquation)
+	{
+		mState.blendEquationRGB = rgbEquation;
+		mState.blendEquationAlpha = alphaEquation;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setStencilTestEnabled(bool enabled)
+{
+	if(mState.stencilTestEnabled != enabled)
+	{
+		mState.stencilTestEnabled = enabled;
+		mStencilStateDirty = true;
+	}
+}
+
+bool Context::isStencilTestEnabled() const
+{
+	return mState.stencilTestEnabled;
+}
+
+void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
+{
+	if(mState.stencilFunc != stencilFunc ||
+	   mState.stencilRef != stencilRef ||
+	   mState.stencilMask != stencilMask)
+	{
+		mState.stencilFunc = stencilFunc;
+		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
+		mState.stencilMask = stencilMask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
+{
+	if(mState.stencilBackFunc != stencilBackFunc ||
+	   mState.stencilBackRef != stencilBackRef ||
+	   mState.stencilBackMask != stencilBackMask)
+	{
+		mState.stencilBackFunc = stencilBackFunc;
+		mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
+		mState.stencilBackMask = stencilBackMask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilWritemask(GLuint stencilWritemask)
+{
+	if(mState.stencilWritemask != stencilWritemask)
+	{
+		mState.stencilWritemask = stencilWritemask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
+{
+	if(mState.stencilBackWritemask != stencilBackWritemask)
+	{
+		mState.stencilBackWritemask = stencilBackWritemask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
+{
+	if(mState.stencilFail != stencilFail ||
+	   mState.stencilPassDepthFail != stencilPassDepthFail ||
+	   mState.stencilPassDepthPass != stencilPassDepthPass)
+	{
+		mState.stencilFail = stencilFail;
+		mState.stencilPassDepthFail = stencilPassDepthFail;
+		mState.stencilPassDepthPass = stencilPassDepthPass;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
+{
+	if(mState.stencilBackFail != stencilBackFail ||
+	   mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
+	   mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
+	{
+		mState.stencilBackFail = stencilBackFail;
+		mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
+		mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setPolygonOffsetFillEnabled(bool enabled)
+{
+	if(mState.polygonOffsetFillEnabled != enabled)
+	{
+		mState.polygonOffsetFillEnabled = enabled;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+bool Context::isPolygonOffsetFillEnabled() const
+{
+	return mState.polygonOffsetFillEnabled;
+}
+
+void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
+{
+	if(mState.polygonOffsetFactor != factor ||
+	   mState.polygonOffsetUnits != units)
+	{
+		mState.polygonOffsetFactor = factor;
+		mState.polygonOffsetUnits = units;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+void Context::setSampleAlphaToCoverageEnabled(bool enabled)
+{
+	if(mState.sampleAlphaToCoverageEnabled != enabled)
+	{
+		mState.sampleAlphaToCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleAlphaToCoverageEnabled() const
+{
+	return mState.sampleAlphaToCoverageEnabled;
+}
+
+void Context::setSampleCoverageEnabled(bool enabled)
+{
+	if(mState.sampleCoverageEnabled != enabled)
+	{
+		mState.sampleCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleCoverageEnabled() const
+{
+	return mState.sampleCoverageEnabled;
+}
+
+void Context::setSampleCoverageParams(GLclampf value, bool invert)
+{
+	if(mState.sampleCoverageValue != value ||
+	   mState.sampleCoverageInvert != invert)
+	{
+		mState.sampleCoverageValue = value;
+		mState.sampleCoverageInvert = invert;
+		mSampleStateDirty = true;
+	}
+}
+
+void Context::setScissorTestEnabled(bool enabled)
+{
+	mState.scissorTestEnabled = enabled;
+}
+
+bool Context::isScissorTestEnabled() const
+{
+	return mState.scissorTestEnabled;
+}
+
+void Context::setDitherEnabled(bool enabled)
+{
+	if(mState.ditherEnabled != enabled)
+	{
+		mState.ditherEnabled = enabled;
+		mDitherStateDirty = true;
+	}
+}
+
+bool Context::isDitherEnabled() const
+{
+	return mState.ditherEnabled;
+}
+
+void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)
+{
+	UNIMPLEMENTED();
+	mState.primitiveRestartFixedIndexEnabled = enabled;
+}
+
+bool Context::isPrimitiveRestartFixedIndexEnabled() const
+{
+	return mState.primitiveRestartFixedIndexEnabled;
+}
+
+void Context::setRasterizerDiscardEnabled(bool enabled)
+{
+	mState.rasterizerDiscardEnabled = enabled;
+}
+
+bool Context::isRasterizerDiscardEnabled() const
+{
+	return mState.rasterizerDiscardEnabled;
+}
+
+void Context::setLineWidth(GLfloat width)
+{
+	mState.lineWidth = width;
+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
+}
+
+void Context::setGenerateMipmapHint(GLenum hint)
+{
+	mState.generateMipmapHint = hint;
+}
+
+void Context::setFragmentShaderDerivativeHint(GLenum hint)
+{
+	mState.fragmentShaderDerivativeHint = hint;
+	// TODO: Propagate the hint to shader translator so we can write
+	// ddx, ddx_coarse, or ddx_fine depending on the hint.
+	// Ignore for now. It is valid for implementations to ignore hint.
+}
+
+void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.viewportX = x;
+	mState.viewportY = y;
+	mState.viewportWidth = width;
+	mState.viewportHeight = height;
+}
+
+void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.scissorX = x;
+	mState.scissorY = y;
+	mState.scissorWidth = width;
+	mState.scissorHeight = height;
+}
+
+void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
+{
+	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
+	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
+	{
+		mState.colorMaskRed = red;
+		mState.colorMaskGreen = green;
+		mState.colorMaskBlue = blue;
+		mState.colorMaskAlpha = alpha;
+		mMaskStateDirty = true;
+	}
+}
+
+unsigned int Context::getColorMask() const
+{
+	return (mState.colorMaskRed ? 0x1 : 0) |
+	       (mState.colorMaskGreen ? 0x2 : 0) |
+	       (mState.colorMaskBlue ? 0x4 : 0) |
+	       (mState.colorMaskAlpha ? 0x8 : 0);
+}
+
+void Context::setDepthMask(bool mask)
+{
+	if(mState.depthMask != mask)
+	{
+		mState.depthMask = mask;
+		mMaskStateDirty = true;
+	}
+}
+
+void Context::setActiveSampler(unsigned int active)
+{
+	mState.activeSampler = active;
+}
+
+GLuint Context::getReadFramebufferName() const
+{
+	return mState.readFramebuffer;
+}
+
+GLuint Context::getDrawFramebufferName() const
+{
+	return mState.drawFramebuffer;
+}
+
+GLuint Context::getRenderbufferName() const
+{
+	return mState.renderbuffer.name();
+}
+
+void Context::setFramebufferReadBuffer(GLuint buf)
+{
+	getReadFramebuffer()->setReadBuffer(buf);
+}
+
+void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
+{
+	Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
+	{
+		drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
+	}
+}
+
+GLuint Context::getReadFramebufferColorIndex() const
+{
+	GLenum buf = getReadFramebuffer()->getReadBuffer();
+	switch(buf)
+	{
+	case GL_BACK:
+		return 0;
+	case GL_NONE:
+		return GL_INVALID_INDEX;
+	default:
+		return buf - GL_COLOR_ATTACHMENT0;
+}
+}
+
+GLuint Context::getArrayBufferName() const
+{
+	return mState.arrayBuffer.name();
+}
+
+GLuint Context::getElementArrayBufferName() const
+{
+	Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();
+	return elementArrayBuffer ? elementArrayBuffer->name : 0;
+}
+
+GLuint Context::getActiveQuery(GLenum target) const
+{
+	Query *queryObject = nullptr;
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED_EXT:
+		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
+		break;
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
+		break;
+	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+		queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];
+		break;
+	default:
+		ASSERT(false);
+	}
+
+	if(queryObject)
+	{
+		return queryObject->name;
+	}
+
+	return 0;
+}
+
+void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
+{
+	getCurrentVertexArray()->enableAttribute(attribNum, enabled);
+}
+
+void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
+{
+	getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);
+}
+
+const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
+{
+	return getCurrentVertexArray()->getVertexAttribute(attribNum);
+}
+
+void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
+                                   GLsizei stride, const void *pointer)
+{
+	getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, stride, pointer);
+}
+
+const void *Context::getVertexAttribPointer(unsigned int attribNum) const
+{
+	return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
+}
+
+const VertexAttributeArray &Context::getVertexArrayAttributes()
+{
+	return getCurrentVertexArray()->getVertexAttributes();
+}
+
+const VertexAttributeArray &Context::getCurrentVertexAttributes()
+{
+	return mState.vertexAttribute;
+}
+
+void Context::setPackAlignment(GLint alignment)
+{
+	mState.packAlignment = alignment;
+}
+
+void Context::setUnpackAlignment(GLint alignment)
+{
+	mState.unpackInfo.alignment = alignment;
+}
+
+const egl::Image::UnpackInfo& Context::getUnpackInfo() const
+{
+	return mState.unpackInfo;
+}
+
+void Context::setPackRowLength(GLint rowLength)
+{
+	mState.packRowLength = rowLength;
+}
+
+void Context::setPackImageHeight(GLint imageHeight)
+{
+	mState.packImageHeight = imageHeight;
+}
+
+void Context::setPackSkipPixels(GLint skipPixels)
+{
+	mState.packSkipPixels = skipPixels;
+}
+
+void Context::setPackSkipRows(GLint skipRows)
+{
+	mState.packSkipRows = skipRows;
+}
+
+void Context::setPackSkipImages(GLint skipImages)
+{
+	mState.packSkipImages = skipImages;
+}
+
+void Context::setUnpackRowLength(GLint rowLength)
+{
+	mState.unpackInfo.rowLength = rowLength;
+}
+
+void Context::setUnpackImageHeight(GLint imageHeight)
+{
+	mState.unpackInfo.imageHeight = imageHeight;
+}
+
+void Context::setUnpackSkipPixels(GLint skipPixels)
+{
+	mState.unpackInfo.skipPixels = skipPixels;
+}
+
+void Context::setUnpackSkipRows(GLint skipRows)
+{
+	mState.unpackInfo.skipRows = skipRows;
+}
+
+void Context::setUnpackSkipImages(GLint skipImages)
+{
+	mState.unpackInfo.skipImages = skipImages;
+}
+
+GLuint Context::createBuffer()
+{
+	return mResourceManager->createBuffer();
+}
+
+GLuint Context::createProgram()
+{
+	return mResourceManager->createProgram();
+}
+
+GLuint Context::createShader(GLenum type)
+{
+	return mResourceManager->createShader(type);
+}
+
+GLuint Context::createTexture()
+{
+	return mResourceManager->createTexture();
+}
+
+GLuint Context::createRenderbuffer()
+{
+	return mResourceManager->createRenderbuffer();
+}
+
+// Returns an unused framebuffer name
+GLuint Context::createFramebuffer()
+{
+	return mFramebufferNameSpace.allocate();
+}
+
+GLuint Context::createFence()
+{
+	return mFenceNameSpace.allocate(new Fence());
+}
+
+// Returns an unused query name
+GLuint Context::createQuery()
+{
+	return mQueryNameSpace.allocate();
+}
+
+// Returns an unused vertex array name
+GLuint Context::createVertexArray()
+{
+	return mVertexArrayNameSpace.allocate();
+}
+
+GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
+{
+	GLuint handle = mResourceManager->createFenceSync(condition, flags);
+
+	return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
+}
+
+// Returns an unused transform feedback name
+GLuint Context::createTransformFeedback()
+{
+	return mTransformFeedbackNameSpace.allocate();
+}
+
+// Returns an unused sampler name
+GLuint Context::createSampler()
+{
+	return mResourceManager->createSampler();
+}
+
+void Context::deleteBuffer(GLuint buffer)
+{
+	detachBuffer(buffer);
+
+	mResourceManager->deleteBuffer(buffer);
+}
+
+void Context::deleteShader(GLuint shader)
+{
+	mResourceManager->deleteShader(shader);
+}
+
+void Context::deleteProgram(GLuint program)
+{
+	mResourceManager->deleteProgram(program);
+}
+
+void Context::deleteTexture(GLuint texture)
+{
+	detachTexture(texture);
+
+	mResourceManager->deleteTexture(texture);
+}
+
+void Context::deleteRenderbuffer(GLuint renderbuffer)
+{
+	if(mResourceManager->getRenderbuffer(renderbuffer))
+	{
+		detachRenderbuffer(renderbuffer);
+	}
+
+	mResourceManager->deleteRenderbuffer(renderbuffer);
+}
+
+void Context::deleteFramebuffer(GLuint framebuffer)
+{
+	detachFramebuffer(framebuffer);
+
+	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
+
+	if(framebufferObject)
+	{
+		delete framebufferObject;
+	}
+}
+
+void Context::deleteFence(GLuint fence)
+{
+	Fence *fenceObject = mFenceNameSpace.remove(fence);
+
+	if(fenceObject)
+	{
+		delete fenceObject;
+	}
+}
+
+void Context::deleteQuery(GLuint query)
+{
+	Query *queryObject = mQueryNameSpace.remove(query);
+
+	if(queryObject)
+	{
+		queryObject->release();
+	}
+}
+
+void Context::deleteVertexArray(GLuint vertexArray)
+{
+	// [OpenGL ES 3.0.2] section 2.10 page 43:
+	// If a vertex array object that is currently bound is deleted, the binding
+	// for that object reverts to zero and the default vertex array becomes current.
+	if(getCurrentVertexArray()->name == vertexArray)
+	{
+		bindVertexArray(0);
+	}
+
+	VertexArray *vertexArrayObject = mVertexArrayNameSpace.remove(vertexArray);
+
+	if(vertexArrayObject)
+	{
+		delete vertexArrayObject;
+	}
+}
+
+void Context::deleteFenceSync(GLsync fenceSync)
+{
+	// The spec specifies the underlying Fence object is not deleted until all current
+	// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
+	// and since our API is currently designed for being called from a single thread, we can delete
+	// the fence immediately.
+	mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
+}
+
+void Context::deleteTransformFeedback(GLuint transformFeedback)
+{
+	TransformFeedback *transformFeedbackObject = mTransformFeedbackNameSpace.remove(transformFeedback);
+
+	if(transformFeedbackObject)
+	{
+		delete transformFeedbackObject;
+	}
+}
+
+void Context::deleteSampler(GLuint sampler)
+{
+	detachSampler(sampler);
+
+	mResourceManager->deleteSampler(sampler);
+}
+
+Buffer *Context::getBuffer(GLuint handle) const
+{
+	return mResourceManager->getBuffer(handle);
+}
+
+Shader *Context::getShader(GLuint handle) const
+{
+	return mResourceManager->getShader(handle);
+}
+
+Program *Context::getProgram(GLuint handle) const
+{
+	return mResourceManager->getProgram(handle);
+}
+
+Texture *Context::getTexture(GLuint handle) const
+{
+	return mResourceManager->getTexture(handle);
+}
+
+Renderbuffer *Context::getRenderbuffer(GLuint handle) const
+{
+	return mResourceManager->getRenderbuffer(handle);
+}
+
+Framebuffer *Context::getReadFramebuffer() const
+{
+	return getFramebuffer(mState.readFramebuffer);
+}
+
+Framebuffer *Context::getDrawFramebuffer() const
+{
+	return getFramebuffer(mState.drawFramebuffer);
+}
+
+void Context::bindArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.arrayBuffer = getBuffer(buffer);
+}
+
+void Context::bindElementArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
+}
+
+void Context::bindCopyReadBuffer(GLuint buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.copyReadBuffer = getBuffer(buffer);
+}
+
+void Context::bindCopyWriteBuffer(GLuint buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.copyWriteBuffer = getBuffer(buffer);
+}
+
+void Context::bindPixelPackBuffer(GLuint buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.pixelPackBuffer = getBuffer(buffer);
+}
+
+void Context::bindPixelUnpackBuffer(GLuint buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.pixelUnpackBuffer = getBuffer(buffer);
+}
+
+void Context::bindTransformFeedbackBuffer(GLuint buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
+
+	if(transformFeedback)
+	{
+		transformFeedback->setGenericBuffer(getBuffer(buffer));
+	}
+}
+
+void Context::bindTexture2D(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+
+	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindTextureCubeMap(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
+
+	mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindTextureExternal(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
+
+	mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindTexture3D(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
+
+	mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindTexture2DArray(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
+
+	mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindReadFramebuffer(GLuint framebuffer)
+{
+	if(!getFramebuffer(framebuffer))
+	{
+		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
+	}
+
+	mState.readFramebuffer = framebuffer;
+}
+
+void Context::bindDrawFramebuffer(GLuint framebuffer)
+{
+	if(!getFramebuffer(framebuffer))
+	{
+		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
+	}
+
+	mState.drawFramebuffer = framebuffer;
+}
+
+void Context::bindRenderbuffer(GLuint renderbuffer)
+{
+	mResourceManager->checkRenderbufferAllocation(renderbuffer);
+
+	mState.renderbuffer = getRenderbuffer(renderbuffer);
+}
+
+void Context::bindVertexArray(GLuint array)
+{
+	VertexArray *vertexArray = getVertexArray(array);
+
+	if(!vertexArray)
+	{
+		vertexArray = new VertexArray(array);
+		mVertexArrayNameSpace.insert(array, vertexArray);
+	}
+
+	mState.vertexArray = array;
+}
+
+void Context::bindGenericUniformBuffer(GLuint buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.genericUniformBuffer = getBuffer(buffer);
+}
+
+void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	Buffer* bufferObject = getBuffer(buffer);
+	mState.uniformBuffers[index].set(bufferObject, offset, size);
+}
+
+void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	getTransformFeedback()->setGenericBuffer(getBuffer(buffer));
+}
+
+void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	Buffer* bufferObject = getBuffer(buffer);
+	getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
+}
+
+void Context::bindTransformFeedback(GLuint id)
+{
+	if(!getTransformFeedback(id))
+	{
+		mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));
+	}
+
+	mState.transformFeedback = id;
+}
+
+bool Context::bindSampler(GLuint unit, GLuint sampler)
+{
+	mResourceManager->checkSamplerAllocation(sampler);
+
+	Sampler* samplerObject = getSampler(sampler);
+
+	if(sampler)
+	{
+		mState.sampler[unit] = samplerObject;
+	}
+
+	return !!samplerObject;
+}
+
+void Context::useProgram(GLuint program)
+{
+	GLuint priorProgram = mState.currentProgram;
+	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
+
+	if(priorProgram != program)
+	{
+		Program *newProgram = mResourceManager->getProgram(program);
+		Program *oldProgram = mResourceManager->getProgram(priorProgram);
+
+		if(newProgram)
+		{
+			newProgram->addRef();
+		}
+
+		if(oldProgram)
+		{
+			oldProgram->release();
+		}
+	}
+}
+
+void Context::beginQuery(GLenum target, GLuint query)
+{
+	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
+	// of zero, if the active query object name for <target> is non-zero (for the
+	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
+	// the active query for either target is non-zero), if <id> is the name of an
+	// existing query object whose type does not match <target>, or if <id> is the
+	// active query object name for any query type, the error INVALID_OPERATION is
+	// generated.
+
+	// Ensure no other queries are active
+	// NOTE: If other queries than occlusion are supported, we will need to check
+	// separately that:
+	//    a) The query ID passed is not the current active query for any target/type
+	//    b) There are no active queries for the requested target (and in the case
+	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
+	//       no query may be active for either if glBeginQuery targets either.
+	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
+	{
+		if(mState.activeQuery[i])
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	QueryType qType;
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED_EXT:
+		qType = QUERY_ANY_SAMPLES_PASSED;
+		break;
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
+		break;
+	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+		qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
+		break;
+	default:
+		ASSERT(false);
+	}
+
+	Query *queryObject = createQuery(query, target);
+
+	// Check that name was obtained with glGenQueries
+	if(!queryObject)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	// Check for type mismatch
+	if(queryObject->getType() != target)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	// Set query as active for specified target
+	mState.activeQuery[qType] = queryObject;
+
+	// Begin query
+	queryObject->begin();
+}
+
+void Context::endQuery(GLenum target)
+{
+	QueryType qType;
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED_EXT:                qType = QUERY_ANY_SAMPLES_PASSED;                    break;
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;       break;
+	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
+	default: UNREACHABLE(target); return;
+	}
+
+	Query *queryObject = mState.activeQuery[qType];
+
+	if(!queryObject)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	queryObject->end();
+
+	mState.activeQuery[qType] = nullptr;
+}
+
+void Context::setFramebufferZero(Framebuffer *buffer)
+{
+	delete mFramebufferNameSpace.remove(0);
+	mFramebufferNameSpace.insert(0, buffer);
+}
+
+void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
+{
+	Renderbuffer *renderbufferObject = mState.renderbuffer;
+	renderbufferObject->setStorage(renderbuffer);
+}
+
+Framebuffer *Context::getFramebuffer(unsigned int handle) const
+{
+	return mFramebufferNameSpace.find(handle);
+}
+
+Fence *Context::getFence(unsigned int handle) const
+{
+	return mFenceNameSpace.find(handle);
+}
+
+FenceSync *Context::getFenceSync(GLsync handle) const
+{
+	return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
+}
+
+Query *Context::getQuery(unsigned int handle) const
+{
+	return mQueryNameSpace.find(handle);
+}
+
+Query *Context::createQuery(unsigned int handle, GLenum type)
+{
+	if(!mQueryNameSpace.isReserved(handle))
+	{
+		return nullptr;
+	}
+	else
+	{
+		Query *query = mQueryNameSpace.find(handle);
+		if(!query)
+		{
+			query = new Query(handle, type);
+			query->addRef();
+			mQueryNameSpace.insert(handle, query);
+		}
+
+		return query;
+	}
+}
+
+VertexArray *Context::getVertexArray(GLuint array) const
+{
+	return mVertexArrayNameSpace.find(array);
+}
+
+VertexArray *Context::getCurrentVertexArray() const
+{
+	return getVertexArray(mState.vertexArray);
+}
+
+bool Context::isVertexArray(GLuint array) const
+{
+	return mVertexArrayNameSpace.isReserved(array);
+}
+
+bool Context::hasZeroDivisor() const
+{
+	// Verify there is at least one active attribute with a divisor of zero
+	es2::Program *programObject = getCurrentProgram();
+	for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+	{
+		bool active = (programObject->getAttributeStream(attributeIndex) != -1);
+		if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
+{
+	return mTransformFeedbackNameSpace.find(transformFeedback);
+}
+
+Sampler *Context::getSampler(GLuint sampler) const
+{
+	return mResourceManager->getSampler(sampler);
+}
+
+bool Context::isSampler(GLuint sampler) const
+{
+	return mResourceManager->isSampler(sampler);
+}
+
+Buffer *Context::getArrayBuffer() const
+{
+	return mState.arrayBuffer;
+}
+
+Buffer *Context::getElementArrayBuffer() const
+{
+	return getCurrentVertexArray()->getElementArrayBuffer();
+}
+
+Buffer *Context::getCopyReadBuffer() const
+{
+	return mState.copyReadBuffer;
+}
+
+Buffer *Context::getCopyWriteBuffer() const
+{
+	return mState.copyWriteBuffer;
+}
+
+Buffer *Context::getPixelPackBuffer() const
+{
+	return mState.pixelPackBuffer;
+}
+
+Buffer *Context::getPixelUnpackBuffer() const
+{
+	return mState.pixelUnpackBuffer;
+}
+
+Buffer *Context::getGenericUniformBuffer() const
+{
+	return mState.genericUniformBuffer;
+}
+
+bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
+{
+	switch(target)
+	{
+	case GL_ARRAY_BUFFER:
+		*buffer = getArrayBuffer();
+		break;
+	case GL_ELEMENT_ARRAY_BUFFER:
+		*buffer = getElementArrayBuffer();
+		break;
+	case GL_COPY_READ_BUFFER:
+		if(clientVersion >= 3)
+		{
+			*buffer = getCopyReadBuffer();
+			break;
+		}
+		else return false;
+	case GL_COPY_WRITE_BUFFER:
+		if(clientVersion >= 3)
+		{
+			*buffer = getCopyWriteBuffer();
+			break;
+		}
+		else return false;
+	case GL_PIXEL_PACK_BUFFER:
+		if(clientVersion >= 3)
+		{
+			*buffer = getPixelPackBuffer();
+			break;
+		}
+		else return false;
+	case GL_PIXEL_UNPACK_BUFFER:
+		if(clientVersion >= 3)
+		{
+			*buffer = getPixelUnpackBuffer();
+			break;
+		}
+		else return false;
+	case GL_TRANSFORM_FEEDBACK_BUFFER:
+		if(clientVersion >= 3)
+		{
+			TransformFeedback* transformFeedback = getTransformFeedback();
+			*buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr;
+			break;
+		}
+		else return false;
+	case GL_UNIFORM_BUFFER:
+		if(clientVersion >= 3)
+		{
+			*buffer = getGenericUniformBuffer();
+			break;
+		}
+		else return false;
+	default:
+		return false;
+	}
+	return true;
+}
+
+TransformFeedback *Context::getTransformFeedback() const
+{
+	return getTransformFeedback(mState.transformFeedback);
+}
+
+Program *Context::getCurrentProgram() const
+{
+	return mResourceManager->getProgram(mState.currentProgram);
+}
+
+Texture2D *Context::getTexture2D() const
+{
+	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
+}
+
+Texture3D *Context::getTexture3D() const
+{
+	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
+}
+
+Texture2DArray *Context::getTexture2DArray() const
+{
+	return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
+}
+
+TextureCubeMap *Context::getTextureCubeMap() const
+{
+	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
+}
+
+TextureExternal *Context::getTextureExternal() const
+{
+	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
+}
+
+Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
+{
+	GLuint texid = mState.samplerTexture[type][sampler].name();
+
+	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
+	{
+		switch(type)
+		{
+		case TEXTURE_2D: return mTexture2DZero;
+		case TEXTURE_3D: return mTexture3DZero;
+		case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
+		case TEXTURE_CUBE: return mTextureCubeMapZero;
+		case TEXTURE_EXTERNAL: return mTextureExternalZero;
+		default: UNREACHABLE(type);
+		}
+	}
+
+	return mState.samplerTexture[type][sampler];
+}
+
+void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+	mResourceManager->checkSamplerAllocation(sampler);
+
+	Sampler *samplerObject = getSampler(sampler);
+	ASSERT(samplerObject);
+
+	switch(pname)
+	{
+	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;
+	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;
+	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;
+	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;
+	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;
+	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;
+	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;
+	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;
+	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;
+	default:                       UNREACHABLE(pname); break;
+	}
+}
+
+void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+	mResourceManager->checkSamplerAllocation(sampler);
+
+	Sampler *samplerObject = getSampler(sampler);
+	ASSERT(samplerObject);
+
+	switch(pname)
+	{
+	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(roundf(param)));       break;
+	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(roundf(param)));       break;
+	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(roundf(param)));           break;
+	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(roundf(param)));           break;
+	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(roundf(param)));           break;
+	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                                       break;
+	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                                       break;
+	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(roundf(param)));  break;
+	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(roundf(param)));  break;
+	default:                       UNREACHABLE(pname); break;
+	}
+}
+
+GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
+{
+	mResourceManager->checkSamplerAllocation(sampler);
+
+	Sampler *samplerObject = getSampler(sampler);
+	ASSERT(samplerObject);
+
+	switch(pname)
+	{
+	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());
+	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());
+	case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());
+	case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());
+	case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());
+	case GL_TEXTURE_MIN_LOD:       return static_cast<GLint>(roundf(samplerObject->getMinLod()));
+	case GL_TEXTURE_MAX_LOD:       return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
+	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());
+	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());
+	default:                       UNREACHABLE(pname); return 0;
+	}
+}
+
+GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
+{
+	mResourceManager->checkSamplerAllocation(sampler);
+
+	Sampler *samplerObject = getSampler(sampler);
+	ASSERT(samplerObject);
+
+	switch(pname)
+	{
+	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());
+	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());
+	case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());
+	case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());
+	case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());
+	case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();
+	case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();
+	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());
+	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());
+	default:                       UNREACHABLE(pname); return 0;
+	}
+}
+
+bool Context::getBooleanv(GLenum pname, GLboolean *params) const
+{
+	switch(pname)
+	{
+	case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;
+	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
+	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;
+	case GL_COLOR_WRITEMASK:
+		params[0] = mState.colorMaskRed;
+		params[1] = mState.colorMaskGreen;
+		params[2] = mState.colorMaskBlue;
+		params[3] = mState.colorMaskAlpha;
+		break;
+	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;                  break;
+	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;         break;
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled;     break;
+	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;            break;
+	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;               break;
+	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;               break;
+	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;                 break;
+	case GL_BLEND:                    *params = mState.blendEnabled;                     break;
+	case GL_DITHER:                   *params = mState.ditherEnabled;                    break;
+	case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
+	case GL_RASTERIZER_DISCARD:       *params = mState.rasterizerDiscardEnabled;         break;
+	case GL_TRANSFORM_FEEDBACK_ACTIVE:
+		{
+			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
+			if(transformFeedback)
+			{
+				*params = transformFeedback->isActive();
+				break;
+			}
+			else return false;
+		}
+	 case GL_TRANSFORM_FEEDBACK_PAUSED:
+		{
+			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
+			if(transformFeedback)
+			{
+				*params = transformFeedback->isPaused();
+				break;
+			}
+			else return false;
+		}
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getFloatv(GLenum pname, GLfloat *params) const
+{
+	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application.
+	switch(pname)
+	{
+	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
+	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
+	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
+	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
+	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
+		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
+		break;
+	case GL_ALIASED_POINT_SIZE_RANGE:
+		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
+		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
+		break;
+	case GL_DEPTH_RANGE:
+		params[0] = mState.zNear;
+		params[1] = mState.zFar;
+		break;
+	case GL_COLOR_CLEAR_VALUE:
+		params[0] = mState.colorClearValue.red;
+		params[1] = mState.colorClearValue.green;
+		params[2] = mState.colorClearValue.blue;
+		params[3] = mState.colorClearValue.alpha;
+		break;
+	case GL_BLEND_COLOR:
+		params[0] = mState.blendColor.red;
+		params[1] = mState.blendColor.green;
+		params[2] = mState.blendColor.blue;
+		params[3] = mState.blendColor.alpha;
+		break;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+		*params = MAX_TEXTURE_MAX_ANISOTROPY;
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
+template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
+
+template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
+{
+	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application. You may find it in
+	// Context::getFloatv.
+	switch(pname)
+	{
+	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
+	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
+	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
+	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
+	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
+	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
+	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
+	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
+	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
+	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
+	case GL_ARRAY_BUFFER_BINDING:             *params = getArrayBufferName();                 break;
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = getElementArrayBufferName();          break;
+//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+	case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
+	case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
+	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
+	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
+	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
+	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackInfo.alignment;          break;
+	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
+	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
+	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
+	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
+	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
+	case GL_STENCIL_VALUE_MASK:               *params = sw::clampToSignedInt(mState.stencilMask); break;
+	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
+	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
+	case GL_STENCIL_BACK_VALUE_MASK:          *params = sw::clampToSignedInt(mState.stencilBackMask); break;
+	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
+	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
+	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
+	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
+	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
+	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
+	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
+	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
+	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
+	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
+	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
+	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
+	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
+	case GL_STENCIL_WRITEMASK:                *params = sw::clampToSignedInt(mState.stencilWritemask); break;
+	case GL_STENCIL_BACK_WRITEMASK:           *params = sw::clampToSignedInt(mState.stencilBackWritemask); break;
+	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
+	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
+	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;          break;
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           break;
+	case GL_MAX_SAMPLES_ANGLE:                *params = IMPLEMENTATION_MAX_SAMPLES;               break;
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			int width, height, samples;
+
+			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
+			{
+				switch(pname)
+				{
+				case GL_SAMPLE_BUFFERS:
+					if(samples > 1)
+					{
+						*params = 1;
+					}
+					else
+					{
+						*params = 0;
+					}
+					break;
+				case GL_SAMPLES:
+					*params = samples;
+					break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+		{
+			Framebuffer *framebuffer = getReadFramebuffer();
+			*params = framebuffer->getImplementationColorReadType();
+		}
+		break;
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+		{
+			Framebuffer *framebuffer = getReadFramebuffer();
+			*params = framebuffer->getImplementationColorReadFormat();
+		}
+		break;
+	case GL_MAX_VIEWPORT_DIMS:
+		{
+			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
+			params[0] = maxDimension;
+			params[1] = maxDimension;
+		}
+		break;
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		{
+			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
+			{
+				params[i] = compressedTextureFormats[i];
+			}
+		}
+		break;
+	case GL_VIEWPORT:
+		params[0] = mState.viewportX;
+		params[1] = mState.viewportY;
+		params[2] = mState.viewportWidth;
+		params[3] = mState.viewportHeight;
+		break;
+	case GL_SCISSOR_BOX:
+		params[0] = mState.scissorX;
+		params[1] = mState.scissorY;
+		params[2] = mState.scissorWidth;
+		params[3] = mState.scissorHeight;
+		break;
+	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
+	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
+
+			if(colorbuffer)
+			{
+				switch(pname)
+				{
+				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
+				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
+				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
+				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_DEPTH_BITS:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+
+			if(depthbuffer)
+			{
+				*params = depthbuffer->getDepthSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_STENCIL_BITS:
+		{
+			Framebuffer *framebuffer = getDrawFramebuffer();
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+
+			if(stencilbuffer)
+			{
+				*params = stencilbuffer->getStencilSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_TEXTURE_BINDING_2D:
+		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+		{
+			error(GL_INVALID_OPERATION);
+			return false;
+		}
+
+		*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
+		break;
+	case GL_TEXTURE_BINDING_CUBE_MAP:
+		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+		{
+			error(GL_INVALID_OPERATION);
+			return false;
+		}
+
+		*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
+		break;
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:
+		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+		{
+			error(GL_INVALID_OPERATION);
+			return false;
+		}
+
+		*params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
+		break;
+	case GL_TEXTURE_BINDING_3D_OES:
+		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+		{
+			error(GL_INVALID_OPERATION);
+			return false;
+		}
+
+		*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
+		break;
+	case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0
+		if(clientVersion < 3)
+		{
+			return false;
+		}
+		else if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+		{
+			error(GL_INVALID_OPERATION);
+			return false;
+		}
+
+		*params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();
+		break;
+	case GL_COPY_READ_BUFFER_BINDING: // name, initially 0
+		if(clientVersion >= 3)
+		{
+			*params = mState.copyReadBuffer.name();
+		}
+		else
+		{
+			return false;
+		}
+		break;
+	case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0
+		if(clientVersion >= 3)
+		{
+			*params = mState.copyWriteBuffer.name();
+		}
+		else
+		{
+			return false;
+		}
+		break;
+	case GL_DRAW_BUFFER0:
+	case GL_DRAW_BUFFER1:
+	case GL_DRAW_BUFFER2:
+	case GL_DRAW_BUFFER3:
+	case GL_DRAW_BUFFER4:
+	case GL_DRAW_BUFFER5:
+	case GL_DRAW_BUFFER6:
+	case GL_DRAW_BUFFER7:
+	case GL_DRAW_BUFFER8:
+	case GL_DRAW_BUFFER9:
+	case GL_DRAW_BUFFER10:
+	case GL_DRAW_BUFFER11:
+	case GL_DRAW_BUFFER12:
+	case GL_DRAW_BUFFER13:
+	case GL_DRAW_BUFFER14:
+	case GL_DRAW_BUFFER15:
+		*params = getDrawFramebuffer()->getDrawBuffer(pname - GL_DRAW_BUFFER0);
+		break;
+	case GL_MAJOR_VERSION:
+		if(clientVersion >= 3)
+		{
+			*params = clientVersion;
+		}
+		else
+		{
+			return false;
+		}
+		break;
+	case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048
+		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
+		break;
+	case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048
+		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
+		break;
+	case GL_MAX_COLOR_ATTACHMENTS:
+		*params = MAX_COLOR_ATTACHMENTS;
+		break;
+	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048
+		*params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
+		break;
+	case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70
+		UNIMPLEMENTED();
+		*params = 70;
+		break;
+	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176
+		*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
+		break;
+	case GL_MAX_DRAW_BUFFERS:
+		*params = MAX_DRAW_BUFFERS;
+		break;
+	case GL_MAX_ELEMENT_INDEX:
+		*params = MAX_ELEMENT_INDEX;
+		break;
+	case GL_MAX_ELEMENTS_INDICES:
+		*params = MAX_ELEMENTS_INDICES;
+		break;
+	case GL_MAX_ELEMENTS_VERTICES:
+		*params = MAX_ELEMENTS_VERTICES;
+		break;
+	case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128
+		UNIMPLEMENTED();
+		*params = 128;
+		break;
+	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12
+		*params = MAX_FRAGMENT_UNIFORM_BLOCKS;
+		break;
+	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 896
+		*params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
+		break;
+	case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7
+		UNIMPLEMENTED();
+		*params = 7;
+		break;
+	case GL_MAX_SERVER_WAIT_TIMEOUT: // integer
+		UNIMPLEMENTED();
+		*params = 0;
+		break;
+	case GL_MAX_TEXTURE_LOD_BIAS: // integer,  at least 2.0
+		UNIMPLEMENTED();
+		*params = 2;
+		break;
+	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64
+		UNIMPLEMENTED();
+		*params = 64;
+		break;
+	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4
+		UNIMPLEMENTED();
+		*params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
+		break;
+	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4
+		UNIMPLEMENTED();
+		*params = 4;
+		break;
+	case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384
+		*params = MAX_UNIFORM_BLOCK_SIZE;
+		break;
+	case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 24
+		*params = MAX_UNIFORM_BUFFER_BINDINGS;
+		break;
+	case GL_MAX_VARYING_COMPONENTS: // integer, at least 60
+		UNIMPLEMENTED();
+		*params = 60;
+		break;
+	case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer,  at least 64
+		UNIMPLEMENTED();
+		*params = 64;
+		break;
+	case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer,  at least 12
+		*params = MAX_VERTEX_UNIFORM_BLOCKS;
+		break;
+	case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer,  at least 1024
+		*params = MAX_VERTEX_UNIFORM_COMPONENTS;
+		break;
+	case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8
+		UNIMPLEMENTED();
+		*params = -8;
+		break;
+	case GL_MINOR_VERSION: // integer
+		UNIMPLEMENTED();
+		*params = 0;
+		break;
+	case GL_NUM_EXTENSIONS: // integer
+		GLuint numExtensions;
+		getExtensions(0, &numExtensions);
+		*params = numExtensions;
+		break;
+	case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0
+		UNIMPLEMENTED();
+		*params = 0;
+		break;
+	case GL_PACK_ROW_LENGTH: // integer, initially 0
+		*params = mState.packRowLength;
+		break;
+	case GL_PACK_SKIP_PIXELS: // integer, initially 0
+		*params = mState.packSkipPixels;
+		break;
+	case GL_PACK_SKIP_ROWS: // integer, initially 0
+		*params = mState.packSkipRows;
+		break;
+	case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0
+		if(clientVersion >= 3)
+		{
+			*params = mState.pixelPackBuffer.name();
+		}
+		else
+		{
+			return false;
+		}
+		break;
+	case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0
+		if(clientVersion >= 3)
+		{
+			*params = mState.pixelUnpackBuffer.name();
+		}
+		else
+		{
+			return false;
+		}
+		break;
+	case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS​]
+		UNIMPLEMENTED();
+		*params = 0;
+		break;
+	case GL_READ_BUFFER: // symbolic constant,  initial value is GL_BACK​
+		*params = getReadFramebuffer()->getReadBuffer();
+		break;
+	case GL_SAMPLER_BINDING: // GLint, default 0
+		*params = mState.sampler[mState.activeSampler].name();
+		break;
+	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
+		if(clientVersion >= 3)
+		{
+			*params = mState.genericUniformBuffer.name();
+		}
+		else
+		{
+			return false;
+		}
+		break;
+	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1
+		*params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;
+		break;
+	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
+		if(clientVersion >= 3)
+		{
+			*params = mState.genericUniformBuffer->size();
+		}
+		else
+		{
+			return false;
+		}
+		break;
+	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
+		if(clientVersion >= 3)
+		{
+			*params = mState.genericUniformBuffer->offset();
+		}
+		else
+		{
+			return false;
+		}
+		*params = 0;
+		break;
+	case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0
+		*params = mState.unpackInfo.imageHeight;
+		break;
+	case GL_UNPACK_ROW_LENGTH: // integer, initially 0
+		*params = mState.unpackInfo.rowLength;
+		break;
+	case GL_UNPACK_SKIP_IMAGES: // integer, initially 0
+		*params = mState.unpackInfo.skipImages;
+		break;
+	case GL_UNPACK_SKIP_PIXELS: // integer, initially 0
+		*params = mState.unpackInfo.skipPixels;
+		break;
+	case GL_UNPACK_SKIP_ROWS: // integer, initially 0
+		*params = mState.unpackInfo.skipRows;
+		break;
+	case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0
+		*params = getCurrentVertexArray()->name;
+		break;
+	case GL_TRANSFORM_FEEDBACK_BINDING:
+		{
+			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
+			if(transformFeedback)
+			{
+				*params = transformFeedback->name;
+			}
+			else
+			{
+				return false;
+			}
+		}
+		break;
+	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+		{
+			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
+			if(transformFeedback)
+			{
+				*params = transformFeedback->getGenericBufferName();
+			}
+			else
+			{
+				return false;
+			}
+		}
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
+template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
+
+template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
+{
+	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
+	if(!transformFeedback)
+	{
+		return false;
+	}
+
+	switch(pname)
+	{
+	case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
+		*param = transformFeedback->name;
+		break;
+	case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
+		*param = transformFeedback->isActive();
+		break;
+	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
+		*param = transformFeedback->getBufferName(index);
+		break;
+	case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
+		*param = transformFeedback->isPaused();
+		break;
+	case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
+		if(transformFeedback->getBuffer(index))
+		{
+			*param = transformFeedback->getSize(index);
+			break;
+		}
+		else return false;
+	case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
+		if(transformFeedback->getBuffer(index))
+		{
+			*param = transformFeedback->getOffset(index);
+		break;
+		}
+		else return false;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
+template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
+
+template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
+{
+	const BufferBinding& uniformBuffer = mState.uniformBuffers[index];
+
+	switch(pname)
+	{
+	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
+		*param = uniformBuffer.get().name();
+		break;
+	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
+		*param = uniformBuffer.getSize();
+		break;
+	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
+		*param = uniformBuffer.getOffset();
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		{
+			*type = GL_INT;
+			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
+		}
+		break;
+	case GL_SHADER_BINARY_FORMATS:
+		{
+			*type = GL_INT;
+			*numParams = 0;
+		}
+		break;
+	case GL_MAX_VERTEX_ATTRIBS:
+	case GL_MAX_VERTEX_UNIFORM_VECTORS:
+	case GL_MAX_VARYING_VECTORS:
+	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+	case GL_MAX_TEXTURE_IMAGE_UNITS:
+	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+	case GL_MAX_RENDERBUFFER_SIZE:
+	case GL_NUM_SHADER_BINARY_FORMATS:
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+	case GL_ARRAY_BUFFER_BINDING:
+	case GL_FRAMEBUFFER_BINDING: // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+	case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
+	case GL_RENDERBUFFER_BINDING:
+	case GL_CURRENT_PROGRAM:
+	case GL_PACK_ALIGNMENT:
+	case GL_UNPACK_ALIGNMENT:
+	case GL_GENERATE_MIPMAP_HINT:
+	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+	case GL_DEPTH_BITS:
+	case GL_STENCIL_BITS:
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+	case GL_CULL_FACE_MODE:
+	case GL_FRONT_FACE:
+	case GL_ACTIVE_TEXTURE:
+	case GL_STENCIL_FUNC:
+	case GL_STENCIL_VALUE_MASK:
+	case GL_STENCIL_REF:
+	case GL_STENCIL_FAIL:
+	case GL_STENCIL_PASS_DEPTH_FAIL:
+	case GL_STENCIL_PASS_DEPTH_PASS:
+	case GL_STENCIL_BACK_FUNC:
+	case GL_STENCIL_BACK_VALUE_MASK:
+	case GL_STENCIL_BACK_REF:
+	case GL_STENCIL_BACK_FAIL:
+	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+	case GL_DEPTH_FUNC:
+	case GL_BLEND_SRC_RGB:
+	case GL_BLEND_SRC_ALPHA:
+	case GL_BLEND_DST_RGB:
+	case GL_BLEND_DST_ALPHA:
+	case GL_BLEND_EQUATION_RGB:
+	case GL_BLEND_EQUATION_ALPHA:
+	case GL_STENCIL_WRITEMASK:
+	case GL_STENCIL_BACK_WRITEMASK:
+	case GL_STENCIL_CLEAR_VALUE:
+	case GL_SUBPIXEL_BITS:
+	case GL_MAX_TEXTURE_SIZE:
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+	case GL_TEXTURE_BINDING_2D:
+	case GL_TEXTURE_BINDING_CUBE_MAP:
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:
+	case GL_TEXTURE_BINDING_3D_OES:
+	case GL_COPY_READ_BUFFER_BINDING:
+	case GL_COPY_WRITE_BUFFER_BINDING:
+	case GL_DRAW_BUFFER0:
+	case GL_DRAW_BUFFER1:
+	case GL_DRAW_BUFFER2:
+	case GL_DRAW_BUFFER3:
+	case GL_DRAW_BUFFER4:
+	case GL_DRAW_BUFFER5:
+	case GL_DRAW_BUFFER6:
+	case GL_DRAW_BUFFER7:
+	case GL_DRAW_BUFFER8:
+	case GL_DRAW_BUFFER9:
+	case GL_DRAW_BUFFER10:
+	case GL_DRAW_BUFFER11:
+	case GL_DRAW_BUFFER12:
+	case GL_DRAW_BUFFER13:
+	case GL_DRAW_BUFFER14:
+	case GL_DRAW_BUFFER15:
+	case GL_MAJOR_VERSION:
+	case GL_MAX_3D_TEXTURE_SIZE:
+	case GL_MAX_ARRAY_TEXTURE_LAYERS:
+	case GL_MAX_COLOR_ATTACHMENTS:
+	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+	case GL_MAX_COMBINED_UNIFORM_BLOCKS:
+	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+	case GL_MAX_DRAW_BUFFERS:
+	case GL_MAX_ELEMENT_INDEX:
+	case GL_MAX_ELEMENTS_INDICES:
+	case GL_MAX_ELEMENTS_VERTICES:
+	case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
+	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
+	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+	case GL_MAX_PROGRAM_TEXEL_OFFSET:
+	case GL_MAX_SERVER_WAIT_TIMEOUT:
+	case GL_MAX_TEXTURE_LOD_BIAS:
+	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+	case GL_MAX_UNIFORM_BLOCK_SIZE:
+	case GL_MAX_UNIFORM_BUFFER_BINDINGS:
+	case GL_MAX_VARYING_COMPONENTS:
+	case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
+	case GL_MAX_VERTEX_UNIFORM_BLOCKS:
+	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+	case GL_MIN_PROGRAM_TEXEL_OFFSET:
+	case GL_MINOR_VERSION:
+	case GL_NUM_EXTENSIONS:
+	case GL_NUM_PROGRAM_BINARY_FORMATS:
+	case GL_PACK_ROW_LENGTH:
+	case GL_PACK_SKIP_PIXELS:
+	case GL_PACK_SKIP_ROWS:
+	case GL_PIXEL_PACK_BUFFER_BINDING:
+	case GL_PIXEL_UNPACK_BUFFER_BINDING:
+	case GL_PROGRAM_BINARY_FORMATS:
+	case GL_READ_BUFFER:
+	case GL_SAMPLER_BINDING:
+	case GL_TEXTURE_BINDING_2D_ARRAY:
+	case GL_UNIFORM_BUFFER_BINDING:
+	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+	case GL_UNIFORM_BUFFER_SIZE:
+	case GL_UNIFORM_BUFFER_START:
+	case GL_UNPACK_IMAGE_HEIGHT:
+	case GL_UNPACK_ROW_LENGTH:
+	case GL_UNPACK_SKIP_IMAGES:
+	case GL_UNPACK_SKIP_PIXELS:
+	case GL_UNPACK_SKIP_ROWS:
+	case GL_VERTEX_ARRAY_BINDING:
+	case GL_TRANSFORM_FEEDBACK_BINDING:
+	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+		{
+			*type = GL_INT;
+			*numParams = 1;
+		}
+		break;
+	case GL_MAX_SAMPLES_ANGLE:
+		{
+			*type = GL_INT;
+			*numParams = 1;
+		}
+		break;
+	case GL_MAX_VIEWPORT_DIMS:
+		{
+			*type = GL_INT;
+			*numParams = 2;
+		}
+		break;
+	case GL_VIEWPORT:
+	case GL_SCISSOR_BOX:
+		{
+			*type = GL_INT;
+			*numParams = 4;
+		}
+		break;
+	case GL_SHADER_COMPILER:
+	case GL_SAMPLE_COVERAGE_INVERT:
+	case GL_DEPTH_WRITEMASK:
+	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
+	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
+	case GL_SAMPLE_COVERAGE:
+	case GL_SCISSOR_TEST:
+	case GL_STENCIL_TEST:
+	case GL_DEPTH_TEST:
+	case GL_BLEND:
+	case GL_DITHER:
+	case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+	case GL_RASTERIZER_DISCARD:
+	case GL_TRANSFORM_FEEDBACK_ACTIVE:
+	case GL_TRANSFORM_FEEDBACK_PAUSED:
+		{
+			*type = GL_BOOL;
+			*numParams = 1;
+		}
+		break;
+	case GL_COLOR_WRITEMASK:
+		{
+			*type = GL_BOOL;
+			*numParams = 4;
+		}
+		break;
+	case GL_POLYGON_OFFSET_FACTOR:
+	case GL_POLYGON_OFFSET_UNITS:
+	case GL_SAMPLE_COVERAGE_VALUE:
+	case GL_DEPTH_CLEAR_VALUE:
+	case GL_LINE_WIDTH:
+		{
+			*type = GL_FLOAT;
+			*numParams = 1;
+		}
+		break;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+	case GL_ALIASED_POINT_SIZE_RANGE:
+	case GL_DEPTH_RANGE:
+		{
+			*type = GL_FLOAT;
+			*numParams = 2;
+		}
+		break;
+	case GL_COLOR_CLEAR_VALUE:
+	case GL_BLEND_COLOR:
+		{
+			*type = GL_FLOAT;
+			*numParams = 4;
+		}
+		break;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+		*type = GL_FLOAT;
+		*numParams = 1;
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+void Context::applyScissor(int width, int height)
+{
+	if(mState.scissorTestEnabled)
+	{
+		sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
+		scissor.clip(0, 0, width, height);
+
+		device->setScissorRect(scissor);
+		device->setScissorEnable(true);
+	}
+	else
+	{
+		device->setScissorEnable(false);
+	}
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
+bool Context::applyRenderTarget()
+{
+	Framebuffer *framebuffer = getDrawFramebuffer();
+	int width, height, samples;
+
+	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+	}
+
+	for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
+	{
+		if(framebuffer->getDrawBuffer(i) != GL_NONE)
+		{
+			egl::Image *renderTarget = framebuffer->getRenderTarget(i);
+			device->setRenderTarget(i, renderTarget);
+			if(renderTarget) renderTarget->release();
+		}
+		else
+		{
+			device->setRenderTarget(i, nullptr);
+		}
+	}
+
+	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
+	device->setDepthBuffer(depthBuffer);
+	if(depthBuffer) depthBuffer->release();
+
+	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
+	device->setStencilBuffer(stencilBuffer);
+	if(stencilBuffer) stencilBuffer->release();
+
+	Viewport viewport;
+	float zNear = clamp01(mState.zNear);
+	float zFar = clamp01(mState.zFar);
+
+	viewport.x0 = mState.viewportX;
+	viewport.y0 = mState.viewportY;
+	viewport.width = mState.viewportWidth;
+	viewport.height = mState.viewportHeight;
+	viewport.minZ = zNear;
+	viewport.maxZ = zFar;
+
+	device->setViewport(viewport);
+
+	applyScissor(width, height);
+
+	Program *program = getCurrentProgram();
+
+	if(program)
+	{
+		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
+		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
+		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
+		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
+	}
+
+	return true;
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
+void Context::applyState(GLenum drawMode)
+{
+	Framebuffer *framebuffer = getDrawFramebuffer();
+
+	if(mState.cullFaceEnabled)
+	{
+		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
+	}
+	else
+	{
+		device->setCullMode(sw::CULL_NONE);
+	}
+
+	if(mDepthStateDirty)
+	{
+		if(mState.depthTestEnabled)
+		{
+			device->setDepthBufferEnable(true);
+			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
+		}
+		else
+		{
+			device->setDepthBufferEnable(false);
+		}
+
+		mDepthStateDirty = false;
+	}
+
+	if(mBlendStateDirty)
+	{
+		if(mState.blendEnabled)
+		{
+			device->setAlphaBlendEnable(true);
+			device->setSeparateAlphaBlendEnable(true);
+
+			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
+
+			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
+			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
+			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
+
+			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
+			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
+			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
+		}
+		else
+		{
+			device->setAlphaBlendEnable(false);
+		}
+
+		mBlendStateDirty = false;
+	}
+
+	if(mStencilStateDirty || mFrontFaceDirty)
+	{
+		if(mState.stencilTestEnabled && framebuffer->hasStencil())
+		{
+			device->setStencilEnable(true);
+			device->setTwoSidedStencil(true);
+
+			// get the maximum size of the stencil ref
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
+
+			if(mState.frontFace == GL_CCW)
+			{
+				device->setStencilWriteMask(mState.stencilWritemask);
+				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+				device->setStencilMask(mState.stencilMask);
+
+				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
+				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+
+				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
+				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
+
+				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
+				device->setStencilMaskCCW(mState.stencilBackMask);
+
+				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
+				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
+				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
+			}
+			else
+			{
+				device->setStencilWriteMaskCCW(mState.stencilWritemask);
+				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+				device->setStencilMaskCCW(mState.stencilMask);
+
+				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
+				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+
+				device->setStencilWriteMask(mState.stencilBackWritemask);
+				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
+
+				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
+				device->setStencilMask(mState.stencilBackMask);
+
+				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
+				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
+				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
+			}
+		}
+		else
+		{
+			device->setStencilEnable(false);
+		}
+
+		mStencilStateDirty = false;
+		mFrontFaceDirty = false;
+	}
+
+	if(mMaskStateDirty)
+	{
+		for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
+		{
+			device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
+		}
+
+		device->setDepthWriteEnable(mState.depthMask);
+
+		mMaskStateDirty = false;
+	}
+
+	if(mPolygonOffsetStateDirty)
+	{
+		if(mState.polygonOffsetFillEnabled)
+		{
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+			if(depthbuffer)
+			{
+				device->setSlopeDepthBias(mState.polygonOffsetFactor);
+				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
+				device->setDepthBias(depthBias);
+			}
+		}
+		else
+		{
+			device->setSlopeDepthBias(0);
+			device->setDepthBias(0);
+		}
+
+		mPolygonOffsetStateDirty = false;
+	}
+
+	if(mSampleStateDirty)
+	{
+		if(mState.sampleAlphaToCoverageEnabled)
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
+		}
+		else
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
+		}
+
+		if(mState.sampleCoverageEnabled)
+		{
+			unsigned int mask = 0;
+			if(mState.sampleCoverageValue != 0)
+			{
+				int width, height, samples;
+				framebuffer->completeness(width, height, samples);
+
+				float threshold = 0.5f;
+
+				for(int i = 0; i < samples; i++)
+				{
+					mask <<= 1;
+
+					if((i + 1) * mState.sampleCoverageValue >= threshold)
+					{
+						threshold += 1.0f;
+						mask |= 1;
+					}
+				}
+			}
+
+			if(mState.sampleCoverageInvert)
+			{
+				mask = ~mask;
+			}
+
+			device->setMultiSampleMask(mask);
+		}
+		else
+		{
+			device->setMultiSampleMask(0xFFFFFFFF);
+		}
+
+		mSampleStateDirty = false;
+	}
+
+	if(mDitherStateDirty)
+	{
+	//	UNIMPLEMENTED();   // FIXME
+
+		mDitherStateDirty = false;
+	}
+
+	device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);
+}
+
+GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
+{
+	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
+
+	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
+	if(err != GL_NO_ERROR)
+	{
+		return err;
+	}
+
+	Program *program = getCurrentProgram();
+
+	device->resetInputStreams(false);
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(program->getAttributeStream(i) == -1)
+		{
+			continue;
+		}
+
+		sw::Resource *resource = attributes[i].vertexBuffer;
+		const void *buffer = (char*)resource->data() + attributes[i].offset;
+
+		int stride = attributes[i].stride;
+
+		buffer = (char*)buffer + stride * base;
+
+		sw::Stream attribute(resource, buffer, stride);
+
+		attribute.type = attributes[i].type;
+		attribute.count = attributes[i].count;
+		attribute.normalized = attributes[i].normalized;
+
+		int stream = program->getAttributeStream(i);
+		device->setInputStream(stream, attribute);
+	}
+
+	return GL_NO_ERROR;
+}
+
+// Applies the indices and element array bindings
+GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+	GLenum err = mIndexDataManager->prepareIndexData(type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo);
+
+	if(err == GL_NO_ERROR)
+	{
+		device->setIndexBuffer(indexInfo->indexBuffer);
+	}
+
+	return err;
+}
+
+// Applies the shaders and shader constants
+void Context::applyShaders()
+{
+	Program *programObject = getCurrentProgram();
+	sw::VertexShader *vertexShader = programObject->getVertexShader();
+	sw::PixelShader *pixelShader = programObject->getPixelShader();
+
+	device->setVertexShader(vertexShader);
+	device->setPixelShader(pixelShader);
+
+	if(programObject->getSerial() != mAppliedProgramSerial)
+	{
+		programObject->dirtyAllUniforms();
+		mAppliedProgramSerial = programObject->getSerial();
+	}
+
+	programObject->applyUniformBuffers(mState.uniformBuffers);
+	programObject->applyUniforms();
+}
+
+void Context::applyTextures()
+{
+	applyTextures(sw::SAMPLER_PIXEL);
+	applyTextures(sw::SAMPLER_VERTEX);
+}
+
+void Context::applyTextures(sw::SamplerType samplerType)
+{
+	Program *programObject = getCurrentProgram();
+
+	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
+
+	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
+	{
+		int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
+
+		if(textureUnit != -1)
+		{
+			TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
+
+			Texture *texture = getSamplerTexture(textureUnit, textureType);
+
+			if(texture->isSamplerComplete())
+			{
+				GLenum wrapS, wrapT, wrapR, minFilter, magFilter;
+
+				Sampler *samplerObject = mState.sampler[textureUnit];
+				if(samplerObject)
+				{
+					wrapS = samplerObject->getWrapS();
+					wrapT = samplerObject->getWrapT();
+					wrapR = samplerObject->getWrapR();
+					minFilter = samplerObject->getMinFilter();
+					magFilter = samplerObject->getMagFilter();
+				}
+				else
+				{
+					wrapS = texture->getWrapS();
+					wrapT = texture->getWrapT();
+					wrapR = texture->getWrapR();
+					minFilter = texture->getMinFilter();
+					magFilter = texture->getMagFilter();
+				}
+				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
+
+				GLenum swizzleR = texture->getSwizzleR();
+				GLenum swizzleG = texture->getSwizzleG();
+				GLenum swizzleB = texture->getSwizzleB();
+				GLenum swizzleA = texture->getSwizzleA();
+
+				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
+				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
+				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
+				device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
+				device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
+				device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
+				device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
+
+				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
+				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
+				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
+
+				applyTexture(samplerType, samplerIndex, texture);
+			}
+			else
+			{
+				applyTexture(samplerType, samplerIndex, nullptr);
+			}
+		}
+		else
+		{
+			applyTexture(samplerType, samplerIndex, nullptr);
+		}
+	}
+}
+
+void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
+{
+	Program *program = getCurrentProgram();
+	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
+	bool textureUsed = false;
+
+	if(type == sw::SAMPLER_PIXEL)
+	{
+		textureUsed = program->getPixelShader()->usesSampler(index);
+	}
+	else if(type == sw::SAMPLER_VERTEX)
+	{
+		textureUsed = program->getVertexShader()->usesSampler(index);
+	}
+	else UNREACHABLE(type);
+
+	sw::Resource *resource = 0;
+
+	if(baseTexture && textureUsed)
+	{
+		resource = baseTexture->getResource();
+	}
+
+	device->setTextureResource(sampler, resource);
+
+	if(baseTexture && textureUsed)
+	{
+		int levelCount = baseTexture->getLevelCount();
+
+		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
+
+			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+			{
+				int surfaceLevel = mipmapLevel;
+
+				if(surfaceLevel < 0)
+				{
+					surfaceLevel = 0;
+				}
+				else if(surfaceLevel >= levelCount)
+				{
+					surfaceLevel = levelCount - 1;
+				}
+
+				egl::Image *surface = texture->getImage(surfaceLevel);
+				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
+			}
+		}
+		else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES)
+		{
+			Texture3D *texture = static_cast<Texture3D*>(baseTexture);
+
+			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+			{
+				int surfaceLevel = mipmapLevel;
+
+				if(surfaceLevel < 0)
+				{
+					surfaceLevel = 0;
+				}
+				else if(surfaceLevel >= levelCount)
+				{
+					surfaceLevel = levelCount - 1;
+				}
+
+				egl::Image *surface = texture->getImage(surfaceLevel);
+				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
+			}
+		}
+		else if(baseTexture->getTarget() == GL_TEXTURE_2D_ARRAY)
+		{
+			Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
+
+			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+			{
+				int surfaceLevel = mipmapLevel;
+
+				if(surfaceLevel < 0)
+				{
+					surfaceLevel = 0;
+				}
+				else if(surfaceLevel >= levelCount)
+				{
+					surfaceLevel = levelCount - 1;
+				}
+
+				egl::Image *surface = texture->getImage(surfaceLevel);
+				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
+			}
+		}
+		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
+		{
+			for(int face = 0; face < 6; face++)
+			{
+				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
+
+				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+				{
+					int surfaceLevel = mipmapLevel;
+
+					if(surfaceLevel < 0)
+					{
+						surfaceLevel = 0;
+					}
+					else if(surfaceLevel >= levelCount)
+					{
+						surfaceLevel = levelCount - 1;
+					}
+
+					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
+					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
+				}
+			}
+		}
+		else UNIMPLEMENTED();
+	}
+	else
+	{
+		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
+	}
+}
+
+void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+{
+	Framebuffer *framebuffer = getReadFramebuffer();
+	int framebufferWidth, framebufferHeight, framebufferSamples;
+
+	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+	}
+
+	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	GLenum readFormat = GL_NONE;
+	GLenum readType = GL_NONE;
+	switch(format)
+	{
+	case GL_DEPTH_COMPONENT:
+		readFormat = framebuffer->getDepthReadFormat();
+		readType = framebuffer->getDepthReadType();
+		break;
+	default:
+		readFormat = framebuffer->getImplementationColorReadFormat();
+		readType = framebuffer->getImplementationColorReadType();
+		break;
+	}
+
+	if(!(readFormat == format && readType == type) && !ValidReadPixelsFormatType(readFormat, readType, format, type, clientVersion))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	GLsizei outputWidth = (mState.packRowLength > 0) ? mState.packRowLength : width;
+	GLsizei outputPitch = egl::ComputePitch(outputWidth, format, type, mState.packAlignment);
+	GLsizei outputHeight = (mState.packImageHeight == 0) ? height : mState.packImageHeight;
+	pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
+	pixels = ((char*)pixels) + egl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packAlignment, mState.packSkipImages, mState.packSkipRows, mState.packSkipPixels);
+
+	// Sized query sanity check
+	if(bufSize)
+	{
+		int requiredSize = outputPitch * height;
+		if(requiredSize > *bufSize)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	egl::Image *renderTarget = nullptr;
+	switch(format)
+	{
+	case GL_DEPTH_COMPONENT:
+		renderTarget = framebuffer->getDepthBuffer();
+		break;
+	default:
+		renderTarget = framebuffer->getReadRenderTarget();
+		break;
+	}
+
+	if(!renderTarget)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	sw::Rect rect = {x, y, x + width, y + height};
+	sw::Rect dstRect = { 0, 0, width, height };
+	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+	sw::Surface externalSurface(width, height, 1, egl::ConvertFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
+	sw::SliceRect sliceRect(rect);
+	sw::SliceRect dstSliceRect(dstRect);
+	device->blit(renderTarget, sliceRect, &externalSurface, dstSliceRect, false);
+
+	renderTarget->release();
+}
+
+void Context::clear(GLbitfield mask)
+{
+	if(mState.rasterizerDiscardEnabled)
+	{
+		return;
+	}
+
+	Framebuffer *framebuffer = getDrawFramebuffer();
+
+	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	if(mask & GL_COLOR_BUFFER_BIT)
+	{
+		unsigned int rgbaMask = getColorMask();
+
+		if(rgbaMask != 0)
+		{
+			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
+		}
+	}
+
+	if(mask & GL_DEPTH_BUFFER_BIT)
+	{
+		if(mState.depthMask != 0)
+		{
+			float depth = clamp01(mState.depthClearValue);
+			device->clearDepth(depth);
+		}
+	}
+
+	if(mask & GL_STENCIL_BUFFER_BIT)
+	{
+		if(mState.stencilWritemask != 0)
+		{
+			int stencil = mState.stencilClearValue & 0x000000FF;
+			device->clearStencil(stencil, mState.stencilWritemask);
+		}
+	}
+}
+
+void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
+{
+	unsigned int rgbaMask = getColorMask();
+	if(rgbaMask && !mState.rasterizerDiscardEnabled)
+	{
+		Framebuffer *framebuffer = getDrawFramebuffer();
+		egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
+
+		if(colorbuffer)
+		{
+			sw::SliceRect clearRect = colorbuffer->getRect();
+
+			if(mState.scissorTestEnabled)
+			{
+				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
+			}
+
+			device->clear(value, format, colorbuffer, clearRect, rgbaMask);
+
+			colorbuffer->release();
+		}
+	}
+}
+
+void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
+{
+	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
+}
+
+void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
+{
+	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
+}
+
+void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
+{
+	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
+}
+
+void Context::clearDepthBuffer(const GLfloat value)
+{
+	if(mState.depthMask && !mState.rasterizerDiscardEnabled)
+	{
+		Framebuffer *framebuffer = getDrawFramebuffer();
+		egl::Image *depthbuffer = framebuffer->getDepthBuffer();
+
+		if(depthbuffer)
+		{
+			float depth = clamp01(value);
+			sw::SliceRect clearRect = depthbuffer->getRect();
+
+			if(mState.scissorTestEnabled)
+			{
+				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
+			}
+
+			depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+
+			depthbuffer->release();
+		}
+	}
+}
+
+void Context::clearStencilBuffer(const GLint value)
+{
+	if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
+	{
+		Framebuffer *framebuffer = getDrawFramebuffer();
+		egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
+
+		if(stencilbuffer)
+		{
+			unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);
+			sw::SliceRect clearRect = stencilbuffer->getRect();
+
+			if(mState.scissorTestEnabled)
+			{
+				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
+			}
+
+			stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+
+			stencilbuffer->release();
+		}
+	}
+}
+
+void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+	if(!mState.currentProgram)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	sw::DrawType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	for(int i = 0; i < instanceCount; ++i)
+	{
+		device->setInstanceID(i);
+
+		GLenum err = applyVertexBuffer(0, first, count, i);
+		if(err != GL_NO_ERROR)
+		{
+			return error(err);
+		}
+
+		applyShaders();
+		applyTextures();
+
+		if(!getCurrentProgram()->validateSamplers(false))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!cullSkipsDraw(mode))
+		{
+			device->drawPrimitive(primitiveType, primitiveCount);
+		}
+	}
+}
+
+void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+	if(!mState.currentProgram)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	sw::DrawType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	for(int i = 0; i < instanceCount; ++i)
+	{
+		device->setInstanceID(i);
+
+		TranslatedIndexData indexInfo;
+		GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
+		if(err != GL_NO_ERROR)
+		{
+			return error(err);
+		}
+
+		GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+		err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
+		if(err != GL_NO_ERROR)
+		{
+			return error(err);
+		}
+
+		applyShaders();
+		applyTextures();
+
+		if(!getCurrentProgram()->validateSamplers(false))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!cullSkipsDraw(mode))
+		{
+			device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
+		}
+	}
+}
+
+void Context::finish()
+{
+	device->finish();
+}
+
+void Context::flush()
+{
+	// We don't queue anything without processing it as fast as possible
+}
+
+void Context::recordInvalidEnum()
+{
+	mInvalidEnum = true;
+}
+
+void Context::recordInvalidValue()
+{
+	mInvalidValue = true;
+}
+
+void Context::recordInvalidOperation()
+{
+	mInvalidOperation = true;
+}
+
+void Context::recordOutOfMemory()
+{
+	mOutOfMemory = true;
+}
+
+void Context::recordInvalidFramebufferOperation()
+{
+	mInvalidFramebufferOperation = true;
+}
+
+// Get one of the recorded errors and clear its flag, if any.
+// [OpenGL ES 2.0.24] section 2.5 page 13.
+GLenum Context::getError()
+{
+	if(mInvalidEnum)
+	{
+		mInvalidEnum = false;
+
+		return GL_INVALID_ENUM;
+	}
+
+	if(mInvalidValue)
+	{
+		mInvalidValue = false;
+
+		return GL_INVALID_VALUE;
+	}
+
+	if(mInvalidOperation)
+	{
+		mInvalidOperation = false;
+
+		return GL_INVALID_OPERATION;
+	}
+
+	if(mOutOfMemory)
+	{
+		mOutOfMemory = false;
+
+		return GL_OUT_OF_MEMORY;
+	}
+
+	if(mInvalidFramebufferOperation)
+	{
+		mInvalidFramebufferOperation = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION;
+	}
+
+	return GL_NO_ERROR;
+}
+
+int Context::getSupportedMultisampleCount(int requested)
+{
+	int supported = 0;
+
+	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
+	{
+		if(supported >= requested)
+		{
+			return supported;
+		}
+
+		supported = multisampleCount[i];
+	}
+
+	return supported;
+}
+
+void Context::detachBuffer(GLuint buffer)
+{
+	// [OpenGL ES 2.0.24] section 2.9 page 22:
+	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
+	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
+
+	if(mState.copyReadBuffer.name() == buffer)
+	{
+		mState.copyReadBuffer = nullptr;
+	}
+
+	if(mState.copyWriteBuffer.name() == buffer)
+	{
+		mState.copyWriteBuffer = nullptr;
+	}
+
+	if(mState.pixelPackBuffer.name() == buffer)
+	{
+		mState.pixelPackBuffer = nullptr;
+	}
+
+	if(mState.pixelUnpackBuffer.name() == buffer)
+	{
+		mState.pixelUnpackBuffer = nullptr;
+	}
+
+	if(mState.genericUniformBuffer.name() == buffer)
+	{
+		mState.genericUniformBuffer = nullptr;
+	}
+
+	if(getArrayBufferName() == buffer)
+	{
+		mState.arrayBuffer = nullptr;
+	}
+
+	// Only detach from the current transform feedback
+	TransformFeedback* currentTransformFeedback = getTransformFeedback();
+	if(currentTransformFeedback)
+	{
+		currentTransformFeedback->detachBuffer(buffer);
+	}
+
+	// Only detach from the current vertex array
+	VertexArray* currentVertexArray = getCurrentVertexArray();
+	if(currentVertexArray)
+	{
+		currentVertexArray->detachBuffer(buffer);
+	}
+
+	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+	{
+		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
+		{
+			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
+		}
+	}
+}
+
+void Context::detachTexture(GLuint texture)
+{
+	// [OpenGL ES 2.0.24] section 3.8 page 84:
+	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
+	// rebound to texture object zero
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+		{
+			if(mState.samplerTexture[type][sampler].name() == texture)
+			{
+				mState.samplerTexture[type][sampler] = nullptr;
+			}
+		}
+	}
+
+	// [OpenGL ES 2.0.24] section 4.4 page 112:
+	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
+	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
+	// image was attached in the currently bound framebuffer.
+
+	Framebuffer *readFramebuffer = getReadFramebuffer();
+	Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+	if(readFramebuffer)
+	{
+		readFramebuffer->detachTexture(texture);
+	}
+
+	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
+	{
+		drawFramebuffer->detachTexture(texture);
+	}
+}
+
+void Context::detachFramebuffer(GLuint framebuffer)
+{
+	// [OpenGL ES 2.0.24] section 4.4 page 107:
+	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
+	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
+
+	if(mState.readFramebuffer == framebuffer)
+	{
+		bindReadFramebuffer(0);
+	}
+
+	if(mState.drawFramebuffer == framebuffer)
+	{
+		bindDrawFramebuffer(0);
+	}
+}
+
+void Context::detachRenderbuffer(GLuint renderbuffer)
+{
+	// [OpenGL ES 2.0.24] section 4.4 page 109:
+	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
+	// had been executed with the target RENDERBUFFER and name of zero.
+
+	if(mState.renderbuffer.name() == renderbuffer)
+	{
+		bindRenderbuffer(0);
+	}
+
+	// [OpenGL ES 2.0.24] section 4.4 page 111:
+	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
+	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
+	// point to which this image was attached in the currently bound framebuffer.
+
+	Framebuffer *readFramebuffer = getReadFramebuffer();
+	Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+	if(readFramebuffer)
+	{
+		readFramebuffer->detachRenderbuffer(renderbuffer);
+	}
+
+	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
+	{
+		drawFramebuffer->detachRenderbuffer(renderbuffer);
+	}
+}
+
+void Context::detachSampler(GLuint sampler)
+{
+	// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
+	// If a sampler object that is currently bound to one or more texture units is
+	// deleted, it is as though BindSampler is called once for each texture unit to
+	// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
+	for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
+	{
+		gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
+		if(samplerBinding.name() == sampler)
+		{
+			samplerBinding = nullptr;
+		}
+	}
+}
+
+bool Context::cullSkipsDraw(GLenum drawMode)
+{
+	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
+}
+
+bool Context::isTriangleMode(GLenum drawMode)
+{
+	switch(drawMode)
+	{
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		return true;
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+		return false;
+	default: UNREACHABLE(drawMode);
+	}
+
+	return false;
+}
+
+void Context::setVertexAttrib(GLuint index, const GLfloat *values)
+{
+	ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+	mState.vertexAttribute[index].setCurrentValue(values);
+
+	mVertexDataManager->dirtyCurrentValue(index);
+}
+
+void Context::setVertexAttrib(GLuint index, const GLint *values)
+{
+	ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+	mState.vertexAttribute[index].setCurrentValue(values);
+
+	mVertexDataManager->dirtyCurrentValue(index);
+}
+
+void Context::setVertexAttrib(GLuint index, const GLuint *values)
+{
+	ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+	mState.vertexAttribute[index].setCurrentValue(values);
+
+	mVertexDataManager->dirtyCurrentValue(index);
+}
+
+void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                              GLbitfield mask)
+{
+	Framebuffer *readFramebuffer = getReadFramebuffer();
+	Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+	int readBufferWidth, readBufferHeight, readBufferSamples;
+	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
+
+	if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
+	   !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+	}
+
+	if(drawBufferSamples > 1)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	sw::SliceRect sourceRect;
+	sw::SliceRect destRect;
+	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
+	bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1);
+
+	if(srcX0 < srcX1)
+	{
+		sourceRect.x0 = srcX0;
+		sourceRect.x1 = srcX1;
+	}
+	else
+	{
+		sourceRect.x0 = srcX1;
+		sourceRect.x1 = srcX0;
+	}
+
+	if(dstX0 < dstX1)
+	{
+		destRect.x0 = dstX0;
+		destRect.x1 = dstX1;
+	}
+	else
+	{
+		destRect.x0 = dstX1;
+		destRect.x1 = dstX0;
+	}
+
+	if(srcY0 < srcY1)
+	{
+		sourceRect.y0 = srcY0;
+		sourceRect.y1 = srcY1;
+	}
+	else
+	{
+		sourceRect.y0 = srcY1;
+		sourceRect.y1 = srcY0;
+	}
+
+	if(dstY0 < dstY1)
+	{
+		destRect.y0 = dstY0;
+		destRect.y1 = dstY1;
+	}
+	else
+	{
+		destRect.y0 = dstY1;
+		destRect.y1 = dstY0;
+	}
+
+	sw::Rect sourceScissoredRect = sourceRect;
+	sw::Rect destScissoredRect = destRect;
+
+	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
+	{
+		if(destRect.x0 < mState.scissorX)
+		{
+			int xDiff = mState.scissorX - destRect.x0;
+			destScissoredRect.x0 = mState.scissorX;
+			sourceScissoredRect.x0 += xDiff;
+		}
+
+		if(destRect.x1 > mState.scissorX + mState.scissorWidth)
+		{
+			int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
+			destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
+			sourceScissoredRect.x1 -= xDiff;
+		}
+
+		if(destRect.y0 < mState.scissorY)
+		{
+			int yDiff = mState.scissorY - destRect.y0;
+			destScissoredRect.y0 = mState.scissorY;
+			sourceScissoredRect.y0 += yDiff;
+		}
+
+		if(destRect.y1 > mState.scissorY + mState.scissorHeight)
+		{
+			int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
+			destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
+			sourceScissoredRect.y1 -= yDiff;
+		}
+	}
+
+	sw::Rect sourceTrimmedRect = sourceScissoredRect;
+	sw::Rect destTrimmedRect = destScissoredRect;
+
+	// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
+	// the actual draw and read surfaces.
+	if(sourceTrimmedRect.x0 < 0)
+	{
+		int xDiff = 0 - sourceTrimmedRect.x0;
+		sourceTrimmedRect.x0 = 0;
+		destTrimmedRect.x0 += xDiff;
+	}
+
+	if(sourceTrimmedRect.x1 > readBufferWidth)
+	{
+		int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
+		sourceTrimmedRect.x1 = readBufferWidth;
+		destTrimmedRect.x1 -= xDiff;
+	}
+
+	if(sourceTrimmedRect.y0 < 0)
+	{
+		int yDiff = 0 - sourceTrimmedRect.y0;
+		sourceTrimmedRect.y0 = 0;
+		destTrimmedRect.y0 += yDiff;
+	}
+
+	if(sourceTrimmedRect.y1 > readBufferHeight)
+	{
+		int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
+		sourceTrimmedRect.y1 = readBufferHeight;
+		destTrimmedRect.y1 -= yDiff;
+	}
+
+	if(destTrimmedRect.x0 < 0)
+	{
+		int xDiff = 0 - destTrimmedRect.x0;
+		destTrimmedRect.x0 = 0;
+		sourceTrimmedRect.x0 += xDiff;
+	}
+
+	if(destTrimmedRect.x1 > drawBufferWidth)
+	{
+		int xDiff = destTrimmedRect.x1 - drawBufferWidth;
+		destTrimmedRect.x1 = drawBufferWidth;
+		sourceTrimmedRect.x1 -= xDiff;
+	}
+
+	if(destTrimmedRect.y0 < 0)
+	{
+		int yDiff = 0 - destTrimmedRect.y0;
+		destTrimmedRect.y0 = 0;
+		sourceTrimmedRect.y0 += yDiff;
+	}
+
+	if(destTrimmedRect.y1 > drawBufferHeight)
+	{
+		int yDiff = destTrimmedRect.y1 - drawBufferHeight;
+		destTrimmedRect.y1 = drawBufferHeight;
+		sourceTrimmedRect.y1 -= yDiff;
+	}
+
+	bool partialBufferCopy = false;
+
+	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
+	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
+	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
+	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
+	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
+	{
+		partialBufferCopy = true;
+	}
+
+	bool blitRenderTarget = false;
+	bool blitDepthStencil = false;
+
+	if(mask & GL_COLOR_BUFFER_BIT)
+	{
+		GLenum readColorbufferType = readFramebuffer->getColorbufferType(getReadFramebufferColorIndex());
+		GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);
+		const bool validReadType = readColorbufferType == GL_TEXTURE_2D || Framebuffer::IsRenderbuffer(readColorbufferType);
+		const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || Framebuffer::IsRenderbuffer(drawColorbufferType);
+		if(!validReadType || !validDrawType)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(partialBufferCopy && readBufferSamples > 1)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		blitRenderTarget = true;
+	}
+
+	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+	{
+		Renderbuffer *readDSBuffer = nullptr;
+		Renderbuffer *drawDSBuffer = nullptr;
+
+		if(mask & GL_DEPTH_BUFFER_BIT)
+		{
+			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
+			{
+				if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType())
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+
+				blitDepthStencil = true;
+				readDSBuffer = readFramebuffer->getDepthbuffer();
+				drawDSBuffer = drawFramebuffer->getDepthbuffer();
+			}
+		}
+
+		if(mask & GL_STENCIL_BUFFER_BIT)
+		{
+			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
+			{
+				if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType())
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+
+				blitDepthStencil = true;
+				readDSBuffer = readFramebuffer->getStencilbuffer();
+				drawDSBuffer = drawFramebuffer->getStencilbuffer();
+			}
+		}
+
+		if(partialBufferCopy)
+		{
+			ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
+			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
+		}
+
+		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
+		   (readDSBuffer && readDSBuffer->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	if(blitRenderTarget || blitDepthStencil)
+	{
+		if(blitRenderTarget)
+		{
+			egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
+			egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
+
+			if(flipX)
+			{
+				swap(destRect.x0, destRect.x1);
+			}
+			if(flipy)
+			{
+				swap(destRect.y0, destRect.y1);
+			}
+
+			bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
+
+			readRenderTarget->release();
+			drawRenderTarget->release();
+
+			if(!success)
+			{
+				ERR("BlitFramebuffer failed.");
+				return;
+			}
+		}
+
+		if(blitDepthStencil)
+		{
+			bool success = device->stretchRect(readFramebuffer->getDepthBuffer(), nullptr, drawFramebuffer->getDepthBuffer(), nullptr, false);
+
+			if(!success)
+			{
+				ERR("BlitFramebuffer failed.");
+				return;
+			}
+		}
+	}
+}
+
+void Context::bindTexImage(egl::Surface *surface)
+{
+	es2::Texture2D *textureObject = getTexture2D();
+
+	if(textureObject)
+	{
+		textureObject->bindTexImage(surface);
+	}
+}
+
+EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+	GLenum textureTarget = GL_NONE;
+
+	switch(target)
+	{
+	case EGL_GL_TEXTURE_2D_KHR:
+		textureTarget = GL_TEXTURE_2D;
+		break;
+	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+		textureTarget = GL_TEXTURE_CUBE_MAP;
+		break;
+	case EGL_GL_RENDERBUFFER_KHR:
+		break;
+	default:
+		return EGL_BAD_PARAMETER;
+	}
+
+	if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return EGL_BAD_MATCH;
+	}
+
+	if(textureTarget != GL_NONE)
+	{
+		es2::Texture *texture = getTexture(name);
+
+		if(!texture || texture->getTarget() != textureTarget)
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
+		{
+			return EGL_BAD_ACCESS;
+		}
+
+		if(textureLevel != 0 && !texture->isSamplerComplete())
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+		{
+			return EGL_BAD_PARAMETER;
+		}
+	}
+	else if(target == EGL_GL_RENDERBUFFER_KHR)
+	{
+		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+		if(!renderbuffer)
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(renderbuffer->isShared())   // Already an EGLImage sibling
+		{
+			return EGL_BAD_ACCESS;
+		}
+	}
+	else UNREACHABLE(target);
+
+	return EGL_SUCCESS;
+}
+
+egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+	GLenum textureTarget = GL_NONE;
+
+	switch(target)
+	{
+	case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
+	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
+	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
+	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
+	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
+	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
+	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
+	}
+
+	if(textureTarget != GL_NONE)
+	{
+		es2::Texture *texture = getTexture(name);
+
+		return texture->createSharedImage(textureTarget, textureLevel);
+	}
+	else if(target == EGL_GL_RENDERBUFFER_KHR)
+	{
+		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+		return renderbuffer->createSharedImage();
+	}
+	else UNREACHABLE(target);
+
+	return 0;
+}
+
+Device *Context::getDevice()
+{
+	return device;
+}
+
+const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const
+{
+	// Keep list sorted in following order:
+	// OES extensions
+	// EXT extensions
+	// Vendor extensions
+	static const GLubyte* extensions[] = {
+		(const GLubyte*)"GL_OES_compressed_ETC1_RGB8_texture",
+		(const GLubyte*)"GL_OES_depth24",
+		(const GLubyte*)"GL_OES_depth32",
+		(const GLubyte*)"GL_OES_depth_texture",
+		(const GLubyte*)"GL_OES_depth_texture_cube_map",
+		(const GLubyte*)"GL_OES_EGL_image",
+		(const GLubyte*)"GL_OES_EGL_image_external",
+		(const GLubyte*)"GL_OES_EGL_sync",
+		(const GLubyte*)"GL_OES_element_index_uint",
+		(const GLubyte*)"GL_OES_framebuffer_object",
+		(const GLubyte*)"GL_OES_packed_depth_stencil",
+		(const GLubyte*)"GL_OES_rgb8_rgba8",
+		(const GLubyte*)"GL_OES_standard_derivatives",
+		(const GLubyte*)"GL_OES_texture_float",
+		(const GLubyte*)"GL_OES_texture_float_linear",
+		(const GLubyte*)"GL_OES_texture_half_float",
+		(const GLubyte*)"GL_OES_texture_half_float_linear",
+		(const GLubyte*)"GL_OES_texture_npot",
+		(const GLubyte*)"GL_OES_texture_3D",
+		(const GLubyte*)"GL_EXT_blend_minmax",
+		(const GLubyte*)"GL_EXT_color_buffer_half_float",
+		(const GLubyte*)"GL_EXT_draw_buffers",
+		(const GLubyte*)"GL_EXT_occlusion_query_boolean",
+		(const GLubyte*)"GL_EXT_read_format_bgra",
+#if (S3TC_SUPPORT)
+		(const GLubyte*)"GL_EXT_texture_compression_dxt1",
+#endif
+		(const GLubyte*)"GL_EXT_texture_filter_anisotropic",
+		(const GLubyte*)"GL_EXT_texture_format_BGRA8888",
+		(const GLubyte*)"GL_ANGLE_framebuffer_blit",
+		(const GLubyte*)"GL_NV_framebuffer_blit",
+		(const GLubyte*)"GL_ANGLE_framebuffer_multisample",
+#if (S3TC_SUPPORT)
+		(const GLubyte*)"GL_ANGLE_texture_compression_dxt3",
+		(const GLubyte*)"GL_ANGLE_texture_compression_dxt5",
+#endif
+		(const GLubyte*)"GL_NV_fence",
+		(const GLubyte*)"GL_NV_read_depth",
+		(const GLubyte*)"GL_EXT_instanced_arrays",
+		(const GLubyte*)"GL_ANGLE_instanced_arrays",
+	};
+	static const GLuint numExtensions = sizeof(extensions) / sizeof(*extensions);
+
+	if(numExt)
+	{
+		*numExt = numExtensions;
+		return nullptr;
+	}
+
+	if(index == GL_INVALID_INDEX)
+	{
+		static GLubyte* extensionsCat = nullptr;
+		if(!extensionsCat && (numExtensions > 0))
+		{
+			size_t totalLength = numExtensions; // 1 space between each extension name + terminating null
+			for(unsigned int i = 0; i < numExtensions; i++)
+			{
+				totalLength += strlen(reinterpret_cast<const char*>(extensions[i]));
+			}
+			extensionsCat = new GLubyte[totalLength];
+			extensionsCat[0] = '\0';
+			for(unsigned int i = 0; i < numExtensions; i++)
+			{
+				if(i != 0)
+				{
+					strcat(reinterpret_cast<char*>(extensionsCat), " ");
+				}
+				strcat(reinterpret_cast<char*>(extensionsCat), reinterpret_cast<const char*>(extensions[i]));
+			}
+		}
+		return extensionsCat;
+	}
+
+	if(index >= numExtensions)
+	{
+		return nullptr;
+	}
+
+	return extensions[index];
+}
+
+}
+
+egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion)
+{
+	ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion);   // Should be checked by eglCreateContext
+	return new es2::Context(config, static_cast<const es2::Context*>(shareContext), clientVersion);
+}
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 08c7a51..94b8fe8 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -1,761 +1,764 @@
-// 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.

-//

-

-// Context.h: Defines the Context class, managing all GL state and performing

-// rendering operations. It is the GLES2 specific implementation of EGLContext.

-

-#ifndef LIBGLESV2_CONTEXT_H_

-#define LIBGLESV2_CONTEXT_H_

-

-#include "ResourceManager.h"

-#include "Buffer.h"

-#include "libEGL/Context.hpp"

-#include "common/NameSpace.hpp"

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-#include "Renderer/Sampler.hpp"

-

-#include <GLES2/gl2.h>

-#include <GLES2/gl2ext.h>

-#include <GLES3/gl3.h>

-#include <EGL/egl.h>

-

-#include <map>

-#include <string>

-

-namespace egl

-{

-class Display;

-class Surface;

-class Config;

-}

-

-namespace es2

-{

-struct TranslatedAttribute;

-struct TranslatedIndexData;

-

-class Device;

-class Shader;

-class Program;

-class Texture;

-class Texture2D;

-class Texture3D;

-class Texture2DArray;

-class TextureCubeMap;

-class TextureExternal;

-class Framebuffer;

-class Renderbuffer;

-class RenderbufferStorage;

-class Colorbuffer;

-class Depthbuffer;

-class StreamingIndexBuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-class VertexDataManager;

-class IndexDataManager;

-class Fence;

-class FenceSync;

-class Query;

-class Sampler;

-class VertexArray;

-class TransformFeedback;

-

-enum

-{

-    MAX_VERTEX_ATTRIBS = sw::VERTEX_ATTRIBUTES,

-	MAX_UNIFORM_VECTORS = 256,   // Device limit

-    MAX_VERTEX_UNIFORM_VECTORS = sw::VERTEX_UNIFORM_VECTORS - 3,   // Reserve space for gl_DepthRange

-    MAX_VARYING_VECTORS = 10,

-    MAX_TEXTURE_IMAGE_UNITS = sw::TEXTURE_IMAGE_UNITS,

-    MAX_VERTEX_TEXTURE_IMAGE_UNITS = sw::VERTEX_TEXTURE_IMAGE_UNITS,

-    MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,

-    MAX_FRAGMENT_UNIFORM_VECTORS = sw::FRAGMENT_UNIFORM_VECTORS - 3,    // Reserve space for gl_DepthRange

-	MAX_ELEMENT_INDEX = 0x7FFFFFFF,

-	MAX_ELEMENTS_INDICES = 0x7FFFFFFF,

-	MAX_ELEMENTS_VERTICES = 0x7FFFFFFF,

-    MAX_VERTEX_OUTPUT_VECTORS = 16,

-    MAX_FRAGMENT_INPUT_VECTORS = 15,

-    MIN_PROGRAM_TEXEL_OFFSET = -8,

-    MAX_PROGRAM_TEXEL_OFFSET = 7,

-	MAX_DRAW_BUFFERS = sw::RENDERTARGETS,

-	MAX_COLOR_ATTACHMENTS = MAX(MAX_DRAW_BUFFERS, 8),

-	MAX_FRAGMENT_UNIFORM_BLOCKS = sw::MAX_FRAGMENT_UNIFORM_BLOCKS,

-	MAX_VERTEX_UNIFORM_BLOCKS = sw::MAX_VERTEX_UNIFORM_BLOCKS,

-	MAX_FRAGMENT_UNIFORM_COMPONENTS = sw::FRAGMENT_UNIFORM_VECTORS * 4,

-	MAX_VERTEX_UNIFORM_COMPONENTS = sw::VERTEX_UNIFORM_VECTORS * 4,

-	MAX_UNIFORM_BLOCK_SIZE = sw::MAX_UNIFORM_BLOCK_SIZE,

-	MAX_FRAGMENT_UNIFORM_BLOCKS_COMPONENTS = sw::MAX_FRAGMENT_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4,

-	MAX_VERTEX_UNIFORM_BLOCKS_COMPONENTS = MAX_VERTEX_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4,

-	MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = MAX_FRAGMENT_UNIFORM_BLOCKS_COMPONENTS + MAX_FRAGMENT_UNIFORM_COMPONENTS,

-	MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = MAX_VERTEX_UNIFORM_BLOCKS_COMPONENTS + MAX_VERTEX_UNIFORM_COMPONENTS,

-	MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4,

-	MAX_UNIFORM_BUFFER_BINDINGS = sw::MAX_UNIFORM_BUFFER_BINDINGS,

-	UNIFORM_BUFFER_OFFSET_ALIGNMENT = 1,

-};

-

-const GLenum compressedTextureFormats[] =

-{

-	GL_ETC1_RGB8_OES,

-#if (S3TC_SUPPORT)

-	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,

-	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,

-	GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,

-	GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,

-#endif

-#if (GL_ES_VERSION_3_0)

-	GL_COMPRESSED_R11_EAC,

-	GL_COMPRESSED_SIGNED_R11_EAC,

-	GL_COMPRESSED_RG11_EAC,

-	GL_COMPRESSED_SIGNED_RG11_EAC,

-	GL_COMPRESSED_RGB8_ETC2,

-	GL_COMPRESSED_SRGB8_ETC2,

-	GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,

-	GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,

-	GL_COMPRESSED_RGBA8_ETC2_EAC,

-	GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,

-	GL_COMPRESSED_RGBA_ASTC_4x4_KHR,

-	GL_COMPRESSED_RGBA_ASTC_5x4_KHR,

-	GL_COMPRESSED_RGBA_ASTC_5x5_KHR,

-	GL_COMPRESSED_RGBA_ASTC_6x5_KHR,

-	GL_COMPRESSED_RGBA_ASTC_6x6_KHR,

-	GL_COMPRESSED_RGBA_ASTC_8x5_KHR,

-	GL_COMPRESSED_RGBA_ASTC_8x6_KHR,

-	GL_COMPRESSED_RGBA_ASTC_8x8_KHR,

-	GL_COMPRESSED_RGBA_ASTC_10x5_KHR,

-	GL_COMPRESSED_RGBA_ASTC_10x6_KHR,

-	GL_COMPRESSED_RGBA_ASTC_10x8_KHR,

-	GL_COMPRESSED_RGBA_ASTC_10x10_KHR,

-	GL_COMPRESSED_RGBA_ASTC_12x10_KHR,

-	GL_COMPRESSED_RGBA_ASTC_12x12_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,

-	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,

-#endif

-};

-

-const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);

-

-const GLint multisampleCount[] = {4, 2, 1};

-const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);

-const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];

-

-const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;

-const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;

-const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;

-const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;

-const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;

-

-enum QueryType

-{

-    QUERY_ANY_SAMPLES_PASSED,

-    QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE,

-    QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,

-

-    QUERY_TYPE_COUNT

-};

-

-struct Color

-{

-    float red;

-    float green;

-    float blue;

-    float alpha;

-};

-

-// Helper structure describing a single vertex attribute

-class VertexAttribute

-{

-public:

-    VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mDivisor(0), mPointer(NULL), mArrayEnabled(false)

-    {

-        mCurrentValue[0].f = 0.0f;

-        mCurrentValue[1].f = 0.0f;

-        mCurrentValue[2].f = 0.0f;

-        mCurrentValue[3].f = 1.0f;

-		mCurrentValueType = ValueUnion::FloatType;

-    }

-

-    int typeSize() const

-    {

-        switch (mType)

-        {

-        case GL_BYTE:           return mSize * sizeof(GLbyte);

-        case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);

-        case GL_SHORT:          return mSize * sizeof(GLshort);

-        case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);

-		case GL_INT:            return mSize * sizeof(GLint);

-		case GL_UNSIGNED_INT:   return mSize * sizeof(GLuint);

-        case GL_FIXED:          return mSize * sizeof(GLfixed);

-        case GL_FLOAT:          return mSize * sizeof(GLfloat);

-        default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);

-        }

-    }

-

-    GLsizei stride() const

-    {

-        return mStride ? mStride : typeSize();

-    }

-

-	inline float getCurrentValueBitsAsFloat(int i) const

-	{

-		return mCurrentValue[i].f;

-	}

-

-	inline float getCurrentValueF(int i) const

-	{

-		switch(mCurrentValueType)

-		{

-		case ValueUnion::FloatType:	return mCurrentValue[i].f;

-		case ValueUnion::IntType:	return static_cast<float>(mCurrentValue[i].i);

-		case ValueUnion::UIntType:	return static_cast<float>(mCurrentValue[i].ui);

-		default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].f;

-		}

-	}

-

-	inline GLint getCurrentValueI(int i) const

-	{

-		switch(mCurrentValueType)

-		{

-		case ValueUnion::FloatType:	return static_cast<GLint>(mCurrentValue[i].f);

-		case ValueUnion::IntType:	return mCurrentValue[i].i;

-		case ValueUnion::UIntType:	return static_cast<GLint>(mCurrentValue[i].ui);

-		default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].i;

-		}

-	}

-

-	inline GLuint getCurrentValueUI(int i) const

-	{

-		switch(mCurrentValueType)

-		{

-		case ValueUnion::FloatType:	return static_cast<GLuint>(mCurrentValue[i].f);

-		case ValueUnion::IntType:	return static_cast<GLuint>(mCurrentValue[i].i);

-		case ValueUnion::UIntType:	return mCurrentValue[i].ui;

-		default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].ui;

-		}

-	}

-

-	inline void setCurrentValue(const GLfloat *values)

-	{

-		mCurrentValue[0].f = values[0];

-		mCurrentValue[1].f = values[1];

-		mCurrentValue[2].f = values[2];

-		mCurrentValue[3].f = values[3];

-		mCurrentValueType = ValueUnion::FloatType;

-	}

-

-	inline void setCurrentValue(const GLint *values)

-	{

-		mCurrentValue[0].i = values[0];

-		mCurrentValue[1].i = values[1];

-		mCurrentValue[2].i = values[2];

-		mCurrentValue[3].i = values[3];

-		mCurrentValueType = ValueUnion::IntType;

-	}

-

-	inline void setCurrentValue(const GLuint *values)

-	{

-		mCurrentValue[0].ui = values[0];

-		mCurrentValue[1].ui = values[1];

-		mCurrentValue[2].ui = values[2];

-		mCurrentValue[3].ui = values[3];

-		mCurrentValueType = ValueUnion::UIntType;

-	}

-

-    // From glVertexAttribPointer

-    GLenum mType;

-    GLint mSize;

-    bool mNormalized;

-    GLsizei mStride;   // 0 means natural stride

-    GLuint mDivisor;   // From glVertexAttribDivisor

-

-    union

-    {

-        const void *mPointer;

-        intptr_t mOffset;

-    };

-

-    gl::BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.

-

-    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray

-

-private:

-	union ValueUnion

-	{

-		enum Type { FloatType, IntType, UIntType };

-

-		float f;

-		GLint i;

-		GLuint ui;

-	};

-

-	ValueUnion mCurrentValue[4];   // From glVertexAttrib

-	ValueUnion::Type mCurrentValueType;

-};

-

-typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];

-

-// Helper structure to store all raw state

-struct State

-{

-    Color colorClearValue;

-    GLclampf depthClearValue;

-    int stencilClearValue;

-

-    bool cullFaceEnabled;

-    GLenum cullMode;

-    GLenum frontFace;

-    bool depthTestEnabled;

-    GLenum depthFunc;

-    bool blendEnabled;

-    GLenum sourceBlendRGB;

-    GLenum destBlendRGB;

-    GLenum sourceBlendAlpha;

-    GLenum destBlendAlpha;

-    GLenum blendEquationRGB;

-    GLenum blendEquationAlpha;

-    Color blendColor;

-    bool stencilTestEnabled;

-    GLenum stencilFunc;

-    GLint stencilRef;

-    GLuint stencilMask;

-    GLenum stencilFail;

-    GLenum stencilPassDepthFail;

-    GLenum stencilPassDepthPass;

-    GLuint stencilWritemask;

-    GLenum stencilBackFunc;

-    GLint stencilBackRef;

-    GLuint stencilBackMask;

-    GLenum stencilBackFail;

-    GLenum stencilBackPassDepthFail;

-    GLenum stencilBackPassDepthPass;

-    GLuint stencilBackWritemask;

-    bool polygonOffsetFillEnabled;

-    GLfloat polygonOffsetFactor;

-    GLfloat polygonOffsetUnits;

-    bool sampleAlphaToCoverageEnabled;

-    bool sampleCoverageEnabled;

-    GLclampf sampleCoverageValue;

-    bool sampleCoverageInvert;

-    bool scissorTestEnabled;

-    bool ditherEnabled;

-    bool primitiveRestartFixedIndexEnabled;

-    bool rasterizerDiscardEnabled;

-    bool colorLogicOpEnabled;

-    GLenum logicalOperation;

-

-    GLfloat lineWidth;

-

-    GLenum generateMipmapHint;

-    GLenum fragmentShaderDerivativeHint;

-

-    GLint viewportX;

-    GLint viewportY;

-    GLsizei viewportWidth;

-    GLsizei viewportHeight;

-    float zNear;

-    float zFar;

-

-    GLint scissorX;

-    GLint scissorY;

-    GLsizei scissorWidth;

-    GLsizei scissorHeight;

-

-    bool colorMaskRed;

-    bool colorMaskGreen;

-    bool colorMaskBlue;

-    bool colorMaskAlpha;

-    bool depthMask;

-

-    unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0

-    gl::BindingPointer<Buffer> arrayBuffer;

-	gl::BindingPointer<Buffer> copyReadBuffer;

-	gl::BindingPointer<Buffer> copyWriteBuffer;

-	gl::BindingPointer<Buffer> pixelPackBuffer;

-	gl::BindingPointer<Buffer> pixelUnpackBuffer;

-	gl::BindingPointer<Buffer> genericUniformBuffer;

-	BufferBinding uniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];

-

-    GLuint readFramebuffer;

-    GLuint drawFramebuffer;

-    gl::BindingPointer<Renderbuffer> renderbuffer;

-    GLuint currentProgram;

-	GLuint vertexArray;

-	GLuint transformFeedback;

-	gl::BindingPointer<Sampler> sampler[MAX_COMBINED_TEXTURE_IMAGE_UNITS];

-

-    VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];

-    gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];

-	gl::BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];

-

-	egl::Image::UnpackInfo unpackInfo;

-    GLint packAlignment;

-	GLint packRowLength;

-	GLint packImageHeight;

-	GLint packSkipPixels;

-	GLint packSkipRows;

-	GLint packSkipImages;

-};

-

-class Context : public egl::Context

-{

-public:

-    Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion);

-

-	virtual void makeCurrent(egl::Surface *surface);

-	virtual EGLint getClientVersion() const;

-

-    void markAllStateDirty();

-

-    // State manipulation

-    void setClearColor(float red, float green, float blue, float alpha);

-    void setClearDepth(float depth);

-    void setClearStencil(int stencil);

-

-    void setCullFaceEnabled(bool enabled);

-    bool isCullFaceEnabled() const;

-    void setCullMode(GLenum mode);

-    void setFrontFace(GLenum front);

-

-    void setDepthTestEnabled(bool enabled);

-    bool isDepthTestEnabled() const;

-    void setDepthFunc(GLenum depthFunc);

-    void setDepthRange(float zNear, float zFar);

-

-    void setBlendEnabled(bool enabled);

-    bool isBlendEnabled() const;

-    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);

-    void setBlendColor(float red, float green, float blue, float alpha);

-    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);

-

-    void setStencilTestEnabled(bool enabled);

-    bool isStencilTestEnabled() const;

-    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);

-    void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);

-    void setStencilWritemask(GLuint stencilWritemask);

-    void setStencilBackWritemask(GLuint stencilBackWritemask);

-    void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);

-    void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);

-

-    void setPolygonOffsetFillEnabled(bool enabled);

-    bool isPolygonOffsetFillEnabled() const;

-    void setPolygonOffsetParams(GLfloat factor, GLfloat units);

-

-    void setSampleAlphaToCoverageEnabled(bool enabled);

-    bool isSampleAlphaToCoverageEnabled() const;

-    void setSampleCoverageEnabled(bool enabled);

-    bool isSampleCoverageEnabled() const;

-    void setSampleCoverageParams(GLclampf value, bool invert);

-

-    void setDitherEnabled(bool enabled);

-    bool isDitherEnabled() const;

-

-    void setPrimitiveRestartFixedIndexEnabled(bool enabled);

-    bool isPrimitiveRestartFixedIndexEnabled() const;

-

-    void setRasterizerDiscardEnabled(bool enabled);

-    bool isRasterizerDiscardEnabled() const;

-

-    void setLineWidth(GLfloat width);

-

-    void setGenerateMipmapHint(GLenum hint);

-    void setFragmentShaderDerivativeHint(GLenum hint);

-

-    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-	void setScissorTestEnabled(bool enabled);

-    bool isScissorTestEnabled() const;

-    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-    void setColorMask(bool red, bool green, bool blue, bool alpha);

-    unsigned int getColorMask() const;

-    void setDepthMask(bool mask);

-

-    void setActiveSampler(unsigned int active);

-

-    GLuint getReadFramebufferName() const;

-    GLuint getDrawFramebufferName() const;

-    GLuint getRenderbufferName() const;

-

-	void setFramebufferReadBuffer(GLenum buf);

-	void setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs);

-	GLuint getReadFramebufferColorIndex() const;

-

-	GLuint getActiveQuery(GLenum target) const;

-

-    GLuint getArrayBufferName() const;

-	GLuint getElementArrayBufferName() const;

-

-    void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);

-    void setVertexAttribDivisor(unsigned int attribNum, GLuint divisor);

-    const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;

-    void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,

-                              bool normalized, GLsizei stride, const void *pointer);

-    const void *getVertexAttribPointer(unsigned int attribNum) const;

-

-	const VertexAttributeArray &getVertexArrayAttributes();

-	// Context attribute current values can be queried independently from VAO current values

-	const VertexAttributeArray &getCurrentVertexAttributes();

-

-    void setUnpackAlignment(GLint alignment);

-	void setUnpackRowLength(GLint rowLength);

-	void setUnpackImageHeight(GLint imageHeight);

-	void setUnpackSkipPixels(GLint skipPixels);

-	void setUnpackSkipRows(GLint skipRows);

-	void setUnpackSkipImages(GLint skipImages);

-	const egl::Image::UnpackInfo& getUnpackInfo() const;

-

-    void setPackAlignment(GLint alignment);

-	void setPackRowLength(GLint rowLength);

-	void setPackImageHeight(GLint imageHeight);

-	void setPackSkipPixels(GLint skipPixels);

-	void setPackSkipRows(GLint skipRows);

-	void setPackSkipImages(GLint skipImages);

-

-    // These create and destroy methods are merely pass-throughs to

-    // ResourceManager, which owns these object types

-    GLuint createBuffer();

-    GLuint createShader(GLenum type);

-    GLuint createProgram();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-    GLuint createSampler();

-    GLsync createFenceSync(GLenum condition, GLbitfield flags);

-

-    void deleteBuffer(GLuint buffer);

-    void deleteShader(GLuint shader);

-    void deleteProgram(GLuint program);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-    void deleteSampler(GLuint sampler);

-    void deleteFenceSync(GLsync fenceSync);

-

-    // Framebuffers are owned by the Context, so these methods do not pass through

-    GLuint createFramebuffer();

-    void deleteFramebuffer(GLuint framebuffer);

-

-    // Fences are owned by the Context

-    GLuint createFence();

-    void deleteFence(GLuint fence);

-

-	// Queries are owned by the Context

-    GLuint createQuery();

-    void deleteQuery(GLuint query);

-

-	// Vertex arrays are owned by the Context

-	GLuint createVertexArray();

-	void deleteVertexArray(GLuint array);

-

-	// Transform feedbacks are owned by the Context

-	GLuint createTransformFeedback();

-	void deleteTransformFeedback(GLuint transformFeedback);

-

-    void bindArrayBuffer(GLuint buffer);

-    void bindElementArrayBuffer(GLuint buffer);

-	void bindCopyReadBuffer(GLuint buffer);

-	void bindCopyWriteBuffer(GLuint buffer);

-	void bindPixelPackBuffer(GLuint buffer);

-	void bindPixelUnpackBuffer(GLuint buffer);

-	void bindTransformFeedbackBuffer(GLuint buffer);

-    void bindTexture2D(GLuint texture);

-    void bindTextureCubeMap(GLuint texture);

-    void bindTextureExternal(GLuint texture);

-	void bindTexture3D(GLuint texture);

-	void bindTexture2DArray(GLuint texture);

-    void bindReadFramebuffer(GLuint framebuffer);

-    void bindDrawFramebuffer(GLuint framebuffer);

-    void bindRenderbuffer(GLuint renderbuffer);

-	void bindVertexArray(GLuint array);

-	void bindGenericUniformBuffer(GLuint buffer);

-	void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);

-	void bindGenericTransformFeedbackBuffer(GLuint buffer);

-	void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);

-	void bindTransformFeedback(GLuint transformFeedback);

-	bool bindSampler(GLuint unit, GLuint sampler);

-    void useProgram(GLuint program);

-

-	void beginQuery(GLenum target, GLuint query);

-    void endQuery(GLenum target);

-

-    void setFramebufferZero(Framebuffer *framebuffer);

-

-    void setRenderbufferStorage(RenderbufferStorage *renderbuffer);

-

-    void setVertexAttrib(GLuint index, const GLfloat *values);

-    void setVertexAttrib(GLuint index, const GLint *values);

-    void setVertexAttrib(GLuint index, const GLuint *values);

-

-	Buffer *getBuffer(GLuint handle) const;

-	Fence *getFence(GLuint handle) const;

-	FenceSync *getFenceSync(GLsync handle) const;

-	Shader *getShader(GLuint handle) const;

-	Program *getProgram(GLuint handle) const;

-	virtual Texture *getTexture(GLuint handle) const;

-	Framebuffer *getFramebuffer(GLuint handle) const;

-	virtual Renderbuffer *getRenderbuffer(GLuint handle) const;

-	Query *getQuery(GLuint handle) const;

-	VertexArray *getVertexArray(GLuint array) const;

-	VertexArray *getCurrentVertexArray() const;

-	bool isVertexArray(GLuint array) const;

-	TransformFeedback *getTransformFeedback(GLuint transformFeedback) const;

-	TransformFeedback *getTransformFeedback() const;

-	Sampler *getSampler(GLuint sampler) const;

-	bool isSampler(GLuint sampler) const;

-

-	Buffer *getArrayBuffer() const;

-	Buffer *getElementArrayBuffer() const;

-	Buffer *getCopyReadBuffer() const;

-	Buffer *getCopyWriteBuffer() const;

-	Buffer *getPixelPackBuffer() const;

-	Buffer *getPixelUnpackBuffer() const;

-	Buffer *getGenericUniformBuffer() const;

-	bool getBuffer(GLenum target, es2::Buffer **buffer) const;

-	Program *getCurrentProgram() const;

-	Texture2D *getTexture2D() const;

-	Texture3D *getTexture3D() const;

-	Texture2DArray *getTexture2DArray() const;

-	TextureCubeMap *getTextureCubeMap() const;

-	TextureExternal *getTextureExternal() const;

-	Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;

-	Framebuffer *getReadFramebuffer() const;

-	Framebuffer *getDrawFramebuffer() const;

-

-	bool getFloatv(GLenum pname, GLfloat *params) const;

-	template<typename T> bool getIntegerv(GLenum pname, T *params) const;

-	bool getBooleanv(GLenum pname, GLboolean *params) const;

-	template<typename T> bool getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const;

-	template<typename T> bool getUniformBufferiv(GLuint index, GLenum pname, T *param) const;

-	void samplerParameteri(GLuint sampler, GLenum pname, GLint param);

-	void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param);

-	GLint getSamplerParameteri(GLuint sampler, GLenum pname);

-	GLfloat getSamplerParameterf(GLuint sampler, GLenum pname);

-

-	bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const;

-

-	bool hasZeroDivisor() const;

-

-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);

-    void clear(GLbitfield mask);

-    void clearColorBuffer(GLint drawbuffer, const GLint *value);

-    void clearColorBuffer(GLint drawbuffer, const GLuint *value);

-    void clearColorBuffer(GLint drawbuffer, const GLfloat *value);

-    void clearDepthBuffer(const GLfloat value);

-    void clearStencilBuffer(const GLint value);

-    void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount = 1);

-    void drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount = 1);

-    void finish();

-    void flush();

-

-    void recordInvalidEnum();

-    void recordInvalidValue();

-    void recordInvalidOperation();

-    void recordOutOfMemory();

-    void recordInvalidFramebufferOperation();

-

-    GLenum getError();

-

-    static int getSupportedMultisampleCount(int requested);

-

-    void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,

-                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                         GLbitfield mask);

-

-	virtual void bindTexImage(egl::Surface *surface);

-	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);

-	virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);

-

-	Device *getDevice();

-

-	const GLubyte* getExtensions(GLuint index, GLuint* numExt = nullptr) const;

-

-private:

-	virtual ~Context();

-

-	void applyScissor(int width, int height);

-    bool applyRenderTarget();

-    void applyState(GLenum drawMode);

-	GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId);

-    GLenum applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);

-    void applyShaders();

-    void applyTextures();

-    void applyTextures(sw::SamplerType type);

-	void applyTexture(sw::SamplerType type, int sampler, Texture *texture);

-	void clearColorBuffer(GLint drawbuffer, void *value, sw::Format format);

-

-    void detachBuffer(GLuint buffer);

-    void detachTexture(GLuint texture);

-    void detachFramebuffer(GLuint framebuffer);

-    void detachRenderbuffer(GLuint renderbuffer);

-    void detachSampler(GLuint sampler);

-

-    bool cullSkipsDraw(GLenum drawMode);

-    bool isTriangleMode(GLenum drawMode);

-

-	Query *createQuery(GLuint handle, GLenum type);

-

-	const EGLint clientVersion;

-    const egl::Config *const mConfig;

-

-    State mState;

-

-	gl::BindingPointer<Texture2D> mTexture2DZero;

-	gl::BindingPointer<Texture3D> mTexture3DZero;

-	gl::BindingPointer<Texture2DArray> mTexture2DArrayZero;

-	gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero;

-    gl::BindingPointer<TextureExternal> mTextureExternalZero;

-

-	gl::NameSpace<Framebuffer> mFramebufferNameSpace;

-	gl::NameSpace<Fence, 0> mFenceNameSpace;

-	gl::NameSpace<Query> mQueryNameSpace;

-	gl::NameSpace<VertexArray> mVertexArrayNameSpace;

-	gl::NameSpace<TransformFeedback> mTransformFeedbackNameSpace;

-

-    VertexDataManager *mVertexDataManager;

-    IndexDataManager *mIndexDataManager;

-

-    // Recorded errors

-    bool mInvalidEnum;

-    bool mInvalidValue;

-    bool mInvalidOperation;

-    bool mOutOfMemory;

-    bool mInvalidFramebufferOperation;

-

-    bool mHasBeenCurrent;

-

-    unsigned int mAppliedProgramSerial;

-

-    // state caching flags

-    bool mDepthStateDirty;

-    bool mMaskStateDirty;

-    bool mBlendStateDirty;

-    bool mStencilStateDirty;

-    bool mPolygonOffsetStateDirty;

-    bool mSampleStateDirty;

-    bool mFrontFaceDirty;

-    bool mDitherStateDirty;

-

-	Device *device;

-    ResourceManager *mResourceManager;

-};

-}

-

-#endif   // INCLUDE_CONTEXT_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Context.h: Defines the Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#ifndef LIBGLESV2_CONTEXT_H_
+#define LIBGLESV2_CONTEXT_H_
+
+#include "ResourceManager.h"
+#include "Buffer.h"
+#include "libEGL/Context.hpp"
+#include "common/NameSpace.hpp"
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+#include "Renderer/Sampler.hpp"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+#include <EGL/egl.h>
+
+#include <map>
+#include <string>
+
+namespace egl
+{
+class Display;
+class Surface;
+class Config;
+}
+
+namespace es2
+{
+struct TranslatedAttribute;
+struct TranslatedIndexData;
+
+class Device;
+class Shader;
+class Program;
+class Texture;
+class Texture2D;
+class Texture3D;
+class Texture2DArray;
+class TextureCubeMap;
+class TextureExternal;
+class Framebuffer;
+class Renderbuffer;
+class RenderbufferStorage;
+class Colorbuffer;
+class Depthbuffer;
+class StreamingIndexBuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+class VertexDataManager;
+class IndexDataManager;
+class Fence;
+class FenceSync;
+class Query;
+class Sampler;
+class VertexArray;
+class TransformFeedback;
+
+enum
+{
+	MAX_VERTEX_ATTRIBS = sw::VERTEX_ATTRIBUTES,
+	MAX_UNIFORM_VECTORS = 256,   // Device limit
+	MAX_VERTEX_UNIFORM_VECTORS = sw::VERTEX_UNIFORM_VECTORS - 3,   // Reserve space for gl_DepthRange
+	MAX_VARYING_VECTORS = 10,
+	MAX_TEXTURE_IMAGE_UNITS = sw::TEXTURE_IMAGE_UNITS,
+	MAX_VERTEX_TEXTURE_IMAGE_UNITS = sw::VERTEX_TEXTURE_IMAGE_UNITS,
+	MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,
+	MAX_FRAGMENT_UNIFORM_VECTORS = sw::FRAGMENT_UNIFORM_VECTORS - 3,    // Reserve space for gl_DepthRange
+	MAX_ELEMENT_INDEX = 0x7FFFFFFF,
+	MAX_ELEMENTS_INDICES = 0x7FFFFFFF,
+	MAX_ELEMENTS_VERTICES = 0x7FFFFFFF,
+	MAX_VERTEX_OUTPUT_VECTORS = 16,
+	MAX_FRAGMENT_INPUT_VECTORS = 15,
+	MIN_PROGRAM_TEXEL_OFFSET = -8,
+	MAX_PROGRAM_TEXEL_OFFSET = 7,
+	MAX_DRAW_BUFFERS = sw::RENDERTARGETS,
+	MAX_COLOR_ATTACHMENTS = MAX(MAX_DRAW_BUFFERS, 8),
+	MAX_FRAGMENT_UNIFORM_BLOCKS = sw::MAX_FRAGMENT_UNIFORM_BLOCKS,
+	MAX_VERTEX_UNIFORM_BLOCKS = sw::MAX_VERTEX_UNIFORM_BLOCKS,
+	MAX_FRAGMENT_UNIFORM_COMPONENTS = sw::FRAGMENT_UNIFORM_VECTORS * 4,
+	MAX_VERTEX_UNIFORM_COMPONENTS = sw::VERTEX_UNIFORM_VECTORS * 4,
+	MAX_UNIFORM_BLOCK_SIZE = sw::MAX_UNIFORM_BLOCK_SIZE,
+	MAX_FRAGMENT_UNIFORM_BLOCKS_COMPONENTS = sw::MAX_FRAGMENT_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4,
+	MAX_VERTEX_UNIFORM_BLOCKS_COMPONENTS = MAX_VERTEX_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4,
+	MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = MAX_FRAGMENT_UNIFORM_BLOCKS_COMPONENTS + MAX_FRAGMENT_UNIFORM_COMPONENTS,
+	MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = MAX_VERTEX_UNIFORM_BLOCKS_COMPONENTS + MAX_VERTEX_UNIFORM_COMPONENTS,
+	MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4,
+	MAX_UNIFORM_BUFFER_BINDINGS = sw::MAX_UNIFORM_BUFFER_BINDINGS,
+	UNIFORM_BUFFER_OFFSET_ALIGNMENT = 1,
+};
+
+const GLenum compressedTextureFormats[] =
+{
+	GL_ETC1_RGB8_OES,
+#if (S3TC_SUPPORT)
+	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+	GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
+	GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
+#endif
+#if (GL_ES_VERSION_3_0)
+	GL_COMPRESSED_R11_EAC,
+	GL_COMPRESSED_SIGNED_R11_EAC,
+	GL_COMPRESSED_RG11_EAC,
+	GL_COMPRESSED_SIGNED_RG11_EAC,
+	GL_COMPRESSED_RGB8_ETC2,
+	GL_COMPRESSED_SRGB8_ETC2,
+	GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+	GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+	GL_COMPRESSED_RGBA8_ETC2_EAC,
+	GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
+	GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
+	GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
+	GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
+	GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
+	GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
+	GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
+	GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
+	GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
+	GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
+	GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
+	GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
+	GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
+	GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
+	GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
+	GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
+#endif
+};
+
+const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
+
+const GLint multisampleCount[] = {4, 2, 1};
+const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);
+const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];
+
+const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
+const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
+const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;
+const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;
+const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;
+
+enum QueryType
+{
+	QUERY_ANY_SAMPLES_PASSED,
+	QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE,
+	QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
+
+	QUERY_TYPE_COUNT
+};
+
+struct Color
+{
+	float red;
+	float green;
+	float blue;
+	float alpha;
+};
+
+// Helper structure describing a single vertex attribute
+class VertexAttribute
+{
+public:
+	VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mDivisor(0), mPointer(nullptr), mArrayEnabled(false)
+	{
+		mCurrentValue[0].f = 0.0f;
+		mCurrentValue[1].f = 0.0f;
+		mCurrentValue[2].f = 0.0f;
+		mCurrentValue[3].f = 1.0f;
+		mCurrentValueType = ValueUnion::FloatType;
+	}
+
+	int typeSize() const
+	{
+		switch(mType)
+		{
+		case GL_BYTE:           return mSize * sizeof(GLbyte);
+		case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);
+		case GL_SHORT:          return mSize * sizeof(GLshort);
+		case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
+		case GL_INT:            return mSize * sizeof(GLint);
+		case GL_UNSIGNED_INT:   return mSize * sizeof(GLuint);
+		case GL_FIXED:          return mSize * sizeof(GLfixed);
+		case GL_FLOAT:          return mSize * sizeof(GLfloat);
+		default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);
+		}
+	}
+
+	GLsizei stride() const
+	{
+		return mStride ? mStride : typeSize();
+	}
+
+	inline float getCurrentValueBitsAsFloat(int i) const
+	{
+		return mCurrentValue[i].f;
+	}
+
+	inline float getCurrentValueF(int i) const
+	{
+		switch(mCurrentValueType)
+		{
+		case ValueUnion::FloatType:	return mCurrentValue[i].f;
+		case ValueUnion::IntType:	return static_cast<float>(mCurrentValue[i].i);
+		case ValueUnion::UIntType:	return static_cast<float>(mCurrentValue[i].ui);
+		default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].f;
+		}
+	}
+
+	inline GLint getCurrentValueI(int i) const
+	{
+		switch(mCurrentValueType)
+		{
+		case ValueUnion::FloatType:	return static_cast<GLint>(mCurrentValue[i].f);
+		case ValueUnion::IntType:	return mCurrentValue[i].i;
+		case ValueUnion::UIntType:	return static_cast<GLint>(mCurrentValue[i].ui);
+		default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].i;
+		}
+	}
+
+	inline GLuint getCurrentValueUI(int i) const
+	{
+		switch(mCurrentValueType)
+		{
+		case ValueUnion::FloatType:	return static_cast<GLuint>(mCurrentValue[i].f);
+		case ValueUnion::IntType:	return static_cast<GLuint>(mCurrentValue[i].i);
+		case ValueUnion::UIntType:	return mCurrentValue[i].ui;
+		default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].ui;
+		}
+	}
+
+	inline void setCurrentValue(const GLfloat *values)
+	{
+		mCurrentValue[0].f = values[0];
+		mCurrentValue[1].f = values[1];
+		mCurrentValue[2].f = values[2];
+		mCurrentValue[3].f = values[3];
+		mCurrentValueType = ValueUnion::FloatType;
+	}
+
+	inline void setCurrentValue(const GLint *values)
+	{
+		mCurrentValue[0].i = values[0];
+		mCurrentValue[1].i = values[1];
+		mCurrentValue[2].i = values[2];
+		mCurrentValue[3].i = values[3];
+		mCurrentValueType = ValueUnion::IntType;
+	}
+
+	inline void setCurrentValue(const GLuint *values)
+	{
+		mCurrentValue[0].ui = values[0];
+		mCurrentValue[1].ui = values[1];
+		mCurrentValue[2].ui = values[2];
+		mCurrentValue[3].ui = values[3];
+		mCurrentValueType = ValueUnion::UIntType;
+	}
+
+	// From glVertexAttribPointer
+	GLenum mType;
+	GLint mSize;
+	bool mNormalized;
+	GLsizei mStride;   // 0 means natural stride
+	GLuint mDivisor;   // From glVertexAttribDivisor
+
+	union
+	{
+		const void *mPointer;
+		intptr_t mOffset;
+	};
+
+	gl::BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
+
+	bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
+
+private:
+	union ValueUnion
+	{
+		enum Type { FloatType, IntType, UIntType };
+
+		float f;
+		GLint i;
+		GLuint ui;
+	};
+
+	ValueUnion mCurrentValue[4];   // From glVertexAttrib
+	ValueUnion::Type mCurrentValueType;
+};
+
+typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
+
+// Helper structure to store all raw state
+struct State
+{
+	Color colorClearValue;
+	GLclampf depthClearValue;
+	int stencilClearValue;
+
+	bool cullFaceEnabled;
+	GLenum cullMode;
+	GLenum frontFace;
+	bool depthTestEnabled;
+	GLenum depthFunc;
+	bool blendEnabled;
+	GLenum sourceBlendRGB;
+	GLenum destBlendRGB;
+	GLenum sourceBlendAlpha;
+	GLenum destBlendAlpha;
+	GLenum blendEquationRGB;
+	GLenum blendEquationAlpha;
+	Color blendColor;
+	bool stencilTestEnabled;
+	GLenum stencilFunc;
+	GLint stencilRef;
+	GLuint stencilMask;
+	GLenum stencilFail;
+	GLenum stencilPassDepthFail;
+	GLenum stencilPassDepthPass;
+	GLuint stencilWritemask;
+	GLenum stencilBackFunc;
+	GLint stencilBackRef;
+	GLuint stencilBackMask;
+	GLenum stencilBackFail;
+	GLenum stencilBackPassDepthFail;
+	GLenum stencilBackPassDepthPass;
+	GLuint stencilBackWritemask;
+	bool polygonOffsetFillEnabled;
+	GLfloat polygonOffsetFactor;
+	GLfloat polygonOffsetUnits;
+	bool sampleAlphaToCoverageEnabled;
+	bool sampleCoverageEnabled;
+	GLclampf sampleCoverageValue;
+	bool sampleCoverageInvert;
+	bool scissorTestEnabled;
+	bool ditherEnabled;
+	bool primitiveRestartFixedIndexEnabled;
+	bool rasterizerDiscardEnabled;
+	bool colorLogicOpEnabled;
+	GLenum logicalOperation;
+
+	GLfloat lineWidth;
+
+	GLenum generateMipmapHint;
+	GLenum fragmentShaderDerivativeHint;
+
+	GLint viewportX;
+	GLint viewportY;
+	GLsizei viewportWidth;
+	GLsizei viewportHeight;
+	float zNear;
+	float zFar;
+
+	GLint scissorX;
+	GLint scissorY;
+	GLsizei scissorWidth;
+	GLsizei scissorHeight;
+
+	bool colorMaskRed;
+	bool colorMaskGreen;
+	bool colorMaskBlue;
+	bool colorMaskAlpha;
+	bool depthMask;
+
+	unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0
+	gl::BindingPointer<Buffer> arrayBuffer;
+	gl::BindingPointer<Buffer> copyReadBuffer;
+	gl::BindingPointer<Buffer> copyWriteBuffer;
+	gl::BindingPointer<Buffer> pixelPackBuffer;
+	gl::BindingPointer<Buffer> pixelUnpackBuffer;
+	gl::BindingPointer<Buffer> genericUniformBuffer;
+	BufferBinding uniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
+
+	GLuint readFramebuffer;
+	GLuint drawFramebuffer;
+	gl::BindingPointer<Renderbuffer> renderbuffer;
+	GLuint currentProgram;
+	GLuint vertexArray;
+	GLuint transformFeedback;
+	gl::BindingPointer<Sampler> sampler[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+
+	VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
+	gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+	gl::BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
+
+	egl::Image::UnpackInfo unpackInfo;
+	GLint packAlignment;
+	GLint packRowLength;
+	GLint packImageHeight;
+	GLint packSkipPixels;
+	GLint packSkipRows;
+	GLint packSkipImages;
+};
+
+class Context : public egl::Context
+{
+public:
+	Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion);
+
+	virtual void makeCurrent(egl::Surface *surface);
+	virtual EGLint getClientVersion() const;
+
+	void markAllStateDirty();
+
+	// State manipulation
+	void setClearColor(float red, float green, float blue, float alpha);
+	void setClearDepth(float depth);
+	void setClearStencil(int stencil);
+
+	void setCullFaceEnabled(bool enabled);
+	bool isCullFaceEnabled() const;
+	void setCullMode(GLenum mode);
+	void setFrontFace(GLenum front);
+
+	void setDepthTestEnabled(bool enabled);
+	bool isDepthTestEnabled() const;
+	void setDepthFunc(GLenum depthFunc);
+	void setDepthRange(float zNear, float zFar);
+
+	void setBlendEnabled(bool enabled);
+	bool isBlendEnabled() const;
+	void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
+	void setBlendColor(float red, float green, float blue, float alpha);
+	void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
+
+	void setStencilTestEnabled(bool enabled);
+	bool isStencilTestEnabled() const;
+	void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
+	void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
+	void setStencilWritemask(GLuint stencilWritemask);
+	void setStencilBackWritemask(GLuint stencilBackWritemask);
+	void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
+	void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);
+
+	void setPolygonOffsetFillEnabled(bool enabled);
+	bool isPolygonOffsetFillEnabled() const;
+	void setPolygonOffsetParams(GLfloat factor, GLfloat units);
+
+	void setSampleAlphaToCoverageEnabled(bool enabled);
+	bool isSampleAlphaToCoverageEnabled() const;
+	void setSampleCoverageEnabled(bool enabled);
+	bool isSampleCoverageEnabled() const;
+	void setSampleCoverageParams(GLclampf value, bool invert);
+
+	void setDitherEnabled(bool enabled);
+	bool isDitherEnabled() const;
+
+	void setPrimitiveRestartFixedIndexEnabled(bool enabled);
+	bool isPrimitiveRestartFixedIndexEnabled() const;
+
+	void setRasterizerDiscardEnabled(bool enabled);
+	bool isRasterizerDiscardEnabled() const;
+
+	void setLineWidth(GLfloat width);
+
+	void setGenerateMipmapHint(GLenum hint);
+	void setFragmentShaderDerivativeHint(GLenum hint);
+
+	void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setScissorTestEnabled(bool enabled);
+	bool isScissorTestEnabled() const;
+	void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setColorMask(bool red, bool green, bool blue, bool alpha);
+	unsigned int getColorMask() const;
+	void setDepthMask(bool mask);
+
+	void setActiveSampler(unsigned int active);
+
+	GLuint getReadFramebufferName() const;
+	GLuint getDrawFramebufferName() const;
+	GLuint getRenderbufferName() const;
+
+	void setFramebufferReadBuffer(GLenum buf);
+	void setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs);
+	GLuint getReadFramebufferColorIndex() const;
+
+	GLuint getActiveQuery(GLenum target) const;
+
+	GLuint getArrayBufferName() const;
+	GLuint getElementArrayBufferName() const;
+
+	void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);
+	void setVertexAttribDivisor(unsigned int attribNum, GLuint divisor);
+	const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
+	void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
+	                          bool normalized, GLsizei stride, const void *pointer);
+	const void *getVertexAttribPointer(unsigned int attribNum) const;
+
+	const VertexAttributeArray &getVertexArrayAttributes();
+	// Context attribute current values can be queried independently from VAO current values
+	const VertexAttributeArray &getCurrentVertexAttributes();
+
+	void setUnpackAlignment(GLint alignment);
+	void setUnpackRowLength(GLint rowLength);
+	void setUnpackImageHeight(GLint imageHeight);
+	void setUnpackSkipPixels(GLint skipPixels);
+	void setUnpackSkipRows(GLint skipRows);
+	void setUnpackSkipImages(GLint skipImages);
+	const egl::Image::UnpackInfo& getUnpackInfo() const;
+
+	void setPackAlignment(GLint alignment);
+	void setPackRowLength(GLint rowLength);
+	void setPackImageHeight(GLint imageHeight);
+	void setPackSkipPixels(GLint skipPixels);
+	void setPackSkipRows(GLint skipRows);
+	void setPackSkipImages(GLint skipImages);
+
+	// These create and destroy methods are merely pass-throughs to
+	// ResourceManager, which owns these object types
+	GLuint createBuffer();
+	GLuint createShader(GLenum type);
+	GLuint createProgram();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+	GLuint createSampler();
+	GLsync createFenceSync(GLenum condition, GLbitfield flags);
+
+	void deleteBuffer(GLuint buffer);
+	void deleteShader(GLuint shader);
+	void deleteProgram(GLuint program);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+	void deleteSampler(GLuint sampler);
+	void deleteFenceSync(GLsync fenceSync);
+
+	// Framebuffers are owned by the Context, so these methods do not pass through
+	GLuint createFramebuffer();
+	void deleteFramebuffer(GLuint framebuffer);
+
+	// Fences are owned by the Context
+	GLuint createFence();
+	void deleteFence(GLuint fence);
+
+	// Queries are owned by the Context
+	GLuint createQuery();
+	void deleteQuery(GLuint query);
+
+	// Vertex arrays are owned by the Context
+	GLuint createVertexArray();
+	void deleteVertexArray(GLuint array);
+
+	// Transform feedbacks are owned by the Context
+	GLuint createTransformFeedback();
+	void deleteTransformFeedback(GLuint transformFeedback);
+
+	void bindArrayBuffer(GLuint buffer);
+	void bindElementArrayBuffer(GLuint buffer);
+	void bindCopyReadBuffer(GLuint buffer);
+	void bindCopyWriteBuffer(GLuint buffer);
+	void bindPixelPackBuffer(GLuint buffer);
+	void bindPixelUnpackBuffer(GLuint buffer);
+	void bindTransformFeedbackBuffer(GLuint buffer);
+	void bindTexture2D(GLuint texture);
+	void bindTextureCubeMap(GLuint texture);
+	void bindTextureExternal(GLuint texture);
+	void bindTexture3D(GLuint texture);
+	void bindTexture2DArray(GLuint texture);
+	void bindReadFramebuffer(GLuint framebuffer);
+	void bindDrawFramebuffer(GLuint framebuffer);
+	void bindRenderbuffer(GLuint renderbuffer);
+	void bindVertexArray(GLuint array);
+	void bindGenericUniformBuffer(GLuint buffer);
+	void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
+	void bindGenericTransformFeedbackBuffer(GLuint buffer);
+	void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
+	void bindTransformFeedback(GLuint transformFeedback);
+	bool bindSampler(GLuint unit, GLuint sampler);
+	void useProgram(GLuint program);
+
+	void beginQuery(GLenum target, GLuint query);
+	void endQuery(GLenum target);
+
+	void setFramebufferZero(Framebuffer *framebuffer);
+
+	void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
+
+	void setVertexAttrib(GLuint index, const GLfloat *values);
+	void setVertexAttrib(GLuint index, const GLint *values);
+	void setVertexAttrib(GLuint index, const GLuint *values);
+
+	Buffer *getBuffer(GLuint handle) const;
+	Fence *getFence(GLuint handle) const;
+	FenceSync *getFenceSync(GLsync handle) const;
+	Shader *getShader(GLuint handle) const;
+	Program *getProgram(GLuint handle) const;
+	virtual Texture *getTexture(GLuint handle) const;
+	Framebuffer *getFramebuffer(GLuint handle) const;
+	virtual Renderbuffer *getRenderbuffer(GLuint handle) const;
+	Query *getQuery(GLuint handle) const;
+	VertexArray *getVertexArray(GLuint array) const;
+	VertexArray *getCurrentVertexArray() const;
+	bool isVertexArray(GLuint array) const;
+	TransformFeedback *getTransformFeedback(GLuint transformFeedback) const;
+	TransformFeedback *getTransformFeedback() const;
+	Sampler *getSampler(GLuint sampler) const;
+	bool isSampler(GLuint sampler) const;
+
+	Buffer *getArrayBuffer() const;
+	Buffer *getElementArrayBuffer() const;
+	Buffer *getCopyReadBuffer() const;
+	Buffer *getCopyWriteBuffer() const;
+	Buffer *getPixelPackBuffer() const;
+	Buffer *getPixelUnpackBuffer() const;
+	Buffer *getGenericUniformBuffer() const;
+	bool getBuffer(GLenum target, es2::Buffer **buffer) const;
+	Program *getCurrentProgram() const;
+	Texture2D *getTexture2D() const;
+	Texture3D *getTexture3D() const;
+	Texture2DArray *getTexture2DArray() const;
+	TextureCubeMap *getTextureCubeMap() const;
+	TextureExternal *getTextureExternal() const;
+	Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
+	Framebuffer *getReadFramebuffer() const;
+	Framebuffer *getDrawFramebuffer() const;
+
+	bool getFloatv(GLenum pname, GLfloat *params) const;
+	template<typename T> bool getIntegerv(GLenum pname, T *params) const;
+	bool getBooleanv(GLenum pname, GLboolean *params) const;
+	template<typename T> bool getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const;
+	template<typename T> bool getUniformBufferiv(GLuint index, GLenum pname, T *param) const;
+	void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
+	void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
+	GLint getSamplerParameteri(GLuint sampler, GLenum pname);
+	GLfloat getSamplerParameterf(GLuint sampler, GLenum pname);
+
+	bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const;
+
+	bool hasZeroDivisor() const;
+
+	void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
+	void clear(GLbitfield mask);
+	void clearColorBuffer(GLint drawbuffer, const GLint *value);
+	void clearColorBuffer(GLint drawbuffer, const GLuint *value);
+	void clearColorBuffer(GLint drawbuffer, const GLfloat *value);
+	void clearDepthBuffer(const GLfloat value);
+	void clearStencilBuffer(const GLint value);
+	void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount = 1);
+	void drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount = 1);
+	void finish();
+	void flush();
+
+	void recordInvalidEnum();
+	void recordInvalidValue();
+	void recordInvalidOperation();
+	void recordOutOfMemory();
+	void recordInvalidFramebufferOperation();
+
+	GLenum getError();
+
+	static int getSupportedMultisampleCount(int requested);
+
+	void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+	                     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+	                     GLbitfield mask);
+
+	virtual void bindTexImage(egl::Surface *surface);
+	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+	virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+
+	Device *getDevice();
+
+	const GLubyte* getExtensions(GLuint index, GLuint* numExt = nullptr) const;
+
+private:
+	virtual ~Context();
+
+	void applyScissor(int width, int height);
+	bool applyRenderTarget();
+	void applyState(GLenum drawMode);
+	GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId);
+	GLenum applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+	void applyShaders();
+	void applyTextures();
+	void applyTextures(sw::SamplerType type);
+	void applyTexture(sw::SamplerType type, int sampler, Texture *texture);
+	void clearColorBuffer(GLint drawbuffer, void *value, sw::Format format);
+
+	void detachBuffer(GLuint buffer);
+	void detachTexture(GLuint texture);
+	void detachFramebuffer(GLuint framebuffer);
+	void detachRenderbuffer(GLuint renderbuffer);
+	void detachSampler(GLuint sampler);
+
+	bool cullSkipsDraw(GLenum drawMode);
+	bool isTriangleMode(GLenum drawMode);
+
+	Query *createQuery(GLuint handle, GLenum type);
+
+	const EGLint clientVersion;
+	const egl::Config *const mConfig;
+
+	State mState;
+
+	gl::BindingPointer<Texture2D> mTexture2DZero;
+	gl::BindingPointer<Texture3D> mTexture3DZero;
+	gl::BindingPointer<Texture2DArray> mTexture2DArrayZero;
+	gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero;
+	gl::BindingPointer<TextureExternal> mTextureExternalZero;
+
+	gl::NameSpace<Framebuffer> mFramebufferNameSpace;
+	gl::NameSpace<Fence, 0> mFenceNameSpace;
+	gl::NameSpace<Query> mQueryNameSpace;
+	gl::NameSpace<VertexArray> mVertexArrayNameSpace;
+	gl::NameSpace<TransformFeedback> mTransformFeedbackNameSpace;
+
+	VertexDataManager *mVertexDataManager;
+	IndexDataManager *mIndexDataManager;
+
+	// Recorded errors
+	bool mInvalidEnum;
+	bool mInvalidValue;
+	bool mInvalidOperation;
+	bool mOutOfMemory;
+	bool mInvalidFramebufferOperation;
+
+	bool mHasBeenCurrent;
+
+	unsigned int mAppliedProgramSerial;
+
+	// state caching flags
+	bool mDepthStateDirty;
+	bool mMaskStateDirty;
+	bool mBlendStateDirty;
+	bool mStencilStateDirty;
+	bool mPolygonOffsetStateDirty;
+	bool mSampleStateDirty;
+	bool mFrontFaceDirty;
+	bool mDitherStateDirty;
+
+	Device *device;
+	ResourceManager *mResourceManager;
+};
+}
+
+#endif   // INCLUDE_CONTEXT_H_
diff --git a/src/OpenGL/libGLESv2/Device.cpp b/src/OpenGL/libGLESv2/Device.cpp
index 7da952b..f24f984 100644
--- a/src/OpenGL/libGLESv2/Device.cpp
+++ b/src/OpenGL/libGLESv2/Device.cpp
@@ -1,877 +1,880 @@
-// 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.

-//

-

-#include "Device.hpp"

-

-#include "common/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"

-

-namespace es2

-{

-	using namespace sw;

-

-	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)

-	{

-		for(int i = 0; i < RENDERTARGETS; i++)

-		{

-			renderTarget[i] = nullptr;

-		}

-

-		depthBuffer = nullptr;

-		stencilBuffer = nullptr;

-

-		setDepthBufferEnable(true);

-		setFillMode(FILL_SOLID);

-		setShadingMode(SHADING_GOURAUD);

-		setDepthWriteEnable(true);

-		setAlphaTestEnable(false);

-		setSourceBlendFactor(BLEND_ONE);

-		setDestBlendFactor(BLEND_ZERO);

-		setCullMode(CULL_COUNTERCLOCKWISE);

-		setDepthCompare(DEPTH_LESSEQUAL);

-		setAlphaReference(0.0f);

-		setAlphaCompare(ALPHA_ALWAYS);

-		setAlphaBlendEnable(false);

-		setFogEnable(false);

-		setSpecularEnable(false);

-		setFogColor(0);

-		setPixelFogMode(FOG_NONE);

-		setFogStart(0.0f);

-		setFogEnd(1.0f);

-		setFogDensity(1.0f);

-		setRangeFogEnable(false);

-		setStencilEnable(false);

-		setStencilFailOperation(OPERATION_KEEP);

-		setStencilZFailOperation(OPERATION_KEEP);

-		setStencilPassOperation(OPERATION_KEEP);

-		setStencilCompare(STENCIL_ALWAYS);

-		setStencilReference(0);

-		setStencilMask(0xFFFFFFFF);

-		setStencilWriteMask(0xFFFFFFFF);

-		setVertexFogMode(FOG_NONE);

-		setClipFlags(0);

-		setPointSize(1.0f);

-		setPointSizeMin(0.125f);

-        setPointSizeMax(8192.0f);

-		setBlendOperation(BLENDOP_ADD);

-		scissorEnable = false;

-		setSlopeDepthBias(0.0f);

-		setTwoSidedStencil(false);

-		setStencilFailOperationCCW(OPERATION_KEEP);

-		setStencilZFailOperationCCW(OPERATION_KEEP);

-		setStencilPassOperationCCW(OPERATION_KEEP);

-		setStencilCompareCCW(STENCIL_ALWAYS);

-		setBlendConstant(0xFFFFFFFF);

-		setWriteSRGB(false);

-		setDepthBias(0.0f);

-		setSeparateAlphaBlendEnable(false);

-		setSourceBlendFactorAlpha(BLEND_ONE);

-		setDestBlendFactorAlpha(BLEND_ZERO);

-		setBlendOperationAlpha(BLENDOP_ADD);

-		setPointSpriteEnable(true);

-		setColorLogicOpEnabled(false);

-		setLogicalOperation(LOGICALOP_COPY);

-

-		for(int i = 0; i < 16; i++)

-		{

-			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);

-			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);

-			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);

-			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);

-		}

-

-		for(int i = 0; i < 4; i++)

-		{

-			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);

-			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);

-			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);

-			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);

-		}

-

-		for(int i = 0; i < 6; i++)

-		{

-			float plane[4] = {0, 0, 0, 0};

-

-			setClipPlane(i, plane);

-		}

-

-		pixelShader = nullptr;

-		vertexShader = nullptr;

-

-		pixelShaderDirty = true;

-		pixelShaderConstantsFDirty = 0;

-		vertexShaderDirty = true;

-		vertexShaderConstantsFDirty = 0;

-

-		for(int i = 0; i < FRAGMENT_UNIFORM_VECTORS; i++)

-		{

-			float zero[4] = {0, 0, 0, 0};

-

-			setPixelShaderConstantF(i, zero, 1);

-		}

-

-		for(int i = 0; i < VERTEX_UNIFORM_VECTORS; i++)

-		{

-			float zero[4] = {0, 0, 0, 0};

-

-			setVertexShaderConstantF(i, zero, 1);

-		}

-	}

-

-	Device::~Device()

-	{

-		for(int i = 0; i < RENDERTARGETS; i++)

-		{

-			if(renderTarget[i])

-			{

-				renderTarget[i]->release();

-				renderTarget[i] = nullptr;

-			}

-		}

-

-		if(depthBuffer)

-		{

-			depthBuffer->release();

-			depthBuffer = nullptr;

-		}

-

-		if(stencilBuffer)

-		{

-			stencilBuffer->release();

-			stencilBuffer = nullptr;

-		}

-

-		delete context;

-	}

-

-	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)

-	{

-		if(!rgbaMask)

-		{

-			return;

-		}

-

-		float rgba[4];

-		rgba[0] = red;

-		rgba[1] = green;

-		rgba[2] = blue;

-		rgba[3] = alpha;

-

-		for(int i = 0; i < RENDERTARGETS; ++i)

-		{

-			if(renderTarget[i])

-			{

-				sw::SliceRect clearRect = renderTarget[i]->getRect();

-

-				if(scissorEnable)

-				{

-					clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-				}

-

-				int depth = sw::max(renderTarget[i]->getDepth(), 1);

-				for(clearRect.slice = 0; clearRect.slice < depth; clearRect.slice++)

-				{

-					clear(rgba, FORMAT_A32B32G32R32F, renderTarget[i], clearRect, rgbaMask);

-				}

-			}

-		}

-	}

-

-	void Device::clearDepth(float z)

-	{

-		if(!depthBuffer)

-		{

-			return;

-		}

-

-		z = clamp01(z);

-		sw::SliceRect clearRect = depthBuffer->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	void Device::clearStencil(unsigned int stencil, unsigned int mask)

-	{

-		if(!stencilBuffer)

-		{

-			return;

-		}

-

-		sw::SliceRect clearRect = stencilBuffer->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return nullptr;

-		}

-

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

-		case FORMAT_D32F:

-		case FORMAT_D32F_COMPLEMENTARY:

-			lockable = false;

-			break;

-	//	case FORMAT_S8_LOCKABLE:

-	//	case FORMAT_D16_LOCKABLE:

-		case FORMAT_D32F_LOCKABLE:

-	//	case FORMAT_D32_LOCKABLE:

-		case FORMAT_DF24S8:

-		case FORMAT_DF16S8:

-		case FORMAT_D32FS8_TEXTURE:

-		case FORMAT_D32FS8_SHADOW:

-			lockable = true;

-			break;

-		default:

-			UNREACHABLE(format);

-		}

-

-		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return nullptr;

-		}

-

-		return surface;

-	}

-

-	egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return nullptr;

-		}

-

-		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return nullptr;

-		}

-

-		return surface;

-	}

-

-	void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		draw(type, indexOffset, primitiveCount);

-	}

-

-	void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		setIndexBuffer(nullptr);

-

-		draw(type, 0, primitiveCount);

-	}

-

-	void Device::setPixelShader(PixelShader *pixelShader)

-	{

-		this->pixelShader = pixelShader;

-		pixelShaderDirty = true;

-	}

-

-	void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)

-	{

-		for(unsigned int i = 0; i < count && startRegister + i < FRAGMENT_UNIFORM_VECTORS; i++)

-		{

-			pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];

-			pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];

-			pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];

-			pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];

-		}

-

-		pixelShaderConstantsFDirty = max(startRegister + count, pixelShaderConstantsFDirty);

-		pixelShaderDirty = true;   // Reload DEF constants

-	}

-

-	void Device::setScissorEnable(bool enable)

-	{

-		scissorEnable = enable;

-	}

-

-	void Device::setRenderTarget(int index, egl::Image *renderTarget)

-	{

-		if(renderTarget)

-		{

-			renderTarget->addRef();

-		}

-

-		if(this->renderTarget[index])

-		{

-			this->renderTarget[index]->release();

-		}

-

-		this->renderTarget[index] = renderTarget;

-

-		Renderer::setRenderTarget(index, renderTarget);

-	}

-

-	void Device::setDepthBuffer(egl::Image *depthBuffer)

-	{

-		if(this->depthBuffer == depthBuffer)

-		{

-			return;

-		}

-

-		if(depthBuffer)

-		{

-			depthBuffer->addRef();

-		}

-

-		if(this->depthBuffer)

-		{

-			this->depthBuffer->release();

-		}

-

-		this->depthBuffer = depthBuffer;

-

-		Renderer::setDepthBuffer(depthBuffer);

-	}

-

-	void Device::setStencilBuffer(egl::Image *stencilBuffer)

-	{

-		if(this->stencilBuffer == stencilBuffer)

-		{

-			return;

-		}

-

-		if(stencilBuffer)

-		{

-			stencilBuffer->addRef();

-		}

-

-		if(this->stencilBuffer)

-		{

-			this->stencilBuffer->release();

-		}

-

-		this->stencilBuffer = stencilBuffer;

-

-		Renderer::setStencilBuffer(stencilBuffer);

-	}

-

-	void Device::setScissorRect(const sw::Rect &rect)

-	{

-		scissorRect = rect;

-	}

-

-	void Device::setVertexShader(VertexShader *vertexShader)

-	{

-		this->vertexShader = vertexShader;

-		vertexShaderDirty = true;

-	}

-

-	void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)

-	{

-		for(unsigned int i = 0; i < count && startRegister + i < VERTEX_UNIFORM_VECTORS; i++)

-		{

-			vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];

-			vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];

-			vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];

-			vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];

-		}

-

-		vertexShaderConstantsFDirty = max(startRegister + count, vertexShaderConstantsFDirty);

-		vertexShaderDirty = true;   // Reload DEF constants

-	}

-

-	void Device::setViewport(const Viewport &viewport)

-	{

-		this->viewport = viewport;

-	}

-

-	void Device::copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY)

-	{

-		unsigned int widthB = width * bytes;

-		unsigned int widthMaxB = widthB - 1;

-

-		if(flipX)

-		{

-			if(flipY)

-			{

-				sourceBuffer += (height - 1) * sourcePitch;

-				for(unsigned int y = 0; y < height; ++y, sourceBuffer -= sourcePitch, destBuffer += destPitch)

-				{

-					for(unsigned int x = 0; x < widthB; ++x)

-					{

-						destBuffer[x] = sourceBuffer[widthMaxB - x];

-					}

-				}

-			}

-			else

-			{

-				for(unsigned int y = 0; y < height; ++y, sourceBuffer += sourcePitch, destBuffer += destPitch)

-				{

-					for(unsigned int x = 0; x < widthB; ++x)

-					{

-						destBuffer[x] = sourceBuffer[widthMaxB - x];

-					}

-				}

-			}

-		}

-		else

-		{

-			if(flipY)

-			{

-				sourceBuffer += (height - 1) * sourcePitch;

-				for(unsigned int y = 0; y < height; ++y, sourceBuffer -= sourcePitch, destBuffer += destPitch)

-				{

-					memcpy(destBuffer, sourceBuffer, widthB);

-				}

-			}

-			else

-			{

-				for(unsigned int y = 0; y < height; ++y, sourceBuffer += sourcePitch, destBuffer += destPitch)

-				{

-					memcpy(destBuffer, sourceBuffer, widthB);

-				}

-			}

-		}

-	}

-

-	bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter)

-	{

-		if(!source || !dest)

-		{

-			ERR("Invalid parameters");

-			return false;

-		}

-

-		int sWidth = source->getWidth();

-		int sHeight = source->getHeight();

-		int dWidth = dest->getWidth();

-		int dHeight = dest->getHeight();

-

-		bool flipX = false;

-		bool flipY = false;

-		if(sourceRect && destRect)

-		{

-			flipX = (sourceRect->x0 < sourceRect->x1) ^ (destRect->x0 < destRect->x1);

-			flipY = (sourceRect->y0 < sourceRect->y1) ^ (destRect->y0 < destRect->y1);

-		}

-		else if(sourceRect)

-		{

-			flipX = (sourceRect->x0 > sourceRect->x1);

-			flipY = (sourceRect->y0 > sourceRect->y1);

-		}

-		else if(destRect)

-		{

-			flipX = (destRect->x0 > destRect->x1);

-			flipY = (destRect->y0 > destRect->y1);

-		}

-

-		SliceRect sRect;

-		SliceRect dRect;

-

-		if(sourceRect)

-		{

-			sRect = *sourceRect;

-

-			if(sRect.x0 > sRect.x1)

-			{

-				swap(sRect.x0, sRect.x1);

-			}

-

-			if(sRect.y0 > sRect.y1)

-			{

-				swap(sRect.y0, sRect.y1);

-			}

-		}

-		else

-		{

-			sRect.y0 = 0;

-			sRect.x0 = 0;

-			sRect.y1 = sHeight;

-			sRect.x1 = sWidth;

-		}

-

-		if(destRect)

-		{

-			dRect = *destRect;

-

-			if(dRect.x0 > dRect.x1)

-			{

-				swap(dRect.x0, dRect.x1);

-			}

-

-			if(dRect.y0 > dRect.y1)

-			{

-				swap(dRect.y0, dRect.y1);

-			}

-		}

-		else

-		{

-			dRect.y0 = 0;

-			dRect.x0 = 0;

-			dRect.y1 = dHeight;

-			dRect.x1 = dWidth;

-		}

-

-		if(!validRectangle(&sRect, source) || !validRectangle(&dRect, dest))

-		{

-			ERR("Invalid parameters");

-			return false;

-		}

-

-		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);

-		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();

-		bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::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, sourceRect->slice, LOCK_READONLY, PUBLIC);

-				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, destRect->slice, LOCK_DISCARD, PUBLIC);

-

-				copyBuffer(sourceBuffer, destBuffer, source->getWidth(), source->getHeight(), source->getInternalPitchB(), dest->getInternalPitchB(), egl::Image::bytes(source->getInternalFormat()), flipX, flipY);

-

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

-

-				copyBuffer(sourceBuffer, destBuffer, source->getWidth(), source->getHeight(), source->getInternalPitchB(), dest->getInternalPitchB(), egl::Image::bytes(source->getInternalFormat()), flipX, flipY);

-

-				source->unlockStencil();

-				dest->unlockStencil();

-			}

-		}

-		else if(!scaling && equalFormats)

-		{

-			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sourceRect->slice, LOCK_READONLY, PUBLIC);

-			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, destRect->slice, LOCK_READWRITE, PUBLIC);

-			unsigned int sourcePitch = source->getInternalPitchB();

-			unsigned int destPitch = dest->getInternalPitchB();

-

-			unsigned int width = dRect.x1 - dRect.x0;

-			unsigned int height = dRect.y1 - dRect.y0;

-

-			copyBuffer(sourceBytes, destBytes, width, height, sourcePitch, destPitch, egl::Image::bytes(source->getInternalFormat()), flipX, flipY);

-

-			if(alpha0xFF)

-			{

-				for(unsigned int y = 0; y < height; ++y, destBytes += destPitch)

-				{

-					for(unsigned int x = 0; x < width; ++x)

-					{

-						destBytes[4 * x + 3] = 0xFF;

-					}

-				}

-			}

-

-			source->unlockInternal();

-			dest->unlockInternal();

-		}

-		else

-		{

-			if(flipX)

-			{

-				swap(dRect.x0, dRect.x1);

-			}

-			if(flipY)

-			{

-				swap(dRect.y0, dRect.y1);

-			}

-			blit(source, sRect, dest, dRect, scaling && filter);

-		}

-

-		return true;

-	}

-

-	bool Device::stretchCube(sw::Surface *source, sw::Surface *dest)

-	{

-		if(!source || !dest || egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat()))

-		{

-			ERR("Invalid parameters");

-			return false;

-		}

-

-		int sWidth  = source->getWidth();

-		int sHeight = source->getHeight();

-		int sDepth  = source->getDepth();

-		int dWidth  = dest->getWidth();

-		int dHeight = dest->getHeight();

-		int dDepth  = dest->getDepth();

-

-		bool scaling = (sWidth != dWidth) || (sHeight != dHeight) || (sDepth != dDepth);

-		bool equalFormats = source->getInternalFormat() == dest->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(!scaling && equalFormats)

-		{

-			unsigned int sourcePitch = source->getInternalPitchB();

-			unsigned int destPitch = dest->getInternalPitchB();

-			unsigned int bytes = dWidth * egl::Image::bytes(source->getInternalFormat());

-

-			for(int z = 0; z < dDepth; ++z)

-			{

-				unsigned char *sourceBytes = (unsigned char*)source->lockInternal(0, 0, z, LOCK_READONLY, PUBLIC);

-				unsigned char *destBytes = (unsigned char*)dest->lockInternal(0, 0, z, LOCK_READWRITE, PUBLIC);

-				for(int y = 0; y < dHeight; ++y)

-				{

-					memcpy(destBytes, sourceBytes, bytes);

-

-					if(alpha0xFF)

-					{

-						for(int x = 0; x < dWidth; ++x)

-						{

-							destBytes[4 * x + 3] = 0xFF;

-						}

-					}

-

-					sourceBytes += sourcePitch;

-					destBytes += destPitch;

-				}

-			}

-

-			source->unlockInternal();

-			dest->unlockInternal();

-		}

-		else

-		{

-			blit3D(source, dest);

-		}

-

-		return true;

-	}

-

-	bool Device::bindResources()

-	{

-		if(!bindViewport())

-		{

-			return false;   // Zero-area target region

-		}

-

-		bindShaderConstants();

-

-		return true;

-	}

-

-	void Device::bindShaderConstants()

-	{

-		if(pixelShaderDirty)

-		{

-			if(pixelShader)

-			{

-				if(pixelShaderConstantsFDirty)

-				{

-					Renderer::setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);

-				}

-

-				Renderer::setPixelShader(pixelShader);   // Loads shader constants set with DEF

-				pixelShaderConstantsFDirty = pixelShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty

-			}

-			else

-			{

-				setPixelShader(0);

-			}

-

-			pixelShaderDirty = false;

-		}

-

-		if(vertexShaderDirty)

-		{

-			if(vertexShader)

-			{

-				if(vertexShaderConstantsFDirty)

-				{

-					Renderer::setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);

-				}

-

-				Renderer::setVertexShader(vertexShader);   // Loads shader constants set with DEF

-				vertexShaderConstantsFDirty = vertexShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty

-			}

-			else

-			{

-				setVertexShader(0);

-			}

-

-			vertexShaderDirty = false;

-		}

-	}

-

-	bool Device::bindViewport()

-	{

-		if(viewport.width <= 0 || viewport.height <= 0)

-		{

-			return false;

-		}

-

-		if(scissorEnable)

-		{

-			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)

-			{

-				return false;

-			}

-

-			sw::Rect scissor;

-			scissor.x0 = scissorRect.x0;

-			scissor.x1 = scissorRect.x1;

-			scissor.y0 = scissorRect.y0;

-			scissor.y1 = scissorRect.y1;

-

-			setScissor(scissor);

-		}

-		else

-		{

-			sw::Rect scissor;

-			scissor.x0 = viewport.x0;

-			scissor.x1 = viewport.x0 + viewport.width;

-			scissor.y0 = viewport.y0;

-			scissor.y1 = viewport.y0 + viewport.height;

-

-			for(int i = 0; i < RENDERTARGETS; ++i)

-			{

-				if(renderTarget[i])

-				{

-					scissor.x0 = max(scissor.x0, 0);

-					scissor.x1 = min(scissor.x1, renderTarget[i]->getWidth());

-					scissor.y0 = max(scissor.y0, 0);

-					scissor.y1 = min(scissor.y1, renderTarget[i]->getHeight());

-				}

-			}

-

-			if(depthBuffer)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, depthBuffer->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, depthBuffer->getHeight());

-			}

-

-			if(stencilBuffer)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, stencilBuffer->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, stencilBuffer->getHeight());

-			}

-

-			setScissor(scissor);

-		}

-

-		sw::Viewport view;

-		view.x0 = (float)viewport.x0;

-		view.y0 = (float)viewport.y0;

-		view.width = (float)viewport.width;

-		view.height = (float)viewport.height;

-		view.minZ = viewport.minZ;

-		view.maxZ = viewport.maxZ;

-

-		Renderer::setViewport(view);

-

-		return true;

-	}

-

-	bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface)

-	{

-		if(!rect)

-		{

-			return true;

-		}

-

-		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)

-		{

-			return false;

-		}

-

-		if(rect->x0 < 0 || rect->y0 < 0)

-		{

-			return false;

-		}

-

-		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	void Device::finish()

-	{

-		synchronize();

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Device.hpp"
+
+#include "common/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"
+
+namespace es2
+{
+	using namespace sw;
+
+	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)
+	{
+		for(int i = 0; i < RENDERTARGETS; i++)
+		{
+			renderTarget[i] = nullptr;
+		}
+
+		depthBuffer = nullptr;
+		stencilBuffer = nullptr;
+
+		setDepthBufferEnable(true);
+		setFillMode(FILL_SOLID);
+		setShadingMode(SHADING_GOURAUD);
+		setDepthWriteEnable(true);
+		setAlphaTestEnable(false);
+		setSourceBlendFactor(BLEND_ONE);
+		setDestBlendFactor(BLEND_ZERO);
+		setCullMode(CULL_COUNTERCLOCKWISE);
+		setDepthCompare(DEPTH_LESSEQUAL);
+		setAlphaReference(0.0f);
+		setAlphaCompare(ALPHA_ALWAYS);
+		setAlphaBlendEnable(false);
+		setFogEnable(false);
+		setSpecularEnable(false);
+		setFogColor(0);
+		setPixelFogMode(FOG_NONE);
+		setFogStart(0.0f);
+		setFogEnd(1.0f);
+		setFogDensity(1.0f);
+		setRangeFogEnable(false);
+		setStencilEnable(false);
+		setStencilFailOperation(OPERATION_KEEP);
+		setStencilZFailOperation(OPERATION_KEEP);
+		setStencilPassOperation(OPERATION_KEEP);
+		setStencilCompare(STENCIL_ALWAYS);
+		setStencilReference(0);
+		setStencilMask(0xFFFFFFFF);
+		setStencilWriteMask(0xFFFFFFFF);
+		setVertexFogMode(FOG_NONE);
+		setClipFlags(0);
+		setPointSize(1.0f);
+		setPointSizeMin(0.125f);
+        setPointSizeMax(8192.0f);
+		setBlendOperation(BLENDOP_ADD);
+		scissorEnable = false;
+		setSlopeDepthBias(0.0f);
+		setTwoSidedStencil(false);
+		setStencilFailOperationCCW(OPERATION_KEEP);
+		setStencilZFailOperationCCW(OPERATION_KEEP);
+		setStencilPassOperationCCW(OPERATION_KEEP);
+		setStencilCompareCCW(STENCIL_ALWAYS);
+		setBlendConstant(0xFFFFFFFF);
+		setWriteSRGB(false);
+		setDepthBias(0.0f);
+		setSeparateAlphaBlendEnable(false);
+		setSourceBlendFactorAlpha(BLEND_ONE);
+		setDestBlendFactorAlpha(BLEND_ZERO);
+		setBlendOperationAlpha(BLENDOP_ADD);
+		setPointSpriteEnable(true);
+		setColorLogicOpEnabled(false);
+		setLogicalOperation(LOGICALOP_COPY);
+
+		for(int i = 0; i < 16; i++)
+		{
+			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);
+			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);
+			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);
+			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);
+		}
+
+		for(int i = 0; i < 4; i++)
+		{
+			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);
+			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);
+			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);
+			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);
+		}
+
+		for(int i = 0; i < 6; i++)
+		{
+			float plane[4] = {0, 0, 0, 0};
+
+			setClipPlane(i, plane);
+		}
+
+		pixelShader = nullptr;
+		vertexShader = nullptr;
+
+		pixelShaderDirty = true;
+		pixelShaderConstantsFDirty = 0;
+		vertexShaderDirty = true;
+		vertexShaderConstantsFDirty = 0;
+
+		for(int i = 0; i < FRAGMENT_UNIFORM_VECTORS; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			setPixelShaderConstantF(i, zero, 1);
+		}
+
+		for(int i = 0; i < VERTEX_UNIFORM_VECTORS; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			setVertexShaderConstantF(i, zero, 1);
+		}
+	}
+
+	Device::~Device()
+	{
+		for(int i = 0; i < RENDERTARGETS; i++)
+		{
+			if(renderTarget[i])
+			{
+				renderTarget[i]->release();
+				renderTarget[i] = nullptr;
+			}
+		}
+
+		if(depthBuffer)
+		{
+			depthBuffer->release();
+			depthBuffer = nullptr;
+		}
+
+		if(stencilBuffer)
+		{
+			stencilBuffer->release();
+			stencilBuffer = nullptr;
+		}
+
+		delete context;
+	}
+
+	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
+	{
+		if(!rgbaMask)
+		{
+			return;
+		}
+
+		float rgba[4];
+		rgba[0] = red;
+		rgba[1] = green;
+		rgba[2] = blue;
+		rgba[3] = alpha;
+
+		for(int i = 0; i < RENDERTARGETS; ++i)
+		{
+			if(renderTarget[i])
+			{
+				sw::SliceRect clearRect = renderTarget[i]->getRect();
+
+				if(scissorEnable)
+				{
+					clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+				}
+
+				int depth = sw::max(renderTarget[i]->getDepth(), 1);
+				for(clearRect.slice = 0; clearRect.slice < depth; clearRect.slice++)
+				{
+					clear(rgba, FORMAT_A32B32G32R32F, renderTarget[i], clearRect, rgbaMask);
+				}
+			}
+		}
+	}
+
+	void Device::clearDepth(float z)
+	{
+		if(!depthBuffer)
+		{
+			return;
+		}
+
+		z = clamp01(z);
+		sw::SliceRect clearRect = depthBuffer->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	void Device::clearStencil(unsigned int stencil, unsigned int mask)
+	{
+		if(!stencilBuffer)
+		{
+			return;
+		}
+
+		sw::SliceRect clearRect = stencilBuffer->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return nullptr;
+		}
+
+		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:
+		case FORMAT_D32F:
+		case FORMAT_D32F_COMPLEMENTARY:
+			lockable = false;
+			break;
+	//	case FORMAT_S8_LOCKABLE:
+	//	case FORMAT_D16_LOCKABLE:
+		case FORMAT_D32F_LOCKABLE:
+	//	case FORMAT_D32_LOCKABLE:
+		case FORMAT_DF24S8:
+		case FORMAT_DF16S8:
+		case FORMAT_D32FS8_TEXTURE:
+		case FORMAT_D32FS8_SHADOW:
+			lockable = true;
+			break;
+		default:
+			UNREACHABLE(format);
+		}
+
+		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return nullptr;
+		}
+
+		return surface;
+	}
+
+	egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return nullptr;
+		}
+
+		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return nullptr;
+		}
+
+		return surface;
+	}
+
+	void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		draw(type, indexOffset, primitiveCount);
+	}
+
+	void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		setIndexBuffer(nullptr);
+
+		draw(type, 0, primitiveCount);
+	}
+
+	void Device::setPixelShader(PixelShader *pixelShader)
+	{
+		this->pixelShader = pixelShader;
+		pixelShaderDirty = true;
+	}
+
+	void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		for(unsigned int i = 0; i < count && startRegister + i < FRAGMENT_UNIFORM_VECTORS; i++)
+		{
+			pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
+			pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
+			pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
+			pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
+		}
+
+		pixelShaderConstantsFDirty = max(startRegister + count, pixelShaderConstantsFDirty);
+		pixelShaderDirty = true;   // Reload DEF constants
+	}
+
+	void Device::setScissorEnable(bool enable)
+	{
+		scissorEnable = enable;
+	}
+
+	void Device::setRenderTarget(int index, egl::Image *renderTarget)
+	{
+		if(renderTarget)
+		{
+			renderTarget->addRef();
+		}
+
+		if(this->renderTarget[index])
+		{
+			this->renderTarget[index]->release();
+		}
+
+		this->renderTarget[index] = renderTarget;
+
+		Renderer::setRenderTarget(index, renderTarget);
+	}
+
+	void Device::setDepthBuffer(egl::Image *depthBuffer)
+	{
+		if(this->depthBuffer == depthBuffer)
+		{
+			return;
+		}
+
+		if(depthBuffer)
+		{
+			depthBuffer->addRef();
+		}
+
+		if(this->depthBuffer)
+		{
+			this->depthBuffer->release();
+		}
+
+		this->depthBuffer = depthBuffer;
+
+		Renderer::setDepthBuffer(depthBuffer);
+	}
+
+	void Device::setStencilBuffer(egl::Image *stencilBuffer)
+	{
+		if(this->stencilBuffer == stencilBuffer)
+		{
+			return;
+		}
+
+		if(stencilBuffer)
+		{
+			stencilBuffer->addRef();
+		}
+
+		if(this->stencilBuffer)
+		{
+			this->stencilBuffer->release();
+		}
+
+		this->stencilBuffer = stencilBuffer;
+
+		Renderer::setStencilBuffer(stencilBuffer);
+	}
+
+	void Device::setScissorRect(const sw::Rect &rect)
+	{
+		scissorRect = rect;
+	}
+
+	void Device::setVertexShader(VertexShader *vertexShader)
+	{
+		this->vertexShader = vertexShader;
+		vertexShaderDirty = true;
+	}
+
+	void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		for(unsigned int i = 0; i < count && startRegister + i < VERTEX_UNIFORM_VECTORS; i++)
+		{
+			vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
+			vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
+			vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
+			vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
+		}
+
+		vertexShaderConstantsFDirty = max(startRegister + count, vertexShaderConstantsFDirty);
+		vertexShaderDirty = true;   // Reload DEF constants
+	}
+
+	void Device::setViewport(const Viewport &viewport)
+	{
+		this->viewport = viewport;
+	}
+
+	void Device::copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY)
+	{
+		unsigned int widthB = width * bytes;
+		unsigned int widthMaxB = widthB - 1;
+
+		if(flipX)
+		{
+			if(flipY)
+			{
+				sourceBuffer += (height - 1) * sourcePitch;
+				for(unsigned int y = 0; y < height; ++y, sourceBuffer -= sourcePitch, destBuffer += destPitch)
+				{
+					for(unsigned int x = 0; x < widthB; ++x)
+					{
+						destBuffer[x] = sourceBuffer[widthMaxB - x];
+					}
+				}
+			}
+			else
+			{
+				for(unsigned int y = 0; y < height; ++y, sourceBuffer += sourcePitch, destBuffer += destPitch)
+				{
+					for(unsigned int x = 0; x < widthB; ++x)
+					{
+						destBuffer[x] = sourceBuffer[widthMaxB - x];
+					}
+				}
+			}
+		}
+		else
+		{
+			if(flipY)
+			{
+				sourceBuffer += (height - 1) * sourcePitch;
+				for(unsigned int y = 0; y < height; ++y, sourceBuffer -= sourcePitch, destBuffer += destPitch)
+				{
+					memcpy(destBuffer, sourceBuffer, widthB);
+				}
+			}
+			else
+			{
+				for(unsigned int y = 0; y < height; ++y, sourceBuffer += sourcePitch, destBuffer += destPitch)
+				{
+					memcpy(destBuffer, sourceBuffer, widthB);
+				}
+			}
+		}
+	}
+
+	bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter)
+	{
+		if(!source || !dest)
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		int sWidth = source->getWidth();
+		int sHeight = source->getHeight();
+		int dWidth = dest->getWidth();
+		int dHeight = dest->getHeight();
+
+		bool flipX = false;
+		bool flipY = false;
+		if(sourceRect && destRect)
+		{
+			flipX = (sourceRect->x0 < sourceRect->x1) ^ (destRect->x0 < destRect->x1);
+			flipY = (sourceRect->y0 < sourceRect->y1) ^ (destRect->y0 < destRect->y1);
+		}
+		else if(sourceRect)
+		{
+			flipX = (sourceRect->x0 > sourceRect->x1);
+			flipY = (sourceRect->y0 > sourceRect->y1);
+		}
+		else if(destRect)
+		{
+			flipX = (destRect->x0 > destRect->x1);
+			flipY = (destRect->y0 > destRect->y1);
+		}
+
+		SliceRect sRect;
+		SliceRect dRect;
+
+		if(sourceRect)
+		{
+			sRect = *sourceRect;
+
+			if(sRect.x0 > sRect.x1)
+			{
+				swap(sRect.x0, sRect.x1);
+			}
+
+			if(sRect.y0 > sRect.y1)
+			{
+				swap(sRect.y0, sRect.y1);
+			}
+		}
+		else
+		{
+			sRect.y0 = 0;
+			sRect.x0 = 0;
+			sRect.y1 = sHeight;
+			sRect.x1 = sWidth;
+		}
+
+		if(destRect)
+		{
+			dRect = *destRect;
+
+			if(dRect.x0 > dRect.x1)
+			{
+				swap(dRect.x0, dRect.x1);
+			}
+
+			if(dRect.y0 > dRect.y1)
+			{
+				swap(dRect.y0, dRect.y1);
+			}
+		}
+		else
+		{
+			dRect.y0 = 0;
+			dRect.x0 = 0;
+			dRect.y1 = dHeight;
+			dRect.x1 = dWidth;
+		}
+
+		if(!validRectangle(&sRect, source) || !validRectangle(&dRect, dest))
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
+		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
+		bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::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, sourceRect->slice, LOCK_READONLY, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, destRect->slice, LOCK_DISCARD, PUBLIC);
+
+				copyBuffer(sourceBuffer, destBuffer, source->getWidth(), source->getHeight(), source->getInternalPitchB(), dest->getInternalPitchB(), egl::Image::bytes(source->getInternalFormat()), flipX, flipY);
+
+				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);
+
+				copyBuffer(sourceBuffer, destBuffer, source->getWidth(), source->getHeight(), source->getInternalPitchB(), dest->getInternalPitchB(), egl::Image::bytes(source->getInternalFormat()), flipX, flipY);
+
+				source->unlockStencil();
+				dest->unlockStencil();
+			}
+		}
+		else if(!scaling && equalFormats)
+		{
+			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sourceRect->slice, LOCK_READONLY, PUBLIC);
+			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, destRect->slice, LOCK_READWRITE, PUBLIC);
+			unsigned int sourcePitch = source->getInternalPitchB();
+			unsigned int destPitch = dest->getInternalPitchB();
+
+			unsigned int width = dRect.x1 - dRect.x0;
+			unsigned int height = dRect.y1 - dRect.y0;
+
+			copyBuffer(sourceBytes, destBytes, width, height, sourcePitch, destPitch, egl::Image::bytes(source->getInternalFormat()), flipX, flipY);
+
+			if(alpha0xFF)
+			{
+				for(unsigned int y = 0; y < height; ++y, destBytes += destPitch)
+				{
+					for(unsigned int x = 0; x < width; ++x)
+					{
+						destBytes[4 * x + 3] = 0xFF;
+					}
+				}
+			}
+
+			source->unlockInternal();
+			dest->unlockInternal();
+		}
+		else
+		{
+			if(flipX)
+			{
+				swap(dRect.x0, dRect.x1);
+			}
+			if(flipY)
+			{
+				swap(dRect.y0, dRect.y1);
+			}
+			blit(source, sRect, dest, dRect, scaling && filter);
+		}
+
+		return true;
+	}
+
+	bool Device::stretchCube(sw::Surface *source, sw::Surface *dest)
+	{
+		if(!source || !dest || egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat()))
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		int sWidth  = source->getWidth();
+		int sHeight = source->getHeight();
+		int sDepth  = source->getDepth();
+		int dWidth  = dest->getWidth();
+		int dHeight = dest->getHeight();
+		int dDepth  = dest->getDepth();
+
+		bool scaling = (sWidth != dWidth) || (sHeight != dHeight) || (sDepth != dDepth);
+		bool equalFormats = source->getInternalFormat() == dest->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(!scaling && equalFormats)
+		{
+			unsigned int sourcePitch = source->getInternalPitchB();
+			unsigned int destPitch = dest->getInternalPitchB();
+			unsigned int bytes = dWidth * egl::Image::bytes(source->getInternalFormat());
+
+			for(int z = 0; z < dDepth; ++z)
+			{
+				unsigned char *sourceBytes = (unsigned char*)source->lockInternal(0, 0, z, LOCK_READONLY, PUBLIC);
+				unsigned char *destBytes = (unsigned char*)dest->lockInternal(0, 0, z, LOCK_READWRITE, PUBLIC);
+				for(int y = 0; y < dHeight; ++y)
+				{
+					memcpy(destBytes, sourceBytes, bytes);
+
+					if(alpha0xFF)
+					{
+						for(int x = 0; x < dWidth; ++x)
+						{
+							destBytes[4 * x + 3] = 0xFF;
+						}
+					}
+
+					sourceBytes += sourcePitch;
+					destBytes += destPitch;
+				}
+			}
+
+			source->unlockInternal();
+			dest->unlockInternal();
+		}
+		else
+		{
+			blit3D(source, dest);
+		}
+
+		return true;
+	}
+
+	bool Device::bindResources()
+	{
+		if(!bindViewport())
+		{
+			return false;   // Zero-area target region
+		}
+
+		bindShaderConstants();
+
+		return true;
+	}
+
+	void Device::bindShaderConstants()
+	{
+		if(pixelShaderDirty)
+		{
+			if(pixelShader)
+			{
+				if(pixelShaderConstantsFDirty)
+				{
+					Renderer::setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
+				}
+
+				Renderer::setPixelShader(pixelShader);   // Loads shader constants set with DEF
+				pixelShaderConstantsFDirty = pixelShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty
+			}
+			else
+			{
+				setPixelShader(0);
+			}
+
+			pixelShaderDirty = false;
+		}
+
+		if(vertexShaderDirty)
+		{
+			if(vertexShader)
+			{
+				if(vertexShaderConstantsFDirty)
+				{
+					Renderer::setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
+				}
+
+				Renderer::setVertexShader(vertexShader);   // Loads shader constants set with DEF
+				vertexShaderConstantsFDirty = vertexShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty
+			}
+			else
+			{
+				setVertexShader(0);
+			}
+
+			vertexShaderDirty = false;
+		}
+	}
+
+	bool Device::bindViewport()
+	{
+		if(viewport.width <= 0 || viewport.height <= 0)
+		{
+			return false;
+		}
+
+		if(scissorEnable)
+		{
+			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)
+			{
+				return false;
+			}
+
+			sw::Rect scissor;
+			scissor.x0 = scissorRect.x0;
+			scissor.x1 = scissorRect.x1;
+			scissor.y0 = scissorRect.y0;
+			scissor.y1 = scissorRect.y1;
+
+			setScissor(scissor);
+		}
+		else
+		{
+			sw::Rect scissor;
+			scissor.x0 = viewport.x0;
+			scissor.x1 = viewport.x0 + viewport.width;
+			scissor.y0 = viewport.y0;
+			scissor.y1 = viewport.y0 + viewport.height;
+
+			for(int i = 0; i < RENDERTARGETS; ++i)
+			{
+				if(renderTarget[i])
+				{
+					scissor.x0 = max(scissor.x0, 0);
+					scissor.x1 = min(scissor.x1, renderTarget[i]->getWidth());
+					scissor.y0 = max(scissor.y0, 0);
+					scissor.y1 = min(scissor.y1, renderTarget[i]->getHeight());
+				}
+			}
+
+			if(depthBuffer)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, depthBuffer->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, depthBuffer->getHeight());
+			}
+
+			if(stencilBuffer)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, stencilBuffer->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, stencilBuffer->getHeight());
+			}
+
+			setScissor(scissor);
+		}
+
+		sw::Viewport view;
+		view.x0 = (float)viewport.x0;
+		view.y0 = (float)viewport.y0;
+		view.width = (float)viewport.width;
+		view.height = (float)viewport.height;
+		view.minZ = viewport.minZ;
+		view.maxZ = viewport.maxZ;
+
+		Renderer::setViewport(view);
+
+		return true;
+	}
+
+	bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface)
+	{
+		if(!rect)
+		{
+			return true;
+		}
+
+		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)
+		{
+			return false;
+		}
+
+		if(rect->x0 < 0 || rect->y0 < 0)
+		{
+			return false;
+		}
+
+		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	void Device::finish()
+	{
+		synchronize();
+	}
+}
diff --git a/src/OpenGL/libGLESv2/Device.hpp b/src/OpenGL/libGLESv2/Device.hpp
index 9283cf3..b3721cc 100644
--- a/src/OpenGL/libGLESv2/Device.hpp
+++ b/src/OpenGL/libGLESv2/Device.hpp
@@ -1,97 +1,100 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef gl_Device_hpp

-#define gl_Device_hpp

-

-#include "Renderer/Renderer.hpp"

-

-namespace egl

-{

-	class Image;

-}

-

-namespace es2

-{

-	class Texture;

-

-	struct Viewport

-	{

-		int x0;

-		int y0;

-		unsigned int width;

-		unsigned int height;

-		float minZ;

-		float maxZ;

-	};

-

-	class Device : public sw::Renderer

-	{

-	public:

-		explicit Device(sw::Context *context);

-

-		virtual ~Device();

-

-		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);

-		virtual void clearDepth(float z);

-		virtual void clearStencil(unsigned int stencil, unsigned int mask);

-		virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-		virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);

-		virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);

-		virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount);

-		virtual void setPixelShader(sw::PixelShader *shader);

-		virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);

-		virtual void setScissorEnable(bool enable);

-		virtual void setRenderTarget(int index, egl::Image *renderTarget);

-		virtual void setDepthBuffer(egl::Image *depthBuffer);

-		virtual void setStencilBuffer(egl::Image *stencilBuffer);

-		virtual void setScissorRect(const sw::Rect &rect);

-		virtual void setVertexShader(sw::VertexShader *shader);

-		virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);

-		virtual void setViewport(const Viewport &viewport);

-

-		virtual bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRect *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, bool filter);

-		virtual bool stretchCube(sw::Surface *sourceSurface, sw::Surface *destSurface);

-		virtual void finish();

-

-	private:

-		sw::Context *const context;

-

-		bool bindResources();

-		void bindShaderConstants();

-		bool bindViewport();   // Also adjusts for scissoring

-

-		bool validRectangle(const sw::Rect *rect, sw::Surface *surface);

-

-		void copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY);

-

-		Viewport viewport;

-		sw::Rect scissorRect;

-		bool scissorEnable;

-

-		sw::PixelShader *pixelShader;

-		sw::VertexShader *vertexShader;

-

-		bool pixelShaderDirty;

-		unsigned int pixelShaderConstantsFDirty;

-		bool vertexShaderDirty;

-		unsigned int vertexShaderConstantsFDirty;

-

-		float pixelShaderConstantF[sw::FRAGMENT_UNIFORM_VECTORS][4];

-		float vertexShaderConstantF[sw::VERTEX_UNIFORM_VECTORS][4];

-

-		egl::Image *renderTarget[sw::RENDERTARGETS];

-		egl::Image *depthBuffer;

-		egl::Image *stencilBuffer;

-	};

-}

-

-#endif   // gl_Device_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef gl_Device_hpp
+#define gl_Device_hpp
+
+#include "Renderer/Renderer.hpp"
+
+namespace egl
+{
+	class Image;
+}
+
+namespace es2
+{
+	class Texture;
+
+	struct Viewport
+	{
+		int x0;
+		int y0;
+		unsigned int width;
+		unsigned int height;
+		float minZ;
+		float maxZ;
+	};
+
+	class Device : public sw::Renderer
+	{
+	public:
+		explicit Device(sw::Context *context);
+
+		virtual ~Device();
+
+		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
+		virtual void clearDepth(float z);
+		virtual void clearStencil(unsigned int stencil, unsigned int mask);
+		virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+		virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);
+		virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);
+		virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount);
+		virtual void setPixelShader(sw::PixelShader *shader);
+		virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+		virtual void setScissorEnable(bool enable);
+		virtual void setRenderTarget(int index, egl::Image *renderTarget);
+		virtual void setDepthBuffer(egl::Image *depthBuffer);
+		virtual void setStencilBuffer(egl::Image *stencilBuffer);
+		virtual void setScissorRect(const sw::Rect &rect);
+		virtual void setVertexShader(sw::VertexShader *shader);
+		virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+		virtual void setViewport(const Viewport &viewport);
+
+		virtual bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRect *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, bool filter);
+		virtual bool stretchCube(sw::Surface *sourceSurface, sw::Surface *destSurface);
+		virtual void finish();
+
+	private:
+		sw::Context *const context;
+
+		bool bindResources();
+		void bindShaderConstants();
+		bool bindViewport();   // Also adjusts for scissoring
+
+		bool validRectangle(const sw::Rect *rect, sw::Surface *surface);
+
+		void copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY);
+
+		Viewport viewport;
+		sw::Rect scissorRect;
+		bool scissorEnable;
+
+		sw::PixelShader *pixelShader;
+		sw::VertexShader *vertexShader;
+
+		bool pixelShaderDirty;
+		unsigned int pixelShaderConstantsFDirty;
+		bool vertexShaderDirty;
+		unsigned int vertexShaderConstantsFDirty;
+
+		float pixelShaderConstantF[sw::FRAGMENT_UNIFORM_VECTORS][4];
+		float vertexShaderConstantF[sw::VERTEX_UNIFORM_VECTORS][4];
+
+		egl::Image *renderTarget[sw::RENDERTARGETS];
+		egl::Image *depthBuffer;
+		egl::Image *stencilBuffer;
+	};
+}
+
+#endif   // gl_Device_hpp
diff --git a/src/OpenGL/libGLESv2/Fence.cpp b/src/OpenGL/libGLESv2/Fence.cpp
index 31c3bf6..17a2228 100644
--- a/src/OpenGL/libGLESv2/Fence.cpp
+++ b/src/OpenGL/libGLESv2/Fence.cpp
@@ -1,132 +1,135 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.

-

-#include "Fence.h"

-

-#include "main.h"

-#include "Common/Thread.hpp"

-

-namespace es2

-{

-

-Fence::Fence()

-{ 

-    mQuery = false;

-    mCondition = GL_NONE;

-    mStatus = GL_FALSE;

-}

-

-Fence::~Fence()

-{

-    mQuery = false;

-}

-

-GLboolean Fence::isFence()

-{

-    // GL_NV_fence spec:

-    // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.

-    return mQuery;

-}

-

-void Fence::setFence(GLenum condition)

-{

-    if(condition != GL_ALL_COMPLETED_NV)

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    mQuery = true;

-    mCondition = condition;

-    mStatus = GL_FALSE;

-}

-

-GLboolean Fence::testFence()

-{

-    if(!mQuery)

-    {

-        return error(GL_INVALID_OPERATION, GL_TRUE);

-    }

-

-    // The current assumtion is that no matter where the fence is placed, it is

-    // done by the time it is tested, which is similar to Context::flush(), since

-    // we don't queue anything without processing it as fast as possible.

-    mStatus = GL_TRUE;

-

-    return mStatus;

-}

-

-void Fence::finishFence()

-{

-    if(!mQuery)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    while(!testFence())

-    {

-        sw::Thread::yield();

-    }

-}

-

-void Fence::getFenceiv(GLenum pname, GLint *params)

-{

-    if(!mQuery)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    switch (pname)

-    {

-    case GL_FENCE_STATUS_NV:

-		{

-			// GL_NV_fence spec:

-			// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV

-			// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.

-			if(mStatus)

-			{

-				params[0] = GL_TRUE;

-				return;

-			}

-            

-			mStatus = testFence();

-

-			params[0] = mStatus;            

-			break;

-		}

-    case GL_FENCE_CONDITION_NV:

-        params[0] = mCondition;

-        break;

-    default:

-        return error(GL_INVALID_ENUM);

-        break;

-    }

-}

-

-FenceSync::FenceSync(GLuint name, GLenum condition, GLbitfield flags) : NamedObject(name), mCondition(condition), mFlags(flags)

-{

-}

-

-FenceSync::~FenceSync()

-{

-}

-

-GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)

-{

-	return GL_TRUE;

-}

-

-void FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)

-{

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.
+
+#include "Fence.h"
+
+#include "main.h"
+#include "Common/Thread.hpp"
+
+namespace es2
+{
+
+Fence::Fence()
+{
+	mQuery = false;
+	mCondition = GL_NONE;
+	mStatus = GL_FALSE;
+}
+
+Fence::~Fence()
+{
+	mQuery = false;
+}
+
+GLboolean Fence::isFence()
+{
+	// GL_NV_fence spec:
+	// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
+	return mQuery;
+}
+
+void Fence::setFence(GLenum condition)
+{
+	if(condition != GL_ALL_COMPLETED_NV)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	mQuery = true;
+	mCondition = condition;
+	mStatus = GL_FALSE;
+}
+
+GLboolean Fence::testFence()
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION, GL_TRUE);
+	}
+
+	// The current assumtion is that no matter where the fence is placed, it is
+	// done by the time it is tested, which is similar to Context::flush(), since
+	// we don't queue anything without processing it as fast as possible.
+	mStatus = GL_TRUE;
+
+	return mStatus;
+}
+
+void Fence::finishFence()
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	while(!testFence())
+	{
+		sw::Thread::yield();
+	}
+}
+
+void Fence::getFenceiv(GLenum pname, GLint *params)
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	switch(pname)
+	{
+	case GL_FENCE_STATUS_NV:
+		{
+			// GL_NV_fence spec:
+			// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
+			// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+			if(mStatus)
+			{
+				params[0] = GL_TRUE;
+				return;
+			}
+
+			mStatus = testFence();
+
+			params[0] = mStatus;
+			break;
+		}
+	case GL_FENCE_CONDITION_NV:
+		params[0] = mCondition;
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+		break;
+	}
+}
+
+FenceSync::FenceSync(GLuint name, GLenum condition, GLbitfield flags) : NamedObject(name), mCondition(condition), mFlags(flags)
+{
+}
+
+FenceSync::~FenceSync()
+{
+}
+
+GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
+{
+	return GL_TRUE;
+}
+
+void FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
+{
+}
+
+}
diff --git a/src/OpenGL/libGLESv2/Fence.h b/src/OpenGL/libGLESv2/Fence.h
index 85ce7c6..4a1d8b5 100644
--- a/src/OpenGL/libGLESv2/Fence.h
+++ b/src/OpenGL/libGLESv2/Fence.h
@@ -1,60 +1,63 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Fence.h: Defines the Fence class, which supports the GL_NV_fence extension.

-

-#ifndef LIBGLESV2_FENCE_H_

-#define LIBGLESV2_FENCE_H_

-

-#include "common/Object.hpp"

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-

-class Fence

-{

-  public:

-    Fence();

-    virtual ~Fence();

-

-    GLboolean isFence();

-    void setFence(GLenum condition);

-    GLboolean testFence();

-    void finishFence();

-    void getFenceiv(GLenum pname, GLint *params);

-

-  private:

-    bool mQuery;

-    GLenum mCondition;

-    GLboolean mStatus;

-};

-

-class FenceSync : public gl::NamedObject

-{

-public:

-	FenceSync(GLuint name, GLenum condition, GLbitfield flags);

-	virtual ~FenceSync();

-

-	GLenum clientWait(GLbitfield flags, GLuint64 timeout);

-	void serverWait(GLbitfield flags, GLuint64 timeout);

-

-	GLenum getCondition() const { return mCondition; }

-	GLbitfield getFlags() const { return mFlags; }

-

-private:

-	GLenum mCondition;

-	GLbitfield mFlags;

-};

-

-}

-

-#endif   // LIBGLESV2_FENCE_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Fence.h: Defines the Fence class, which supports the GL_NV_fence extension.
+
+#ifndef LIBGLESV2_FENCE_H_
+#define LIBGLESV2_FENCE_H_
+
+#include "common/Object.hpp"
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+
+class Fence
+{
+public:
+	Fence();
+	virtual ~Fence();
+
+	GLboolean isFence();
+	void setFence(GLenum condition);
+	GLboolean testFence();
+	void finishFence();
+	void getFenceiv(GLenum pname, GLint *params);
+
+private:
+	bool mQuery;
+	GLenum mCondition;
+	GLboolean mStatus;
+};
+
+class FenceSync : public gl::NamedObject
+{
+public:
+	FenceSync(GLuint name, GLenum condition, GLbitfield flags);
+	virtual ~FenceSync();
+
+	GLenum clientWait(GLbitfield flags, GLuint64 timeout);
+	void serverWait(GLbitfield flags, GLuint64 timeout);
+
+	GLenum getCondition() const { return mCondition; }
+	GLbitfield getFlags() const { return mFlags; }
+
+private:
+	GLenum mCondition;
+	GLbitfield mFlags;
+};
+
+}
+
+#endif   // LIBGLESV2_FENCE_H_
diff --git a/src/OpenGL/libGLESv2/Framebuffer.cpp b/src/OpenGL/libGLESv2/Framebuffer.cpp
index 5ab7b7e..3390dd9 100644
--- a/src/OpenGL/libGLESv2/Framebuffer.cpp
+++ b/src/OpenGL/libGLESv2/Framebuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
@@ -610,7 +613,7 @@
 {
 	Renderbuffer *depthbuffer = getDepthbuffer();
 
-	if (depthbuffer)
+	if(depthbuffer)
 	{
 		// There is only one depth read format.
 		return GL_DEPTH_COMPONENT;
@@ -624,9 +627,9 @@
 {
 	Renderbuffer *depthbuffer = getDepthbuffer();
 
-	if (depthbuffer)
+	if(depthbuffer)
 	{
-		switch (depthbuffer->getInternalFormat())
+		switch(depthbuffer->getInternalFormat())
 		{
 		case sw::FORMAT_D16:                return GL_UNSIGNED_SHORT;
 		case sw::FORMAT_D24S8:              return GL_UNSIGNED_INT_24_8_OES;
diff --git a/src/OpenGL/libGLESv2/Framebuffer.h b/src/OpenGL/libGLESv2/Framebuffer.h
index f88e883..37b8683 100644
--- a/src/OpenGL/libGLESv2/Framebuffer.h
+++ b/src/OpenGL/libGLESv2/Framebuffer.h
@@ -1,113 +1,116 @@
-// 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.

-//

-

-// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer

-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.

-

-#ifndef LIBGLESV2_FRAMEBUFFER_H_

-#define LIBGLESV2_FRAMEBUFFER_H_

-

-#include "Context.h"

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-class Renderbuffer;

-class Colorbuffer;

-class Depthbuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-

-class Framebuffer

-{

-public:

-	Framebuffer();

-

-	virtual ~Framebuffer();

-

-	void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level = 0, GLint layer = 0);

-	void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level = 0, GLint layer = 0);

-	void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0);

-

-	void setReadBuffer(GLenum buf);

-	void setDrawBuffer(GLuint index, GLenum buf);

-	GLenum getReadBuffer() const;

-	GLenum getDrawBuffer(GLuint index) const;

-

-	void detachTexture(GLuint texture);

-	void detachRenderbuffer(GLuint renderbuffer);

-

-	egl::Image *getRenderTarget(GLuint index);

-	egl::Image *getReadRenderTarget();

-	egl::Image *getDepthBuffer();

-	egl::Image *getStencilBuffer();

-

-	Renderbuffer *getColorbuffer(GLuint index);

-	Renderbuffer *getReadColorbuffer();

-	Renderbuffer *getDepthbuffer();

-	Renderbuffer *getStencilbuffer();

-

-	GLenum getColorbufferType(GLuint index);

-	GLenum getDepthbufferType();

-	GLenum getStencilbufferType();

-

-	GLuint getColorbufferName(GLuint index);

-	GLuint getDepthbufferName();

-	GLuint getStencilbufferName();

-

-	GLint getColorbufferLayer(GLuint index);

-	GLint getDepthbufferLayer();

-	GLint getStencilbufferLayer();

-

-	bool hasStencil();

-

-	GLenum completeness();

-	GLenum completeness(int &width, int &height, int &samples);

-

-	GLenum getImplementationColorReadFormat();

-	GLenum getImplementationColorReadType();

-	GLenum getDepthReadFormat();

-	GLenum getDepthReadType();

-

-	virtual bool isDefaultFramebuffer() const { return false; }

-

-	static bool IsRenderbuffer(GLenum type);

-

-protected:

-	GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];

-	gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];

-	GLenum readBuffer;

-	GLenum drawBuffer[MAX_COLOR_ATTACHMENTS];

-

-	GLenum mDepthbufferType;

-	gl::BindingPointer<Renderbuffer> mDepthbufferPointer;

-

-	GLenum mStencilbufferType;

-	gl::BindingPointer<Renderbuffer> mStencilbufferPointer;

-

-private:

-	Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const;

-};

-

-class DefaultFramebuffer : public Framebuffer

-{

-public:

-	DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);

-

-	bool isDefaultFramebuffer() const override { return true; }

-};

-

-}

-

-#endif   // LIBGLESV2_FRAMEBUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
+
+#ifndef LIBGLESV2_FRAMEBUFFER_H_
+#define LIBGLESV2_FRAMEBUFFER_H_
+
+#include "Context.h"
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+class Renderbuffer;
+class Colorbuffer;
+class Depthbuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+
+class Framebuffer
+{
+public:
+	Framebuffer();
+
+	virtual ~Framebuffer();
+
+	void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level = 0, GLint layer = 0);
+	void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level = 0, GLint layer = 0);
+	void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0);
+
+	void setReadBuffer(GLenum buf);
+	void setDrawBuffer(GLuint index, GLenum buf);
+	GLenum getReadBuffer() const;
+	GLenum getDrawBuffer(GLuint index) const;
+
+	void detachTexture(GLuint texture);
+	void detachRenderbuffer(GLuint renderbuffer);
+
+	egl::Image *getRenderTarget(GLuint index);
+	egl::Image *getReadRenderTarget();
+	egl::Image *getDepthBuffer();
+	egl::Image *getStencilBuffer();
+
+	Renderbuffer *getColorbuffer(GLuint index);
+	Renderbuffer *getReadColorbuffer();
+	Renderbuffer *getDepthbuffer();
+	Renderbuffer *getStencilbuffer();
+
+	GLenum getColorbufferType(GLuint index);
+	GLenum getDepthbufferType();
+	GLenum getStencilbufferType();
+
+	GLuint getColorbufferName(GLuint index);
+	GLuint getDepthbufferName();
+	GLuint getStencilbufferName();
+
+	GLint getColorbufferLayer(GLuint index);
+	GLint getDepthbufferLayer();
+	GLint getStencilbufferLayer();
+
+	bool hasStencil();
+
+	GLenum completeness();
+	GLenum completeness(int &width, int &height, int &samples);
+
+	GLenum getImplementationColorReadFormat();
+	GLenum getImplementationColorReadType();
+	GLenum getDepthReadFormat();
+	GLenum getDepthReadType();
+
+	virtual bool isDefaultFramebuffer() const { return false; }
+
+	static bool IsRenderbuffer(GLenum type);
+
+protected:
+	GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];
+	gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];
+	GLenum readBuffer;
+	GLenum drawBuffer[MAX_COLOR_ATTACHMENTS];
+
+	GLenum mDepthbufferType;
+	gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
+
+	GLenum mStencilbufferType;
+	gl::BindingPointer<Renderbuffer> mStencilbufferPointer;
+
+private:
+	Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const;
+};
+
+class DefaultFramebuffer : public Framebuffer
+{
+public:
+	DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+
+	bool isDefaultFramebuffer() const override { return true; }
+};
+
+}
+
+#endif   // LIBGLESV2_FRAMEBUFFER_H_
diff --git a/src/OpenGL/libGLESv2/IndexDataManager.cpp b/src/OpenGL/libGLESv2/IndexDataManager.cpp
index 120cd18..8405aea 100644
--- a/src/OpenGL/libGLESv2/IndexDataManager.cpp
+++ b/src/OpenGL/libGLESv2/IndexDataManager.cpp
@@ -1,255 +1,258 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// IndexDataManager.cpp: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#include "IndexDataManager.h"

-

-#include "Buffer.h"

-#include "common/debug.h"

-

-#include <string.h>

-#include <algorithm>

-

-namespace

-{

-    enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };

-}

-

-namespace es2

-{

-

-IndexDataManager::IndexDataManager()

-{

-    mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming index buffer.");

-    }

-}

-

-IndexDataManager::~IndexDataManager()

-{

-    delete mStreamingBuffer;

-}

-

-void copyIndices(GLenum type, const void *input, GLsizei count, void *output)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        memcpy(output, input, count * sizeof(GLubyte));

-    }

-    else if(type == GL_UNSIGNED_INT)

-    {

-        memcpy(output, input, count * sizeof(GLuint));

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        memcpy(output, input, count * sizeof(GLushort));

-    }

-    else UNREACHABLE(type);

-}

-

-template<class IndexType>

-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    *minIndex = indices[0];

-    *maxIndex = indices[0];

-

-    for(GLsizei i = 0; i < count; i++)

-    {

-        if(*minIndex > indices[i]) *minIndex = indices[i];

-        if(*maxIndex < indices[i]) *maxIndex = indices[i];

-    }

-}

-

-void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);

-    }

-    else if(type == GL_UNSIGNED_INT)

-    {

-        computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);

-    }

-    else UNREACHABLE(type);

-}

-

-GLenum IndexDataManager::prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-    intptr_t offset = reinterpret_cast<intptr_t>(indices);

-

-    if(buffer != NULL)

-    {

-        if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))

-        {

-            return GL_INVALID_OPERATION;

-        }

-

-        indices = static_cast<const GLubyte*>(buffer->data()) + offset;

-    }

-

-    StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;

-

-	sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-    if(staticBuffer)

-    {

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = staticBuffer;

-		translated->indexOffset = offset;

-    }

-    else

-    {

-		unsigned int streamOffset = 0;

-        int convertCount = count;

-

-        streamingBuffer->reserveSpace(convertCount * typeSize(type), type);

-        void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);

-        

-        if(output == NULL)

-        {

-            ERR("Failed to map index buffer.");

-            return GL_OUT_OF_MEMORY;

-        }

-

-        copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);

-        streamingBuffer->unmap();

-

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = streamingBuffer->getResource();

-		translated->indexOffset = streamOffset;

-    }

-

-	if(translated->minIndex < start || translated->maxIndex > end)

-	{

-		ERR("glDrawRangeElements: out of range access. Range provided: [%d -> %d]. Range used: [%d -> %d].", start, end, translated->minIndex, translated->maxIndex);

-	}

-

-    return GL_NO_ERROR;

-}

-

-std::size_t IndexDataManager::typeSize(GLenum type)

-{

-    switch(type)

-    {

-    case GL_UNSIGNED_INT:   return sizeof(GLuint);

-    case GL_UNSIGNED_SHORT: return sizeof(GLushort);

-    case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);

-    default: UNREACHABLE(type); return sizeof(GLushort);

-    }

-}

-

-StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(NULL), mBufferSize(initialSize)

-{

-	if(initialSize > 0)

-    {

-		mIndexBuffer = new sw::Resource(initialSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", initialSize);

-        }

-    }

-

-    mWritePosition = 0;

-}

-

-StreamingIndexBuffer::~StreamingIndexBuffer()

-{

-	if(mIndexBuffer)

-    {

-        mIndexBuffer->destruct();

-    }

-}

-

-void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mIndexBuffer)

-    {

-        mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;

-     

-        if(!mapPtr)

-        {

-            ERR(" Lock failed");

-            return NULL;

-        }

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingIndexBuffer::unmap()

-{

-    if(mIndexBuffer)

-    {

-        mIndexBuffer->unlock();

-    }

-}

-

-void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)

-{

-    if(requiredSpace > mBufferSize)

-    {

-        if(mIndexBuffer)

-        {

-            mIndexBuffer->destruct();

-            mIndexBuffer = 0;

-        }

-

-        mBufferSize = std::max(requiredSpace, 2 * mBufferSize);

-

-		mIndexBuffer = new sw::Resource(mBufferSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle

-    {

-		if(mIndexBuffer)

-		{

-			mIndexBuffer->destruct();

-			mIndexBuffer = new sw::Resource(mBufferSize + 16);

-		}

-

-        mWritePosition = 0;

-    }

-}

-

-sw::Resource *StreamingIndexBuffer::getResource() const

-{

-    return mIndexBuffer;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// IndexDataManager.cpp: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#include "IndexDataManager.h"
+
+#include "Buffer.h"
+#include "common/debug.h"
+
+#include <string.h>
+#include <algorithm>
+
+namespace
+{
+	enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
+}
+
+namespace es2
+{
+
+IndexDataManager::IndexDataManager()
+{
+	mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming index buffer.");
+	}
+}
+
+IndexDataManager::~IndexDataManager()
+{
+	delete mStreamingBuffer;
+}
+
+void copyIndices(GLenum type, const void *input, GLsizei count, void *output)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		memcpy(output, input, count * sizeof(GLubyte));
+	}
+	else if(type == GL_UNSIGNED_INT)
+	{
+		memcpy(output, input, count * sizeof(GLuint));
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		memcpy(output, input, count * sizeof(GLushort));
+	}
+	else UNREACHABLE(type);
+}
+
+template<class IndexType>
+void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	*minIndex = indices[0];
+	*maxIndex = indices[0];
+
+	for(GLsizei i = 0; i < count; i++)
+	{
+		if(*minIndex > indices[i]) *minIndex = indices[i];
+		if(*maxIndex < indices[i]) *maxIndex = indices[i];
+	}
+}
+
+void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+	}
+	else if(type == GL_UNSIGNED_INT)
+	{
+		computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
+	}
+	else UNREACHABLE(type);
+}
+
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	intptr_t offset = reinterpret_cast<intptr_t>(indices);
+
+	if(buffer != NULL)
+	{
+		if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		indices = static_cast<const GLubyte*>(buffer->data()) + offset;
+	}
+
+	StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;
+
+	sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;
+
+	if(staticBuffer)
+	{
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = staticBuffer;
+		translated->indexOffset = offset;
+	}
+	else
+	{
+		unsigned int streamOffset = 0;
+		int convertCount = count;
+
+		streamingBuffer->reserveSpace(convertCount * typeSize(type), type);
+		void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);
+
+		if(output == NULL)
+		{
+			ERR("Failed to map index buffer.");
+			return GL_OUT_OF_MEMORY;
+		}
+
+		copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
+		streamingBuffer->unmap();
+
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = streamingBuffer->getResource();
+		translated->indexOffset = streamOffset;
+	}
+
+	if(translated->minIndex < start || translated->maxIndex > end)
+	{
+		ERR("glDrawRangeElements: out of range access. Range provided: [%d -> %d]. Range used: [%d -> %d].", start, end, translated->minIndex, translated->maxIndex);
+	}
+
+	return GL_NO_ERROR;
+}
+
+std::size_t IndexDataManager::typeSize(GLenum type)
+{
+	switch(type)
+	{
+	case GL_UNSIGNED_INT:   return sizeof(GLuint);
+	case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+	case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);
+	default: UNREACHABLE(type); return sizeof(GLushort);
+	}
+}
+
+StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(NULL), mBufferSize(initialSize)
+{
+	if(initialSize > 0)
+	{
+		mIndexBuffer = new sw::Resource(initialSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", initialSize);
+		}
+	}
+
+	mWritePosition = 0;
+}
+
+StreamingIndexBuffer::~StreamingIndexBuffer()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->destruct();
+	}
+}
+
+void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = NULL;
+
+	if(mIndexBuffer)
+	{
+		mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;
+
+		if(!mapPtr)
+		{
+			ERR(" Lock failed");
+			return NULL;
+		}
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingIndexBuffer::unmap()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->unlock();
+	}
+}
+
+void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)
+{
+	if(requiredSpace > mBufferSize)
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = 0;
+		}
+
+		mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
+
+		mIndexBuffer = new sw::Resource(mBufferSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = new sw::Resource(mBufferSize + 16);
+		}
+
+		mWritePosition = 0;
+	}
+}
+
+sw::Resource *StreamingIndexBuffer::getResource() const
+{
+	return mIndexBuffer;
+}
+
+}
diff --git a/src/OpenGL/libGLESv2/IndexDataManager.h b/src/OpenGL/libGLESv2/IndexDataManager.h
index f0d108d..225e30c 100644
--- a/src/OpenGL/libGLESv2/IndexDataManager.h
+++ b/src/OpenGL/libGLESv2/IndexDataManager.h
@@ -1,68 +1,71 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// IndexDataManager.h: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#ifndef LIBGLESV2_INDEXDATAMANAGER_H_

-#define LIBGLESV2_INDEXDATAMANAGER_H_

-

-#include "Context.h"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-

-struct TranslatedIndexData

-{

-    unsigned int minIndex;

-    unsigned int maxIndex;

-    unsigned int indexOffset;

-

-    sw::Resource *indexBuffer;

-};

-

-class StreamingIndexBuffer

-{

-  public:

-    StreamingIndexBuffer(unsigned int initialSize);

-    virtual ~StreamingIndexBuffer();

-

-    void *map(unsigned int requiredSpace, unsigned int *offset);

-	void unmap();

-    void reserveSpace(unsigned int requiredSpace, GLenum type);

-

-	sw::Resource *getResource() const;

-

-  private:

-    sw::Resource *mIndexBuffer;

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-};

-

-class IndexDataManager

-{

-  public:

-    IndexDataManager();

-    virtual ~IndexDataManager();

-

-    GLenum prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);

-

-	static std::size_t typeSize(GLenum type);

-

-  private:

-    StreamingIndexBuffer *mStreamingBuffer;

-};

-

-}

-

-#endif   // LIBGLESV2_INDEXDATAMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// IndexDataManager.h: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#ifndef LIBGLESV2_INDEXDATAMANAGER_H_
+#define LIBGLESV2_INDEXDATAMANAGER_H_
+
+#include "Context.h"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+
+struct TranslatedIndexData
+{
+	unsigned int minIndex;
+	unsigned int maxIndex;
+	unsigned int indexOffset;
+
+	sw::Resource *indexBuffer;
+};
+
+class StreamingIndexBuffer
+{
+public:
+	StreamingIndexBuffer(unsigned int initialSize);
+	virtual ~StreamingIndexBuffer();
+
+	void *map(unsigned int requiredSpace, unsigned int *offset);
+	void unmap();
+	void reserveSpace(unsigned int requiredSpace, GLenum type);
+
+	sw::Resource *getResource() const;
+
+private:
+	sw::Resource *mIndexBuffer;
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+};
+
+class IndexDataManager
+{
+public:
+	IndexDataManager();
+	virtual ~IndexDataManager();
+
+	GLenum prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
+
+	static std::size_t typeSize(GLenum type);
+
+private:
+	StreamingIndexBuffer *mStreamingBuffer;
+};
+
+}
+
+#endif   // LIBGLESV2_INDEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index 6a790f4..a425920 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -1,2952 +1,2955 @@
-// 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.

-//

-

-// Program.cpp: Implements the Program class. Implements GL program objects

-// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.

-

-#include "Program.h"

-

-#include "main.h"

-#include "Buffer.h"

-#include "Shader.h"

-#include "TransformFeedback.h"

-#include "utilities.h"

-#include "common/debug.h"

-#include "Shader/PixelShader.hpp"

-#include "Shader/VertexShader.hpp"

-

-#include <string>

-#include <stdlib.h>

-

-namespace es2

-{

-	unsigned int Program::currentSerial = 1;

-

-	std::string str(int i)

-	{

-		char buffer[20];

-		sprintf(buffer, "%d", i);

-		return buffer;

-	}

-

-	Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex)

-	{

-		static unsigned int registerSizeStd140 = 4; // std140 packing requires dword alignment

-

-		if(blockIndex >= 0)

-		{

-			index = blockIndex;

-			offset = uniform.blockInfo.offset;

-			arrayStride = uniform.blockInfo.arrayStride;

-			matrixStride = uniform.blockInfo.matrixStride;

-			isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;

-		}

-		else

-		{

-			index = -1;

-			offset = -1;

-			arrayStride = -1;

-			matrixStride = -1;

-			isRowMajorMatrix = false;

-		}

-	}

-

-	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,

-	                 const BlockInfo &blockInfo)

-	 : type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)

-	{

-		if(blockInfo.index == -1)

-		{

-			size_t bytes = UniformTypeSize(type) * size();

-			data = new unsigned char[bytes];

-			memset(data, 0, bytes);

-		}

-		else

-		{

-			data = nullptr;

-		}

-		dirty = true;

-

-		psRegisterIndex = -1;

-		vsRegisterIndex = -1;

-	}

-

-	Uniform::~Uniform()

-	{

-		delete[] data;

-	}

-

-	bool Uniform::isArray() const

-	{

-		return arraySize >= 1;

-	}

-

-	int Uniform::size() const

-	{

-		return arraySize > 0 ? arraySize : 1;

-	}

-

-	int Uniform::registerCount() const

-	{

-		return size() * VariableRegisterCount(type);

-	}

-

-	UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes) :

-		name(name), elementIndex(elementIndex), dataSize(dataSize), memberUniformIndexes(memberUniformIndexes), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX)

-	{

-	}

-

-	void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex)

-	{

-		switch(shader)

-		{

-		case GL_VERTEX_SHADER:

-			vsRegisterIndex = registerIndex;

-			break;

-		case GL_FRAGMENT_SHADER:

-			psRegisterIndex = registerIndex;

-			break;

-		default:

-			UNREACHABLE(shader);

-		}

-	}

-

-	bool UniformBlock::isArrayElement() const

-	{

-		return elementIndex != GL_INVALID_INDEX;

-	}

-

-	bool UniformBlock::isReferencedByVertexShader() const

-	{

-		return vsRegisterIndex != GL_INVALID_INDEX;

-	}

-

-	bool UniformBlock::isReferencedByFragmentShader() const

-	{

-		return psRegisterIndex != GL_INVALID_INDEX;

-	}

-

-	UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)

-	{

-	}

-

-	LinkedVarying::LinkedVarying()

-	{

-	}

-

-	LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col)

-	 : name(name), type(type), size(size), reg(reg), col(col)

-	{

-	}

-

-	Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)

-	{

-		device = getDevice();

-

-		fragmentShader = 0;

-		vertexShader = 0;

-		pixelBinary = 0;

-		vertexBinary = 0;

-

-		transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS;

-		totalLinkedVaryingsComponents = 0;

-

-		infoLog = 0;

-		validated = false;

-

-		resetUniformBlockBindings();

-		unlink();

-

-		orphaned = false;

-		retrievableBinary = false;

-		referenceCount = 0;

-	}

-

-	Program::~Program()

-	{

-		unlink();

-

-		if(vertexShader)

-		{

-			vertexShader->release();

-		}

-

-		if(fragmentShader)

-		{

-			fragmentShader->release();

-		}

-	}

-

-	bool Program::attachShader(Shader *shader)

-	{

-		if(shader->getType() == GL_VERTEX_SHADER)

-		{

-			if(vertexShader)

-			{

-				return false;

-			}

-

-			vertexShader = (VertexShader*)shader;

-			vertexShader->addRef();

-		}

-		else if(shader->getType() == GL_FRAGMENT_SHADER)

-		{

-			if(fragmentShader)

-			{

-				return false;

-			}

-

-			fragmentShader = (FragmentShader*)shader;

-			fragmentShader->addRef();

-		}

-		else UNREACHABLE(shader->getType());

-

-		return true;

-	}

-

-	bool Program::detachShader(Shader *shader)

-	{

-		if(shader->getType() == GL_VERTEX_SHADER)

-		{

-			if(vertexShader != shader)

-			{

-				return false;

-			}

-

-			vertexShader->release();

-			vertexShader = 0;

-		}

-		else if(shader->getType() == GL_FRAGMENT_SHADER)

-		{

-			if(fragmentShader != shader)

-			{

-				return false;

-			}

-

-			fragmentShader->release();

-			fragmentShader = 0;

-		}

-		else UNREACHABLE(shader->getType());

-

-		return true;

-	}

-

-	int Program::getAttachedShadersCount() const

-	{

-		return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);

-	}

-

-	sw::PixelShader *Program::getPixelShader()

-	{

-		return pixelBinary;

-	}

-

-	sw::VertexShader *Program::getVertexShader()

-	{

-		return vertexBinary;

-	}

-

-	void Program::bindAttributeLocation(GLuint index, const char *name)

-	{

-		if(index < MAX_VERTEX_ATTRIBS)

-		{

-			for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-			{

-				attributeBinding[i].erase(name);

-			}

-

-			attributeBinding[index].insert(name);

-		}

-	}

-

-	GLuint Program::getAttributeLocation(const char *name)

-	{

-		if(name)

-		{

-			for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)

-			{

-				if(linkedAttribute[index].name == std::string(name))

-				{

-					return index;

-				}

-			}

-		}

-

-		return -1;

-	}

-

-	int Program::getAttributeStream(int attributeIndex)

-	{

-		ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);

-

-		return attributeStream[attributeIndex];

-	}

-

-	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)

-	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)

-	{

-		GLuint logicalTextureUnit = -1;

-

-		switch(type)

-		{

-		case sw::SAMPLER_PIXEL:

-			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));

-

-			if(samplersPS[samplerIndex].active)

-			{

-				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;

-			}

-			break;

-		case sw::SAMPLER_VERTEX:

-			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));

-

-			if(samplersVS[samplerIndex].active)

-			{

-				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;

-			}

-			break;

-		default: UNREACHABLE(type);

-		}

-

-		if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)

-		{

-			return logicalTextureUnit;

-		}

-

-		return -1;

-	}

-

-	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)

-	TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)

-	{

-		switch(type)

-		{

-		case sw::SAMPLER_PIXEL:

-			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));

-			ASSERT(samplersPS[samplerIndex].active);

-			return samplersPS[samplerIndex].textureType;

-		case sw::SAMPLER_VERTEX:

-			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));

-			ASSERT(samplersVS[samplerIndex].active);

-			return samplersVS[samplerIndex].textureType;

-		default: UNREACHABLE(type);

-		}

-

-		return TEXTURE_2D;

-	}

-

-	GLint Program::getUniformLocation(const std::string &name) const

-	{

-		size_t subscript = GL_INVALID_INDEX;

-		std::string baseName = es2::ParseUniformName(name, &subscript);

-

-		size_t numUniforms = uniformIndex.size();

-		for(size_t location = 0; location < numUniforms; location++)

-		{

-			const int index = uniformIndex[location].index;

-			const bool isArray = uniforms[index]->isArray();

-

-			if(uniformIndex[location].name == baseName &&

-			   ((isArray && uniformIndex[location].element == subscript) ||

-			    (subscript == GL_INVALID_INDEX)))

-			{

-				return (GLint)location;

-			}

-		}

-

-		return -1;

-	}

-

-	GLuint Program::getUniformIndex(const std::string &name) const

-	{

-		size_t subscript = GL_INVALID_INDEX;

-		std::string baseName = es2::ParseUniformName(name, &subscript);

-

-		// The app is not allowed to specify array indices other than 0 for arrays of basic types

-		if(subscript != 0 && subscript != GL_INVALID_INDEX)

-		{

-			return GL_INVALID_INDEX;

-		}

-

-		size_t numUniforms = uniforms.size();

-		for(GLuint index = 0; index < numUniforms; index++)

-		{

-			if(uniforms[index]->name == baseName)

-			{

-				if(uniforms[index]->isArray() || subscript == GL_INVALID_INDEX)

-				{

-					return index;

-				}

-			}

-		}

-

-		return GL_INVALID_INDEX;

-	}

-

-	void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const

-	{

-		ASSERT(uniformBlockIndex < getActiveUniformBlockCount());

-

-		const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];

-

-		switch(pname)

-		{

-		case GL_UNIFORM_BLOCK_DATA_SIZE:

-			*params = static_cast<GLint>(uniformBlock.dataSize);

-			break;

-		case GL_UNIFORM_BLOCK_NAME_LENGTH:

-			*params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));

-			break;

-		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:

-			*params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());

-			break;

-		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:

-			{

-				for(unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)

-				{

-					params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);

-				}

-			}

-			break;

-		case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:

-			*params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());

-			break;

-		case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:

-			*params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());

-			break;

-		default: UNREACHABLE(pname);

-		}

-	}

-

-	GLuint Program::getUniformBlockIndex(const std::string &name) const

-	{

-		size_t subscript = GL_INVALID_INDEX;

-		std::string baseName = es2::ParseUniformName(name, &subscript);

-

-		size_t numUniformBlocks = getActiveUniformBlockCount();

-		for(GLuint blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)

-		{

-			const UniformBlock &uniformBlock = *uniformBlocks[blockIndex];

-			if(uniformBlock.name == baseName)

-			{

-				const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);

-				if(subscript == uniformBlock.elementIndex || arrayElementZero)

-				{

-					return blockIndex;

-				}

-			}

-		}

-

-		return GL_INVALID_INDEX;

-	}

-

-	void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)

-	{

-		uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;

-	}

-

-	GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const

-	{

-		return uniformBlockBindings[uniformBlockIndex];

-	}

-

-	void Program::resetUniformBlockBindings()

-	{

-		for(unsigned int blockId = 0; blockId < MAX_UNIFORM_BUFFER_BINDINGS; blockId++)

-		{

-			uniformBlockBindings[blockId] = 0;

-		}

-	}

-

-	bool Program::setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements)

-	{

-		ASSERT(numElements >= 1 && numElements <= 4);

-

-		static GLenum floatType[] = { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 };

-		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };

-

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		int index = numElements - 1;

-		if(targetUniform->type == floatType[index])

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat)* numElements,

-				   v, numElements * sizeof(GLfloat)* count);

-		}

-		else if(targetUniform->type == boolType[index])

-		{

-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * numElements;

-

-			for(int i = 0; i < count * numElements; i++)

-			{

-				boolParams[i] = (v[i] == 0.0f) ? GL_FALSE : GL_TRUE;

-			}

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)

-	{

-		return setUniformfv(location, count, v, 1);

-	}

-

-	bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		return setUniformfv(location, count, v, 2);

-	}

-

-	bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		return setUniformfv(location, count, v, 3);

-	}

-

-	bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		return setUniformfv(location, count, v, 4);

-	}

-

-	bool Program::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type)

-	{

-		int numElements;

-		switch(type)

-		{

-		case GL_FLOAT_MAT2:

-			numElements = 4;

-			break;

-		case GL_FLOAT_MAT2x3:

-		case GL_FLOAT_MAT3x2:

-			numElements = 6;

-			break;

-		case GL_FLOAT_MAT2x4:

-		case GL_FLOAT_MAT4x2:

-			numElements = 8;

-			break;

-		case GL_FLOAT_MAT3:

-			numElements = 9;

-			break;

-		case GL_FLOAT_MAT3x4:

-		case GL_FLOAT_MAT4x3:

-			numElements = 12;

-			break;

-		case GL_FLOAT_MAT4:

-			numElements = 16;

-			break;

-		default:

-			return false;

-		}

-

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		if(targetUniform->type != type)

-		{

-			return false;

-		}

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		GLfloat* dst = reinterpret_cast<GLfloat*>(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * numElements);

-

-		if(transpose == GL_FALSE)

-		{

-			memcpy(dst, value, numElements * sizeof(GLfloat) * count);

-		}

-		else

-		{

-			const int rowSize = VariableRowCount(type);

-			const int colSize = VariableColumnCount(type);

-			for(int n = 0; n < count; ++n)

-			{

-				for(int i = 0; i < colSize; ++i)

-				{

-					for(int j = 0; j < rowSize; ++j)

-					{

-						dst[i * rowSize + j] = value[j * colSize + i];

-					}

-				}

-				dst += numElements;

-				value += numElements;

-			}

-		}

-

-

-		return true;

-	}

-

-	bool Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2);

-	}

-

-	bool Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x3);

-	}

-

-	bool Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x4);

-	}

-

-	bool Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3);

-	}

-

-	bool Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x2);

-	}

-

-	bool Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x4);

-	}

-

-	bool Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4);

-	}

-

-	bool Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x2);

-	}

-

-	bool Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-	{

-		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x3);

-	}

-

-	bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),

-				   v, sizeof(GLint) * count);

-		}

-		else if(targetUniform->type == GL_BOOL)

-		{

-			GLboolean *boolParams = new GLboolean[count];

-

-			for(int i = 0; i < count; i++)

-			{

-				if(v[i] == 0)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),

-				   boolParams, sizeof(GLboolean) * count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)

-	{

-		static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };

-		static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };

-		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };

-

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		int index = numElements - 1;

-		if(targetUniform->type == intType[index] || targetUniform->type == uintType[index])

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,

-				   v, numElements * sizeof(GLint)* count);

-		}

-		else if(targetUniform->type == boolType[index])

-		{

-			GLboolean *boolParams = new GLboolean[count * numElements];

-

-			for(int i = 0; i < count * numElements; i++)

-			{

-				boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,

-				   boolParams, numElements * sizeof(GLboolean)* count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)

-	{

-		return setUniformiv(location, count, v, 2);

-	}

-

-	bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)

-	{

-		return setUniformiv(location, count, v, 3);

-	}

-

-	bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)

-	{

-		return setUniformiv(location, count, v, 4);

-	}

-

-	bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),

-				   v, sizeof(GLuint)* count);

-		}

-		else if(targetUniform->type == GL_BOOL)

-		{

-			GLboolean *boolParams = new GLboolean[count];

-

-			for(int i = 0; i < count; i++)

-			{

-				if(v[i] == 0)

-				{

-					boolParams[i] = GL_FALSE;

-				}

-				else

-				{

-					boolParams[i] = GL_TRUE;

-				}

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),

-				   boolParams, sizeof(GLboolean)* count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)

-	{

-		static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };

-		static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };

-		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };

-

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		targetUniform->dirty = true;

-

-		int size = targetUniform->size();

-

-		if(size == 1 && count > 1)

-		{

-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION

-		}

-

-		count = std::min(size - (int)uniformIndex[location].element, count);

-

-		int index = numElements - 1;

-		if(targetUniform->type == uintType[index] || targetUniform->type == intType[index])

-		{

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,

-				   v, numElements * sizeof(GLuint)* count);

-		}

-		else if(targetUniform->type == boolType[index])

-		{

-			GLboolean *boolParams = new GLboolean[count * numElements];

-

-			for(int i = 0; i < count * numElements; i++)

-			{

-				boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;

-			}

-

-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,

-				   boolParams, numElements * sizeof(GLboolean)* count);

-

-			delete[] boolParams;

-		}

-		else

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	bool Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		return setUniformuiv(location, count, v, 2);

-	}

-

-	bool Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		return setUniformuiv(location, count, v, 3);

-	}

-

-	bool Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		return setUniformuiv(location, count, v, 4);

-	}

-

-	bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		unsigned int count = UniformComponentCount(targetUniform->type);

-

-		// Sized query - ensure the provided buffer is large enough

-		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))

-		{

-			return false;

-		}

-

-		switch (UniformComponentType(targetUniform->type))

-		{

-		case GL_BOOL:

-			{

-				GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;

-				}

-			}

-			break;

-		case GL_FLOAT:

-			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),

-				   count * sizeof(GLfloat));

-			break;

-		case GL_INT:

-			{

-				GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (float)intParams[i];

-				}

-			}

-			break;

-		case GL_UNSIGNED_INT:

-			{

-				GLuint *uintParams = (GLuint*)targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (float)uintParams[i];

-				}

-			}

-			break;

-		default: UNREACHABLE(targetUniform->type);

-		}

-

-		return true;

-	}

-

-	bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		unsigned int count = UniformComponentCount(targetUniform->type);

-

-		// Sized query - ensure the provided buffer is large enough

-		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLint))

-		{

-			return false;

-		}

-

-		switch (UniformComponentType(targetUniform->type))

-		{

-		case GL_BOOL:

-			{

-				GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (GLint)boolParams[i];

-				}

-			}

-			break;

-		case GL_FLOAT:

-			{

-				GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;

-

-				for(unsigned int i = 0; i < count; i++)

-				{

-					params[i] = (GLint)floatParams[i];

-				}

-			}

-			break;

-		case GL_INT:

-		case GL_UNSIGNED_INT:

-			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),

-				   count * sizeof(GLint));

-			break;

-		default: UNREACHABLE(targetUniform->type);

-		}

-

-		return true;

-	}

-

-	bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)

-	{

-		if(location < 0 || location >= (int)uniformIndex.size())

-		{

-			return false;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		unsigned int count = UniformComponentCount(targetUniform->type);

-

-		// Sized query - ensure the provided buffer is large enough

-		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLuint))

-		{

-			return false;

-		}

-

-		switch(UniformComponentType(targetUniform->type))

-		{

-		case GL_BOOL:

-		{

-			GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;

-

-			for(unsigned int i = 0; i < count; i++)

-			{

-				params[i] = (GLuint)boolParams[i];

-			}

-		}

-			break;

-		case GL_FLOAT:

-		{

-			GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;

-

-			for(unsigned int i = 0; i < count; i++)

-			{

-				params[i] = (GLuint)floatParams[i];

-			}

-		}

-			break;

-		case GL_INT:

-		case GL_UNSIGNED_INT:

-			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLuint),

-				   count * sizeof(GLuint));

-			break;

-		default: UNREACHABLE(targetUniform->type);

-		}

-

-		return true;

-	}

-

-	void Program::dirtyAllUniforms()

-	{

-		size_t numUniforms = uniforms.size();

-		for(size_t index = 0; index < numUniforms; index++)

-		{

-			uniforms[index]->dirty = true;

-		}

-	}

-

-	// Applies all the uniforms set for this program object to the device

-	void Program::applyUniforms()

-	{

-		GLint numUniforms = uniformIndex.size();

-		for(GLint location = 0; location < numUniforms; location++)

-		{

-			if(uniformIndex[location].element != 0)

-			{

-				continue;

-			}

-

-			Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-			if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))

-			{

-				GLsizei size = targetUniform->size();

-				GLfloat *f = (GLfloat*)targetUniform->data;

-				GLint *i = (GLint*)targetUniform->data;

-				GLuint *ui = (GLuint*)targetUniform->data;

-				GLboolean *b = (GLboolean*)targetUniform->data;

-

-				switch(targetUniform->type)

-				{

-				case GL_BOOL:       applyUniform1bv(location, size, b);       break;

-				case GL_BOOL_VEC2:  applyUniform2bv(location, size, b);       break;

-				case GL_BOOL_VEC3:  applyUniform3bv(location, size, b);       break;

-				case GL_BOOL_VEC4:  applyUniform4bv(location, size, b);       break;

-				case GL_FLOAT:      applyUniform1fv(location, size, f);       break;

-				case GL_FLOAT_VEC2: applyUniform2fv(location, size, f);       break;

-				case GL_FLOAT_VEC3: applyUniform3fv(location, size, f);       break;

-				case GL_FLOAT_VEC4: applyUniform4fv(location, size, f);       break;

-				case GL_FLOAT_MAT2:   applyUniformMatrix2fv(location, size, f);   break;

-				case GL_FLOAT_MAT2x3: applyUniformMatrix2x3fv(location, size, f); break;

-				case GL_FLOAT_MAT2x4: applyUniformMatrix2x4fv(location, size, f); break;

-				case GL_FLOAT_MAT3x2: applyUniformMatrix3x2fv(location, size, f); break;

-				case GL_FLOAT_MAT3:   applyUniformMatrix3fv(location, size, f);   break;

-				case GL_FLOAT_MAT3x4: applyUniformMatrix3x4fv(location, size, f); break;

-				case GL_FLOAT_MAT4x2: applyUniformMatrix4x2fv(location, size, f); break;

-				case GL_FLOAT_MAT4x3: applyUniformMatrix4x3fv(location, size, f); break;

-				case GL_FLOAT_MAT4:   applyUniformMatrix4fv(location, size, f);   break;

-				case GL_SAMPLER_2D:

-				case GL_SAMPLER_CUBE:

-				case GL_SAMPLER_EXTERNAL_OES:

-				case GL_SAMPLER_3D_OES:

-				case GL_SAMPLER_2D_ARRAY:

-				case GL_SAMPLER_2D_SHADOW:

-				case GL_SAMPLER_CUBE_SHADOW:

-				case GL_SAMPLER_2D_ARRAY_SHADOW:

-				case GL_INT_SAMPLER_2D:

-				case GL_UNSIGNED_INT_SAMPLER_2D:

-				case GL_INT_SAMPLER_CUBE:

-				case GL_UNSIGNED_INT_SAMPLER_CUBE:

-				case GL_INT_SAMPLER_3D:

-				case GL_UNSIGNED_INT_SAMPLER_3D:

-				case GL_INT_SAMPLER_2D_ARRAY:

-				case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:

-				case GL_INT:        applyUniform1iv(location, size, i);       break;

-				case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;

-				case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;

-				case GL_INT_VEC4:   applyUniform4iv(location, size, i);       break;

-				case GL_UNSIGNED_INT:      applyUniform1uiv(location, size, ui); break;

-				case GL_UNSIGNED_INT_VEC2: applyUniform2uiv(location, size, ui); break;

-				case GL_UNSIGNED_INT_VEC3: applyUniform3uiv(location, size, ui); break;

-				case GL_UNSIGNED_INT_VEC4: applyUniform4uiv(location, size, ui); break;

-				default:

-					UNREACHABLE(targetUniform->type);

-				}

-

-				targetUniform->dirty = false;

-			}

-		}

-	}

-

-	void Program::applyUniformBuffers(BufferBinding* uniformBuffers)

-	{

-		GLint vertexUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];

-		GLint fragmentUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];

-

-		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)

-		{

-			vertexUniformBuffers[bufferBindingIndex] = -1;

-		}

-

-		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)

-		{

-			fragmentUniformBuffers[bufferBindingIndex] = -1;

-		}

-

-		int vertexUniformBufferIndex = 0;

-		int fragmentUniformBufferIndex = 0;

-		for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)

-		{

-			UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];

-

-			// Unnecessary to apply an unreferenced standard or shared UBO

-			if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())

-			{

-				continue;

-			}

-

-			GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];

-

-			if(uniformBlock.isReferencedByVertexShader())

-			{

-				vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;

-			}

-

-			if(uniformBlock.isReferencedByFragmentShader())

-			{

-				fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;

-			}

-		}

-

-		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)

-		{

-			int index = vertexUniformBuffers[bufferBindingIndex];

-			device->VertexProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? uniformBuffers[index].get()->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);

-			index = fragmentUniformBuffers[bufferBindingIndex];

-			device->PixelProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? uniformBuffers[index].get()->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);

-		}

-	}

-

-	void Program::applyTransformFeedback(TransformFeedback* transformFeedback)

-	{

-		// Make sure the flags will fit in a 64 bit unsigned int variable

-		ASSERT(sw::max<int>(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) <= 64);

-

-		BufferBinding* transformFeedbackBuffers = (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) ? transformFeedback->getBuffers() : nullptr;

-

-		uint64_t enableTransformFeedback = 0;

-		if(!transformFeedbackBuffers)

-		{

-			for(unsigned int index = 0; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)

-			{

-				device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);

-			}

-			device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);

-			return;

-		}

-

-		unsigned int maxVaryings = transformFeedbackLinkedVaryings.size();

-		switch(transformFeedbackBufferMode)

-		{

-		case GL_SEPARATE_ATTRIBS:

-		{

-			maxVaryings = sw::min(maxVaryings, (unsigned int)MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);

-			// Attribs go to separate buffers

-			for(unsigned int index = 0; index < maxVaryings; ++index)

-			{

-				int size = transformFeedbackLinkedVaryings[index].size;

-				int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);

-				int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);

-				int nbRegs = rowCount > 1 ? colCount * size : size;

-				int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;

-				int componentStride = rowCount * colCount * size;

-				int baseOffset = transformFeedback->vertexOffset() * componentStride * sizeof(float);

-				device->VertexProcessor::setTransformFeedbackBuffer(index,

-					transformFeedbackBuffers[index].get()->getResource(),

-					transformFeedbackBuffers[index].getOffset() + baseOffset,

-					transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,

-					nbRegs, nbComponentsPerReg, componentStride);

-				enableTransformFeedback |= 1ULL << index;

-			}

-		}

-			break;

-		case GL_INTERLEAVED_ATTRIBS:

-		{

-			// OpenGL ES 3.0.4 spec, section 2.15.2:

-			// In INTERLEAVED_ATTRIBS mode, the values of one or more output variables

-			// written by a vertex shader are written, interleaved, into the buffer object

-			// bound to the first transform feedback binding point (index = 0).

-			sw::Resource* resource = transformFeedbackBuffers[0].get()->getResource();

-			int componentStride = totalLinkedVaryingsComponents;

-			int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float));

-			maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);

-			size_t totalComponents = 0;

-			for(unsigned int index = 0; index < maxVaryings; ++index)

-			{

-				int size = transformFeedbackLinkedVaryings[index].size;

-				int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);

-				int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);

-				int nbRegs = rowCount > 1 ? colCount * size : size;

-				int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;

-				device->VertexProcessor::setTransformFeedbackBuffer(index, resource,

-					baseOffset + (totalComponents * sizeof(float)),

-					transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,

-					nbRegs, nbComponentsPerReg, componentStride);

-				totalComponents += rowCount * colCount * size;

-				enableTransformFeedback |= 1ULL << index;

-			}

-		}

-			break;

-		default:

-			UNREACHABLE(transformFeedbackBufferMode);

-			break;

-		}

-

-		// Unset all other transform feedback buffers

-		for(unsigned int index = maxVaryings; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)

-		{

-			device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);

-		}

-

-		device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);

-	}

-

-	bool Program::linkVaryings()

-	{

-		for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)

-		{

-			bool matched = false;

-

-			for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); ++output)

-			{

-				if(output->name == input->name)

-				{

-					if(output->type != input->type || output->size() != input->size())

-					{

-						appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());

-

-						return false;

-					}

-

-					matched = true;

-					break;

-				}

-			}

-

-			if(!matched)

-			{

-				appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());

-

-				return false;

-			}

-		}

-

-		glsl::VaryingList &psVaryings = fragmentShader->varyings;

-		glsl::VaryingList &vsVaryings = vertexShader->varyings;

-

-		for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); ++output)

-		{

-			for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); ++input)

-			{

-				if(output->name == input->name)

-				{

-					int in = input->reg;

-					int out = output->reg;

-					int components = VariableRegisterSize(output->type);

-					int registers = VariableRegisterCount(output->type) * output->size();

-

-					ASSERT(in >= 0);

-

-					if(in + registers > MAX_VARYING_VECTORS)

-					{

-						appendToInfoLog("Too many varyings");

-						return false;

-					}

-

-					if(out >= 0)

-					{

-						if(out + registers > MAX_VARYING_VECTORS)

-						{

-							appendToInfoLog("Too many varyings");

-							return false;

-						}

-

-						for(int i = 0; i < registers; i++)

-						{

-							if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-							if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-							if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-							if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);

-						}

-					}

-					else   // Vertex varying is declared but not written to

-					{

-						for(int i = 0; i < registers; i++)

-						{

-							if(components >= 1) pixelBinary->semantic[in + i][0] = sw::Shader::Semantic();

-							if(components >= 2) pixelBinary->semantic[in + i][1] = sw::Shader::Semantic();

-							if(components >= 3) pixelBinary->semantic[in + i][2] = sw::Shader::Semantic();

-							if(components >= 4) pixelBinary->semantic[in + i][3] = sw::Shader::Semantic();

-						}

-					}

-

-					break;

-				}

-			}

-		}

-

-		return true;

-	}

-

-	bool Program::linkTransformFeedback()

-	{

-		size_t totalComponents = 0;

-		totalLinkedVaryingsComponents = 0;

-

-		std::set<std::string> uniqueNames;

-

-		for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)

-		{

-			size_t subscript = GL_INVALID_INDEX;

-			std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, &subscript);

-			bool hasSubscript = (subscript != GL_INVALID_INDEX);

-

-			if(tfVaryingName.find('[') != std::string::npos)

-			{

-				appendToInfoLog("Capture of array sub-elements is undefined and not supported.");

-				return false;

-			}

-

-			bool found = false;

-			for(const glsl::Varying varying : vertexShader->varyings)

-			{

-				if(tfVaryingName == varying.name)

-				{

-					if(uniqueNames.count(indexedTfVaryingName) > 0)

-					{

-						appendToInfoLog("Two transform feedback varyings specify the same output variable (%s)", indexedTfVaryingName.c_str());

-						return false;

-					}

-					uniqueNames.insert(indexedTfVaryingName);

-

-					if(hasSubscript && ((static_cast<int>(subscript)) >= varying.size()))

-					{

-						appendToInfoLog("Specified transform feedback varying index out of bounds (%s)", indexedTfVaryingName.c_str());

-						return false;

-					}

-

-					size_t size = hasSubscript ? 1 : varying.size();

-

-					size_t rowCount = VariableRowCount(varying.type);

-					size_t colCount = VariableColumnCount(varying.type);

-					size_t componentCount = rowCount * colCount * size;

-					if(transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&

-					   componentCount > sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)

-					{

-						appendToInfoLog("Transform feedback varying's %s components (%d) exceed the maximum separate components (%d).",

-						                varying.name.c_str(), componentCount, sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);

-						return false;

-					}

-

-					totalComponents += componentCount;

-

-					int reg = varying.reg;

-					if(hasSubscript)

-					{

-						reg += rowCount > 1 ? colCount * subscript : subscript;

-					}

-					int col = varying.col;

-					if(tfVaryingName == "gl_PointSize")

-					{

-						// Point size is stored in the y element of the vector, not the x element

-						col = 1; // FIXME: varying.col could already contain this information

-					}

-					transformFeedbackLinkedVaryings.push_back(LinkedVarying(varying.name, varying.type, size, reg, col));

-

-					found = true;

-					break;

-				}

-			}

-

-			if(!found)

-			{

-				appendToInfoLog("Transform feedback varying %s does not exist in the vertex shader.", tfVaryingName.c_str());

-				return false;

-			}

-		}

-

-		if(transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&

-		   totalComponents > sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)

-		{

-			appendToInfoLog("Transform feedback varying total components (%d) exceed the maximum separate components (%d).",

-			                totalComponents, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);

-			return false;

-		}

-

-		totalLinkedVaryingsComponents = totalComponents;

-

-		return true;

-	}

-

-	// Links the code of the vertex and pixel shader by matching up their varyings,

-	// compiling them into binaries, determining the attribute mappings, and collecting

-	// a list of uniforms

-	void Program::link()

-	{

-		unlink();

-

-		resetUniformBlockBindings();

-

-		if(!fragmentShader || !fragmentShader->isCompiled())

-		{

-			return;

-		}

-

-		if(!vertexShader || !vertexShader->isCompiled())

-		{

-			return;

-		}

-

-		vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());

-		pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());

-

-		if(!linkVaryings())

-		{

-			return;

-		}

-

-		if(!linkAttributes())

-		{

-			return;

-		}

-

-		// Link uniform blocks before uniforms to make it easy to assign block indices to fields

-		if(!linkUniformBlocks(vertexShader, fragmentShader))

-		{

-			return;

-		}

-

-		if(!linkUniforms(fragmentShader))

-		{

-			return;

-		}

-

-		if(!linkUniforms(vertexShader))

-		{

-			return;

-		}

-

-		if(!linkTransformFeedback())

-		{

-			return;

-		}

-

-		linked = true;   // Success

-	}

-

-	// Determines the mapping between GL attributes and vertex stream usage indices

-	bool Program::linkAttributes()

-	{

-		unsigned int usedLocations = 0;

-

-		// Link attributes that have a binding location

-		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)

-		{

-			int location = getAttributeBinding(*attribute);

-

-			if(location != -1)   // Set by glBindAttribLocation

-			{

-				int rows = VariableRegisterCount(attribute->type);

-

-				if(rows + location > MAX_VERTEX_ATTRIBS)

-				{

-					appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);

-					return false;

-				}

-

-				// In GLSL 3.00, attribute aliasing produces a link error

-				// In GLSL 1.00, attribute aliasing is allowed

-				if(egl::getClientVersion() >= 3)

-				{

-					for(int i = 0; i < rows; i++)

-					{

-						if(!linkedAttribute[location + i].name.empty())

-						{

-							appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute->name.c_str(), linkedAttribute[location].name.c_str(), location);

-							return false;

-						}

-					}

-				}

-

-				for(int i = 0; i < rows; i++)

-				{

-					linkedAttribute[location + i] = *attribute;

-					usedLocations |= 1 << (location + i);

-				}

-			}

-		}

-

-		// Link attributes that don't have a binding location

-		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)

-		{

-			int location = getAttributeBinding(*attribute);

-

-			if(location == -1)   // Not set by glBindAttribLocation

-			{

-				int rows = VariableRegisterCount(attribute->type);

-				int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);

-

-				if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)

-				{

-					appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());

-					return false;   // Fail to link

-				}

-

-				for(int i = 0; i < rows; i++)

-				{

-					linkedAttribute[availableIndex + i] = *attribute;

-				}

-			}

-		}

-

-		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )

-		{

-			int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);

-			int rows = std::max(VariableRegisterCount(linkedAttribute[attributeIndex].type), 1);

-

-			for(int r = 0; r < rows; r++)

-			{

-				attributeStream[attributeIndex++] = index++;

-			}

-		}

-

-		return true;

-	}

-

-	int Program::getAttributeBinding(const glsl::Attribute &attribute)

-	{

-		if(attribute.location != -1)

-		{

-			return attribute.location;

-		}

-

-		for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)

-		{

-			if(attributeBinding[location].find(attribute.name.c_str()) != attributeBinding[location].end())

-			{

-				return location;

-			}

-		}

-

-		return -1;

-	}

-

-	bool Program::linkUniforms(const Shader *shader)

-	{

-		const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;

-

-		for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)

-		{

-			const glsl::Uniform &uniform = activeUniforms[uniformIndex];

-

-			unsigned int blockIndex = GL_INVALID_INDEX;

-			if(uniform.blockId >= 0)

-			{

-				const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;

-				ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());

-				blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);

-				ASSERT(blockIndex != GL_INVALID_INDEX);

-			}

-			if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex)))

-			{

-				return false;

-			}

-		}

-

-		return true;

-	}

-

-	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo)

-	{

-		if(IsSamplerUniform(type))

-	    {

-			int index = registerIndex;

-

-			do

-			{

-				if(shader == GL_VERTEX_SHADER)

-				{

-					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)

-					{

-						samplersVS[index].active = true;

-

-						switch(type)

-						{

-						default:                      UNREACHABLE(type);

-						case GL_INT_SAMPLER_2D:

-						case GL_UNSIGNED_INT_SAMPLER_2D:

-						case GL_SAMPLER_2D_SHADOW:

-						case GL_SAMPLER_2D:           samplersVS[index].textureType = TEXTURE_2D;       break;

-						case GL_INT_SAMPLER_CUBE:

-						case GL_UNSIGNED_INT_SAMPLER_CUBE:

-						case GL_SAMPLER_CUBE_SHADOW:

-						case GL_SAMPLER_CUBE:         samplersVS[index].textureType = TEXTURE_CUBE;     break;

-						case GL_INT_SAMPLER_3D:

-						case GL_UNSIGNED_INT_SAMPLER_3D:

-						case GL_SAMPLER_3D_OES:       samplersVS[index].textureType = TEXTURE_3D;       break;

-						case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break;

-						case GL_INT_SAMPLER_2D_ARRAY:

-						case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:

-						case GL_SAMPLER_2D_ARRAY_SHADOW:

-						case GL_SAMPLER_2D_ARRAY:     samplersVS[index].textureType = TEXTURE_2D_ARRAY; break;

-						}

-

-						samplersVS[index].logicalTextureUnit = 0;

-					}

-					else

-					{

-					   appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);

-					   return false;

-					}

-				}

-				else if(shader == GL_FRAGMENT_SHADER)

-				{

-					if(index < MAX_TEXTURE_IMAGE_UNITS)

-					{

-						samplersPS[index].active = true;

-

-						switch(type)

-						{

-						default:                      UNREACHABLE(type);

-						case GL_INT_SAMPLER_2D:

-						case GL_UNSIGNED_INT_SAMPLER_2D:

-						case GL_SAMPLER_2D_SHADOW:

-						case GL_SAMPLER_2D:           samplersPS[index].textureType = TEXTURE_2D;       break;

-						case GL_INT_SAMPLER_CUBE:

-						case GL_UNSIGNED_INT_SAMPLER_CUBE:

-						case GL_SAMPLER_CUBE_SHADOW:

-						case GL_SAMPLER_CUBE:         samplersPS[index].textureType = TEXTURE_CUBE;     break;

-						case GL_INT_SAMPLER_3D:

-						case GL_UNSIGNED_INT_SAMPLER_3D:

-						case GL_SAMPLER_3D_OES:       samplersPS[index].textureType = TEXTURE_3D;       break;

-						case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break;

-						case GL_INT_SAMPLER_2D_ARRAY:

-						case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:

-						case GL_SAMPLER_2D_ARRAY_SHADOW:

-						case GL_SAMPLER_2D_ARRAY:     samplersPS[index].textureType = TEXTURE_2D_ARRAY; break;

-						}

-

-						samplersPS[index].logicalTextureUnit = 0;

-					}

-					else

-					{

-						appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);

-						return false;

-					}

-				}

-				else UNREACHABLE(shader);

-

-				index++;

-			}

-			while(index < registerIndex + static_cast<int>(arraySize));

-	    }

-

-		Uniform *uniform = 0;

-		GLint location = getUniformLocation(name);

-

-		if(location >= 0)   // Previously defined, types must match

-		{

-			uniform = uniforms[uniformIndex[location].index];

-

-			if(uniform->type != type)

-			{

-				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());

-				return false;

-			}

-

-			if(uniform->precision != precision)

-			{

-				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());

-				return false;

-			}

-		}

-		else

-		{

-			uniform = new Uniform(type, precision, name, arraySize, blockInfo);

-		}

-

-		if(!uniform)

-		{

-			return false;

-		}

-

-		if(shader == GL_VERTEX_SHADER)

-		{

-			uniform->vsRegisterIndex = registerIndex;

-		}

-		else if(shader == GL_FRAGMENT_SHADER)

-		{

-			uniform->psRegisterIndex = registerIndex;

-		}

-		else UNREACHABLE(shader);

-

-		if(location == -1)   // Not previously defined

-		{

-			uniforms.push_back(uniform);

-			size_t index = uniforms.size() - 1;

-

-			for(int i = 0; i < uniform->size(); i++)

-			{

-				uniformIndex.push_back(UniformLocation(name, i, index));

-			}

-		}

-

-		if(shader == GL_VERTEX_SHADER)

-		{

-			if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)

-			{

-				appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);

-				return false;

-			}

-		}

-		else if(shader == GL_FRAGMENT_SHADER)

-		{

-			if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)

-			{

-				appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);

-				return false;

-			}

-		}

-		else UNREACHABLE(shader);

-

-		return true;

-	}

-

-	bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)

-	{

-		// validate blocks for the same member types

-		if(block1.fields.size() != block2.fields.size())

-		{

-			return false;

-		}

-		if(block1.arraySize != block2.arraySize)

-		{

-			return false;

-		}

-		if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)

-		{

-			return false;

-		}

-		const size_t numBlockMembers = block1.fields.size();

-		for(size_t blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)

-		{

-			const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]];

-			const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]];

-			if(member1.name != member2.name ||

-			   member1.arraySize != member2.arraySize ||

-			   member1.precision != member2.precision ||

-			   member1.type != member2.type)

-			{

-				return false;

-			}

-		}

-		return true;

-	}

-

-	bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader)

-	{

-		const glsl::ActiveUniformBlocks &vertexUniformBlocks = vertexShader->activeUniformBlocks;

-		const glsl::ActiveUniformBlocks &fragmentUniformBlocks = fragmentShader->activeUniformBlocks;

-		// Check that interface blocks defined in the vertex and fragment shaders are identical

-		typedef std::map<std::string, const glsl::UniformBlock*> UniformBlockMap;

-		UniformBlockMap linkedUniformBlocks;

-		for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)

-		{

-			const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex];

-			linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock;

-		}

-		for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)

-		{

-			const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex];

-			UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name);

-			if(entry != linkedUniformBlocks.end())

-			{

-				const glsl::UniformBlock &vertexUniformBlock = *entry->second;

-				if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader))

-				{

-					return false;

-				}

-			}

-		}

-		for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)

-		{

-			const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex];

-			if(!defineUniformBlock(vertexShader, uniformBlock))

-			{

-				return false;

-			}

-		}

-		for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)

-		{

-			const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex];

-			if(!defineUniformBlock(fragmentShader, uniformBlock))

-			{

-				return false;

-			}

-		}

-		return true;

-	}

-

-	bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)

-	{

-		GLuint blockIndex = getUniformBlockIndex(block.name);

-

-		if(blockIndex == GL_INVALID_INDEX)

-		{

-			const std::vector<int>& fields = block.fields;

-			std::vector<unsigned int> memberUniformIndexes;

-			for(size_t i = 0; i < fields.size(); ++i)

-			{

-				memberUniformIndexes.push_back(fields[i]);

-			}

-

-			if(block.arraySize > 0)

-			{

-				int regIndex = block.registerIndex;

-				int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);

-				for(unsigned int i = 0; i < block.arraySize; ++i, regIndex += regInc)

-				{

-					uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes));

-					uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex);

-				}

-			}

-			else

-			{

-				uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));

-				uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);

-			}

-		}

-		else

-		{

-			int regIndex = block.registerIndex;

-			int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);

-			int nbBlocks = (block.arraySize > 0) ? block.arraySize : 1;

-			for(int i = 0; i < nbBlocks; ++i, regIndex += regInc)

-			{

-				uniformBlocks[blockIndex + i]->setRegisterIndex(shader->getType(), regIndex);

-			}

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform(GLint location, float* data)

-	{

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-

-		if(targetUniform->psRegisterIndex != -1)

-		{

-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, data, targetUniform->registerCount());

-		}

-

-		if(targetUniform->vsRegisterIndex != -1)

-		{

-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, data, targetUniform->registerCount());

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = 0;

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 1;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 2;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][3] = 0;

-

-			v += 3;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)

-	{

-		int vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-			vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

-

-			v += 4;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = 0;

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 1;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 2;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		float vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = v[2];

-			vector[i][3] = 0;

-

-			v += 3;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)

-	{

-		return applyUniform(location, (float*)v);

-	}

-

-	bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;

-

-			value += 4;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;

-

-			value += 6;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3];

-			matrix[i][1][0] = value[4];	matrix[i][1][1] = value[5];	matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7];

-

-			value += 8;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2];	matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5];	matrix[i][1][3] = 0;

-			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];	matrix[i][2][2] = value[8];	matrix[i][2][3] = 0;

-

-			value += 9;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;

-			matrix[i][2][0] = value[4];	matrix[i][2][1] = value[5];	matrix[i][2][2] = 0; matrix[i][2][3] = 0;

-

-			value += 6;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; 	matrix[i][0][3] = value[3];

-			matrix[i][1][0] = value[4];	matrix[i][1][1] = value[5];	matrix[i][1][2] = value[6]; 	matrix[i][1][3] = value[7];

-			matrix[i][2][0] = value[8];	matrix[i][2][1] = value[9];	matrix[i][2][2] = value[10];	matrix[i][2][3] = value[11];

-

-			value += 12;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		return applyUniform(location, (float*)value);

-	}

-

-	bool Program::applyUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;

-			matrix[i][2][0] = value[4];	matrix[i][2][1] = value[5];	matrix[i][2][2] = 0; matrix[i][2][3] = 0;

-			matrix[i][3][0] = value[6];	matrix[i][3][1] = value[7];	matrix[i][3][2] = 0; matrix[i][3][3] = 0;

-

-			value += 8;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value)

-	{

-		float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];  matrix[i][0][2] = value[2];  matrix[i][0][3] = 0;

-			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];  matrix[i][1][2] = value[5];  matrix[i][1][3] = 0;

-			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];  matrix[i][2][2] = value[8];  matrix[i][2][3] = 0;

-			matrix[i][3][0] = value[9];	matrix[i][3][1] = value[10]; matrix[i][3][2] = value[11]; matrix[i][3][3] = 0;

-

-			value += 12;

-		}

-

-		return applyUniform(location, (float*)matrix);

-	}

-

-	bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)

-	{

-		GLint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[i];

-			vector[i][1] = 0;

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		if(IsSamplerUniform(targetUniform->type))

-		{

-			if(targetUniform->psRegisterIndex != -1)

-			{

-				for(int i = 0; i < count; i++)

-				{

-					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;

-

-					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)

-					{

-						ASSERT(samplersPS[samplerIndex].active);

-						samplersPS[samplerIndex].logicalTextureUnit = v[i];

-					}

-				}

-			}

-

-			if(targetUniform->vsRegisterIndex != -1)

-			{

-				for(int i = 0; i < count; i++)

-				{

-					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;

-

-					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)

-					{

-						ASSERT(samplersVS[samplerIndex].active);

-						samplersVS[samplerIndex].logicalTextureUnit = v[i];

-					}

-				}

-			}

-		}

-		else

-		{

-			return applyUniform(location, (float*)vector);

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)

-	{

-		GLint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 2;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)

-	{

-		GLint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = v[2];

-			vector[i][3] = 0;

-

-			v += 3;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)

-	{

-		GLint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = v[2];

-			vector[i][3] = v[3];

-

-			v += 4;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform1uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		GLuint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[i];

-			vector[i][1] = 0;

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-		}

-

-		Uniform *targetUniform = uniforms[uniformIndex[location].index];

-		if(IsSamplerUniform(targetUniform->type))

-		{

-			if(targetUniform->psRegisterIndex != -1)

-			{

-				for(int i = 0; i < count; i++)

-				{

-					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;

-

-					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)

-					{

-						ASSERT(samplersPS[samplerIndex].active);

-						samplersPS[samplerIndex].logicalTextureUnit = v[i];

-					}

-				}

-			}

-

-			if(targetUniform->vsRegisterIndex != -1)

-			{

-				for(int i = 0; i < count; i++)

-				{

-					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;

-

-					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)

-					{

-						ASSERT(samplersVS[samplerIndex].active);

-						samplersVS[samplerIndex].logicalTextureUnit = v[i];

-					}

-				}

-			}

-		}

-		else

-		{

-			return applyUniform(location, (float*)vector);

-		}

-

-		return true;

-	}

-

-	bool Program::applyUniform2uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		GLuint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = 0;

-			vector[i][3] = 0;

-

-			v += 2;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform3uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		GLuint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = v[2];

-			vector[i][3] = 0;

-

-			v += 3;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	bool Program::applyUniform4uiv(GLint location, GLsizei count, const GLuint *v)

-	{

-		GLuint vector[MAX_UNIFORM_VECTORS][4];

-

-		for(int i = 0; i < count; i++)

-		{

-			vector[i][0] = v[0];

-			vector[i][1] = v[1];

-			vector[i][2] = v[2];

-			vector[i][3] = v[3];

-

-			v += 4;

-		}

-

-		return applyUniform(location, (float*)vector);

-	}

-

-	void Program::appendToInfoLog(const char *format, ...)

-	{

-		if(!format)

-		{

-			return;

-		}

-

-		char info[1024];

-

-		va_list vararg;

-		va_start(vararg, format);

-		vsnprintf(info, sizeof(info), format, vararg);

-		va_end(vararg);

-

-		size_t infoLength = strlen(info);

-

-		if(!infoLog)

-		{

-			infoLog = new char[infoLength + 2];

-			strcpy(infoLog, info);

-			strcpy(infoLog + infoLength, "\n");

-		}

-		else

-		{

-			size_t logLength = strlen(infoLog);

-			char *newLog = new char[logLength + infoLength + 2];

-			strcpy(newLog, infoLog);

-			strcpy(newLog + logLength, info);

-			strcpy(newLog + logLength + infoLength, "\n");

-

-			delete[] infoLog;

-			infoLog = newLog;

-		}

-	}

-

-	void Program::resetInfoLog()

-	{

-		if(infoLog)

-		{

-			delete[] infoLog;

-			infoLog = 0;

-		}

-	}

-

-	// Returns the program object to an unlinked state, before re-linking, or at destruction

-	void Program::unlink()

-	{

-		delete vertexBinary;

-		vertexBinary = 0;

-		delete pixelBinary;

-		pixelBinary = 0;

-

-		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)

-		{

-			linkedAttribute[index].name.clear();

-			attributeStream[index] = -1;

-		}

-

-		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)

-		{

-			samplersPS[index].active = false;

-		}

-

-		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)

-		{

-			samplersVS[index].active = false;

-		}

-

-		while(!uniforms.empty())

-		{

-			delete uniforms.back();

-			uniforms.pop_back();

-		}

-

-		while(!uniformBlocks.empty())

-		{

-			delete uniformBlocks.back();

-			uniformBlocks.pop_back();

-		}

-

-		uniformIndex.clear();

-		transformFeedbackLinkedVaryings.clear();

-

-		delete[] infoLog;

-		infoLog = 0;

-

-		linked = false;

-	}

-

-	bool Program::isLinked() const

-	{

-		return linked;

-	}

-

-	bool Program::isValidated() const

-	{

-		return validated;

-	}

-

-	GLint Program::getBinaryLength() const

-	{

-		UNIMPLEMENTED();

-		return 0;

-	}

-

-	void Program::release()

-	{

-		referenceCount--;

-

-		if(referenceCount == 0 && orphaned)

-		{

-			resourceManager->deleteProgram(handle);

-		}

-	}

-

-	void Program::addRef()

-	{

-		referenceCount++;

-	}

-

-	unsigned int Program::getRefCount() const

-	{

-		return referenceCount;

-	}

-

-	unsigned int Program::getSerial() const

-	{

-		return serial;

-	}

-

-	unsigned int Program::issueSerial()

-	{

-		return currentSerial++;

-	}

-

-	size_t Program::getInfoLogLength() const

-	{

-		if(!infoLog)

-		{

-			return 0;

-		}

-		else

-		{

-		   return strlen(infoLog) + 1;

-		}

-	}

-

-	void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)

-	{

-		int index = 0;

-

-		if(bufSize > 0)

-		{

-			if(infoLog)

-			{

-				index = std::min(bufSize - 1, (int)strlen(infoLog));

-				memcpy(buffer, infoLog, index);

-			}

-

-			buffer[index] = '\0';

-		}

-

-		if(length)

-		{

-			*length = index;

-		}

-	}

-

-	void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)

-	{

-		int total = 0;

-

-		if(vertexShader && (total < maxCount))

-		{

-			shaders[total++] = vertexShader->getName();

-		}

-

-		if(fragmentShader && (total < maxCount))

-		{

-			shaders[total++] = fragmentShader->getName();

-		}

-

-		if(count)

-		{

-			*count = total;

-		}

-	}

-

-	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const

-	{

-		// Skip over inactive attributes

-		unsigned int activeAttribute = 0;

-		unsigned int attribute;

-		for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)

-		{

-			if(linkedAttribute[attribute].name.empty())

-			{

-				continue;

-			}

-

-			if(activeAttribute == index)

-			{

-				break;

-			}

-

-			activeAttribute++;

-		}

-

-		if(bufsize > 0)

-		{

-			const char *string = linkedAttribute[attribute].name.c_str();

-

-			strncpy(name, string, bufsize);

-			name[bufsize - 1] = '\0';

-

-			if(length)

-			{

-				*length = strlen(name);

-			}

-		}

-

-		*size = 1;   // Always a single 'type' instance

-

-		*type = linkedAttribute[attribute].type;

-	}

-

-	size_t Program::getActiveAttributeCount() const

-	{

-		int count = 0;

-

-		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)

-		{

-			if(!linkedAttribute[attributeIndex].name.empty())

-			{

-				count++;

-			}

-		}

-

-		return count;

-	}

-

-	GLint Program::getActiveAttributeMaxLength() const

-	{

-		int maxLength = 0;

-

-		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)

-		{

-			if(!linkedAttribute[attributeIndex].name.empty())

-			{

-				maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);

-			}

-		}

-

-		return maxLength;

-	}

-

-	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const

-	{

-		if(bufsize > 0)

-		{

-			std::string string = uniforms[index]->name;

-

-			if(uniforms[index]->isArray())

-			{

-				string += "[0]";

-			}

-

-			strncpy(name, string.c_str(), bufsize);

-			name[bufsize - 1] = '\0';

-

-			if(length)

-			{

-				*length = strlen(name);

-			}

-		}

-

-		*size = uniforms[index]->size();

-

-		*type = uniforms[index]->type;

-	}

-

-	size_t Program::getActiveUniformCount() const

-	{

-		return uniforms.size();

-	}

-

-	GLint Program::getActiveUniformMaxLength() const

-	{

-		int maxLength = 0;

-

-		size_t numUniforms = uniforms.size();

-		for(size_t uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)

-		{

-			if(!uniforms[uniformIndex]->name.empty())

-			{

-				int length = (int)(uniforms[uniformIndex]->name.length() + 1);

-				if(uniforms[uniformIndex]->isArray())

-				{

-					length += 3;  // Counting in "[0]".

-				}

-				maxLength = std::max(length, maxLength);

-			}

-		}

-

-		return maxLength;

-	}

-

-	GLint Program::getActiveUniformi(GLuint index, GLenum pname) const

-	{

-		const Uniform& uniform = *uniforms[index];

-		switch(pname)

-		{

-		case GL_UNIFORM_TYPE:         return static_cast<GLint>(uniform.type);

-		case GL_UNIFORM_SIZE:         return static_cast<GLint>(uniform.size());

-		case GL_UNIFORM_NAME_LENGTH:  return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));

-		case GL_UNIFORM_BLOCK_INDEX:  return uniform.blockInfo.index;

-		case GL_UNIFORM_OFFSET:       return uniform.blockInfo.offset;

-		case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;

-		case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;

-		case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);

-		default:

-			UNREACHABLE(pname);

-			break;

-		}

-		return 0;

-	}

-

-	void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const

-	{

-		ASSERT(index < getActiveUniformBlockCount());

-

-		const UniformBlock &uniformBlock = *uniformBlocks[index];

-

-		if(bufSize > 0)

-		{

-			std::string string = uniformBlock.name;

-

-			if(uniformBlock.isArrayElement())

-			{

-				std::ostringstream elementIndex;

-				elementIndex << uniformBlock.elementIndex;

-				string += "[" + elementIndex.str()  + "]";

-			}

-

-			strncpy(name, string.c_str(), bufSize);

-			name[bufSize - 1] = '\0';

-

-			if(length)

-			{

-				*length = strlen(name);

-			}

-		}

-	}

-

-	size_t Program::getActiveUniformBlockCount() const

-	{

-		return uniformBlocks.size();

-	}

-

-	GLint Program::getActiveUniformBlockMaxLength() const

-	{

-		size_t maxLength = 0;

-

-		if(isLinked())

-		{

-			size_t numUniformBlocks = getActiveUniformBlockCount();

-			for(size_t uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)

-			{

-				const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];

-				if(!uniformBlock.name.empty())

-				{

-					size_t length = uniformBlock.name.length() + 1;

-

-					// Counting in "[0]".

-					const int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);

-

-					maxLength = std::max(length + arrayLength, maxLength);

-				}

-			}

-		}

-

-		return maxLength;

-	}

-

-	void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)

-	{

-		transformFeedbackVaryings.resize(count);

-		for(GLsizei i = 0; i < count; i++)

-		{

-			transformFeedbackVaryings[i] = varyings[i];

-		}

-

-		transformFeedbackBufferMode = bufferMode;

-	}

-

-	void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const

-	{

-		if(linked)

-		{

-			ASSERT(index < transformFeedbackLinkedVaryings.size());

-			const LinkedVarying &varying = transformFeedbackLinkedVaryings[index];

-			GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));

-			if(length)

-			{

-				*length = lastNameIdx;

-			}

-			if(size)

-			{

-				*size = varying.size;

-			}

-			if(type)

-			{

-				*type = varying.type;

-			}

-			if(name)

-			{

-				memcpy(name, varying.name.c_str(), lastNameIdx);

-				name[lastNameIdx] = '\0';

-			}

-		}

-	}

-

-	GLsizei Program::getTransformFeedbackVaryingCount() const

-	{

-		if(linked)

-		{

-			return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size());

-		}

-		else

-		{

-			return 0;

-		}

-	}

-

-	GLsizei Program::getTransformFeedbackVaryingMaxLength() const

-	{

-		if(linked)

-		{

-			GLsizei maxSize = 0;

-			for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++)

-			{

-				const LinkedVarying &varying = transformFeedbackLinkedVaryings[i];

-				maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));

-			}

-

-			return maxSize;

-		}

-		else

-		{

-			return 0;

-		}

-	}

-

-	GLenum Program::getTransformFeedbackBufferMode() const

-	{

-		return transformFeedbackBufferMode;

-	}

-

-	void Program::flagForDeletion()

-	{

-		orphaned = true;

-	}

-

-	bool Program::isFlaggedForDeletion() const

-	{

-		return orphaned;

-	}

-

-	void Program::validate()

-	{

-		resetInfoLog();

-

-		if(!isLinked())

-		{

-			appendToInfoLog("Program has not been successfully linked.");

-			validated = false;

-		}

-		else

-		{

-			applyUniforms();

-			if(!validateSamplers(true))

-			{

-				validated = false;

-			}

-			else

-			{

-				validated = true;

-			}

-		}

-	}

-

-	bool Program::validateSamplers(bool logErrors)

-	{

-		// if any two active samplers in a program are of different types, but refer to the same

-		// texture image unit, and this is the current program, then ValidateProgram will fail, and

-		// DrawArrays and DrawElements will issue the INVALID_OPERATION error.

-

-		TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];

-

-		for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)

-		{

-			textureUnitType[i] = TEXTURE_UNKNOWN;

-		}

-

-		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)

-		{

-			if(samplersPS[i].active)

-			{

-				unsigned int unit = samplersPS[i].logicalTextureUnit;

-

-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)

-				{

-					if(logErrors)

-					{

-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);

-					}

-

-					return false;

-				}

-

-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)

-				{

-					if(samplersPS[i].textureType != textureUnitType[unit])

-					{

-						if(logErrors)

-						{

-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);

-						}

-

-						return false;

-					}

-				}

-				else

-				{

-					textureUnitType[unit] = samplersPS[i].textureType;

-				}

-			}

-		}

-

-		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)

-		{

-			if(samplersVS[i].active)

-			{

-				unsigned int unit = samplersVS[i].logicalTextureUnit;

-

-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)

-				{

-					if(logErrors)

-					{

-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);

-					}

-

-					return false;

-				}

-

-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)

-				{

-					if(samplersVS[i].textureType != textureUnitType[unit])

-					{

-						if(logErrors)

-						{

-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);

-						}

-

-						return false;

-					}

-				}

-				else

-				{

-					textureUnitType[unit] = samplersVS[i].textureType;

-				}

-			}

-		}

-

-		return true;

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Program.cpp: Implements the Program class. Implements GL program objects
+// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
+
+#include "Program.h"
+
+#include "main.h"
+#include "Buffer.h"
+#include "Shader.h"
+#include "TransformFeedback.h"
+#include "utilities.h"
+#include "common/debug.h"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+
+#include <string>
+#include <stdlib.h>
+
+namespace es2
+{
+	unsigned int Program::currentSerial = 1;
+
+	std::string str(int i)
+	{
+		char buffer[20];
+		sprintf(buffer, "%d", i);
+		return buffer;
+	}
+
+	Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex)
+	{
+		static unsigned int registerSizeStd140 = 4; // std140 packing requires dword alignment
+
+		if(blockIndex >= 0)
+		{
+			index = blockIndex;
+			offset = uniform.blockInfo.offset;
+			arrayStride = uniform.blockInfo.arrayStride;
+			matrixStride = uniform.blockInfo.matrixStride;
+			isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;
+		}
+		else
+		{
+			index = -1;
+			offset = -1;
+			arrayStride = -1;
+			matrixStride = -1;
+			isRowMajorMatrix = false;
+		}
+	}
+
+	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
+	                 const BlockInfo &blockInfo)
+	 : type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)
+	{
+		if(blockInfo.index == -1)
+		{
+			size_t bytes = UniformTypeSize(type) * size();
+			data = new unsigned char[bytes];
+			memset(data, 0, bytes);
+		}
+		else
+		{
+			data = nullptr;
+		}
+		dirty = true;
+
+		psRegisterIndex = -1;
+		vsRegisterIndex = -1;
+	}
+
+	Uniform::~Uniform()
+	{
+		delete[] data;
+	}
+
+	bool Uniform::isArray() const
+	{
+		return arraySize >= 1;
+	}
+
+	int Uniform::size() const
+	{
+		return arraySize > 0 ? arraySize : 1;
+	}
+
+	int Uniform::registerCount() const
+	{
+		return size() * VariableRegisterCount(type);
+	}
+
+	UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes) :
+		name(name), elementIndex(elementIndex), dataSize(dataSize), memberUniformIndexes(memberUniformIndexes), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX)
+	{
+	}
+
+	void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex)
+	{
+		switch(shader)
+		{
+		case GL_VERTEX_SHADER:
+			vsRegisterIndex = registerIndex;
+			break;
+		case GL_FRAGMENT_SHADER:
+			psRegisterIndex = registerIndex;
+			break;
+		default:
+			UNREACHABLE(shader);
+		}
+	}
+
+	bool UniformBlock::isArrayElement() const
+	{
+		return elementIndex != GL_INVALID_INDEX;
+	}
+
+	bool UniformBlock::isReferencedByVertexShader() const
+	{
+		return vsRegisterIndex != GL_INVALID_INDEX;
+	}
+
+	bool UniformBlock::isReferencedByFragmentShader() const
+	{
+		return psRegisterIndex != GL_INVALID_INDEX;
+	}
+
+	UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
+	{
+	}
+
+	LinkedVarying::LinkedVarying()
+	{
+	}
+
+	LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col)
+	 : name(name), type(type), size(size), reg(reg), col(col)
+	{
+	}
+
+	Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)
+	{
+		device = getDevice();
+
+		fragmentShader = 0;
+		vertexShader = 0;
+		pixelBinary = 0;
+		vertexBinary = 0;
+
+		transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS;
+		totalLinkedVaryingsComponents = 0;
+
+		infoLog = 0;
+		validated = false;
+
+		resetUniformBlockBindings();
+		unlink();
+
+		orphaned = false;
+		retrievableBinary = false;
+		referenceCount = 0;
+	}
+
+	Program::~Program()
+	{
+		unlink();
+
+		if(vertexShader)
+		{
+			vertexShader->release();
+		}
+
+		if(fragmentShader)
+		{
+			fragmentShader->release();
+		}
+	}
+
+	bool Program::attachShader(Shader *shader)
+	{
+		if(shader->getType() == GL_VERTEX_SHADER)
+		{
+			if(vertexShader)
+			{
+				return false;
+			}
+
+			vertexShader = (VertexShader*)shader;
+			vertexShader->addRef();
+		}
+		else if(shader->getType() == GL_FRAGMENT_SHADER)
+		{
+			if(fragmentShader)
+			{
+				return false;
+			}
+
+			fragmentShader = (FragmentShader*)shader;
+			fragmentShader->addRef();
+		}
+		else UNREACHABLE(shader->getType());
+
+		return true;
+	}
+
+	bool Program::detachShader(Shader *shader)
+	{
+		if(shader->getType() == GL_VERTEX_SHADER)
+		{
+			if(vertexShader != shader)
+			{
+				return false;
+			}
+
+			vertexShader->release();
+			vertexShader = 0;
+		}
+		else if(shader->getType() == GL_FRAGMENT_SHADER)
+		{
+			if(fragmentShader != shader)
+			{
+				return false;
+			}
+
+			fragmentShader->release();
+			fragmentShader = 0;
+		}
+		else UNREACHABLE(shader->getType());
+
+		return true;
+	}
+
+	int Program::getAttachedShadersCount() const
+	{
+		return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
+	}
+
+	sw::PixelShader *Program::getPixelShader()
+	{
+		return pixelBinary;
+	}
+
+	sw::VertexShader *Program::getVertexShader()
+	{
+		return vertexBinary;
+	}
+
+	void Program::bindAttributeLocation(GLuint index, const char *name)
+	{
+		if(index < MAX_VERTEX_ATTRIBS)
+		{
+			for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+			{
+				attributeBinding[i].erase(name);
+			}
+
+			attributeBinding[index].insert(name);
+		}
+	}
+
+	GLuint Program::getAttributeLocation(const char *name)
+	{
+		if(name)
+		{
+			for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+			{
+				if(linkedAttribute[index].name == std::string(name))
+				{
+					return index;
+				}
+			}
+		}
+
+		return -1;
+	}
+
+	int Program::getAttributeStream(int attributeIndex)
+	{
+		ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
+
+		return attributeStream[attributeIndex];
+	}
+
+	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)
+	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
+	{
+		GLuint logicalTextureUnit = -1;
+
+		switch(type)
+		{
+		case sw::SAMPLER_PIXEL:
+			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
+
+			if(samplersPS[samplerIndex].active)
+			{
+				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
+			}
+			break;
+		case sw::SAMPLER_VERTEX:
+			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
+
+			if(samplersVS[samplerIndex].active)
+			{
+				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
+			}
+			break;
+		default: UNREACHABLE(type);
+		}
+
+		if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+		{
+			return logicalTextureUnit;
+		}
+
+		return -1;
+	}
+
+	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
+	TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)
+	{
+		switch(type)
+		{
+		case sw::SAMPLER_PIXEL:
+			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
+			ASSERT(samplersPS[samplerIndex].active);
+			return samplersPS[samplerIndex].textureType;
+		case sw::SAMPLER_VERTEX:
+			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
+			ASSERT(samplersVS[samplerIndex].active);
+			return samplersVS[samplerIndex].textureType;
+		default: UNREACHABLE(type);
+		}
+
+		return TEXTURE_2D;
+	}
+
+	GLint Program::getUniformLocation(const std::string &name) const
+	{
+		size_t subscript = GL_INVALID_INDEX;
+		std::string baseName = es2::ParseUniformName(name, &subscript);
+
+		size_t numUniforms = uniformIndex.size();
+		for(size_t location = 0; location < numUniforms; location++)
+		{
+			const int index = uniformIndex[location].index;
+			const bool isArray = uniforms[index]->isArray();
+
+			if(uniformIndex[location].name == baseName &&
+			   ((isArray && uniformIndex[location].element == subscript) ||
+			    (subscript == GL_INVALID_INDEX)))
+			{
+				return (GLint)location;
+			}
+		}
+
+		return -1;
+	}
+
+	GLuint Program::getUniformIndex(const std::string &name) const
+	{
+		size_t subscript = GL_INVALID_INDEX;
+		std::string baseName = es2::ParseUniformName(name, &subscript);
+
+		// The app is not allowed to specify array indices other than 0 for arrays of basic types
+		if(subscript != 0 && subscript != GL_INVALID_INDEX)
+		{
+			return GL_INVALID_INDEX;
+		}
+
+		size_t numUniforms = uniforms.size();
+		for(GLuint index = 0; index < numUniforms; index++)
+		{
+			if(uniforms[index]->name == baseName)
+			{
+				if(uniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
+				{
+					return index;
+				}
+			}
+		}
+
+		return GL_INVALID_INDEX;
+	}
+
+	void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
+	{
+		ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
+
+		const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
+
+		switch(pname)
+		{
+		case GL_UNIFORM_BLOCK_DATA_SIZE:
+			*params = static_cast<GLint>(uniformBlock.dataSize);
+			break;
+		case GL_UNIFORM_BLOCK_NAME_LENGTH:
+			*params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
+			break;
+		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+			*params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
+			break;
+		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+			{
+				for(unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
+				{
+					params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
+				}
+			}
+			break;
+		case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+			*params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
+			break;
+		case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+			*params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
+			break;
+		default: UNREACHABLE(pname);
+		}
+	}
+
+	GLuint Program::getUniformBlockIndex(const std::string &name) const
+	{
+		size_t subscript = GL_INVALID_INDEX;
+		std::string baseName = es2::ParseUniformName(name, &subscript);
+
+		size_t numUniformBlocks = getActiveUniformBlockCount();
+		for(GLuint blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
+		{
+			const UniformBlock &uniformBlock = *uniformBlocks[blockIndex];
+			if(uniformBlock.name == baseName)
+			{
+				const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
+				if(subscript == uniformBlock.elementIndex || arrayElementZero)
+				{
+					return blockIndex;
+				}
+			}
+		}
+
+		return GL_INVALID_INDEX;
+	}
+
+	void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+	{
+		uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
+	}
+
+	GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
+	{
+		return uniformBlockBindings[uniformBlockIndex];
+	}
+
+	void Program::resetUniformBlockBindings()
+	{
+		for(unsigned int blockId = 0; blockId < MAX_UNIFORM_BUFFER_BINDINGS; blockId++)
+		{
+			uniformBlockBindings[blockId] = 0;
+		}
+	}
+
+	bool Program::setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements)
+	{
+		ASSERT(numElements >= 1 && numElements <= 4);
+
+		static GLenum floatType[] = { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 };
+		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
+
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		int index = numElements - 1;
+		if(targetUniform->type == floatType[index])
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat)* numElements,
+				   v, numElements * sizeof(GLfloat)* count);
+		}
+		else if(targetUniform->type == boolType[index])
+		{
+			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * numElements;
+
+			for(int i = 0; i < count * numElements; i++)
+			{
+				boolParams[i] = (v[i] == 0.0f) ? GL_FALSE : GL_TRUE;
+			}
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+	{
+		return setUniformfv(location, count, v, 1);
+	}
+
+	bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		return setUniformfv(location, count, v, 2);
+	}
+
+	bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		return setUniformfv(location, count, v, 3);
+	}
+
+	bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		return setUniformfv(location, count, v, 4);
+	}
+
+	bool Program::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type)
+	{
+		int numElements;
+		switch(type)
+		{
+		case GL_FLOAT_MAT2:
+			numElements = 4;
+			break;
+		case GL_FLOAT_MAT2x3:
+		case GL_FLOAT_MAT3x2:
+			numElements = 6;
+			break;
+		case GL_FLOAT_MAT2x4:
+		case GL_FLOAT_MAT4x2:
+			numElements = 8;
+			break;
+		case GL_FLOAT_MAT3:
+			numElements = 9;
+			break;
+		case GL_FLOAT_MAT3x4:
+		case GL_FLOAT_MAT4x3:
+			numElements = 12;
+			break;
+		case GL_FLOAT_MAT4:
+			numElements = 16;
+			break;
+		default:
+			return false;
+		}
+
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		if(targetUniform->type != type)
+		{
+			return false;
+		}
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		GLfloat* dst = reinterpret_cast<GLfloat*>(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * numElements);
+
+		if(transpose == GL_FALSE)
+		{
+			memcpy(dst, value, numElements * sizeof(GLfloat) * count);
+		}
+		else
+		{
+			const int rowSize = VariableRowCount(type);
+			const int colSize = VariableColumnCount(type);
+			for(int n = 0; n < count; ++n)
+			{
+				for(int i = 0; i < colSize; ++i)
+				{
+					for(int j = 0; j < rowSize; ++j)
+					{
+						dst[i * rowSize + j] = value[j * colSize + i];
+					}
+				}
+				dst += numElements;
+				value += numElements;
+			}
+		}
+
+
+		return true;
+	}
+
+	bool Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2);
+	}
+
+	bool Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x3);
+	}
+
+	bool Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x4);
+	}
+
+	bool Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3);
+	}
+
+	bool Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x2);
+	}
+
+	bool Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x4);
+	}
+
+	bool Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4);
+	}
+
+	bool Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x2);
+	}
+
+	bool Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+	{
+		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x3);
+	}
+
+	bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
+				   v, sizeof(GLint) * count);
+		}
+		else if(targetUniform->type == GL_BOOL)
+		{
+			GLboolean *boolParams = new GLboolean[count];
+
+			for(int i = 0; i < count; i++)
+			{
+				if(v[i] == 0)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
+				   boolParams, sizeof(GLboolean) * count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)
+	{
+		static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
+		static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
+		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
+
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		int index = numElements - 1;
+		if(targetUniform->type == intType[index] || targetUniform->type == uintType[index])
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,
+				   v, numElements * sizeof(GLint)* count);
+		}
+		else if(targetUniform->type == boolType[index])
+		{
+			GLboolean *boolParams = new GLboolean[count * numElements];
+
+			for(int i = 0; i < count * numElements; i++)
+			{
+				boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
+				   boolParams, numElements * sizeof(GLboolean)* count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+	{
+		return setUniformiv(location, count, v, 2);
+	}
+
+	bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+	{
+		return setUniformiv(location, count, v, 3);
+	}
+
+	bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+	{
+		return setUniformiv(location, count, v, 4);
+	}
+
+	bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),
+				   v, sizeof(GLuint)* count);
+		}
+		else if(targetUniform->type == GL_BOOL)
+		{
+			GLboolean *boolParams = new GLboolean[count];
+
+			for(int i = 0; i < count; i++)
+			{
+				if(v[i] == 0)
+				{
+					boolParams[i] = GL_FALSE;
+				}
+				else
+				{
+					boolParams[i] = GL_TRUE;
+				}
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
+				   boolParams, sizeof(GLboolean)* count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)
+	{
+		static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
+		static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
+		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
+
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		targetUniform->dirty = true;
+
+		int size = targetUniform->size();
+
+		if(size == 1 && count > 1)
+		{
+			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
+		}
+
+		count = std::min(size - (int)uniformIndex[location].element, count);
+
+		int index = numElements - 1;
+		if(targetUniform->type == uintType[index] || targetUniform->type == intType[index])
+		{
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,
+				   v, numElements * sizeof(GLuint)* count);
+		}
+		else if(targetUniform->type == boolType[index])
+		{
+			GLboolean *boolParams = new GLboolean[count * numElements];
+
+			for(int i = 0; i < count * numElements; i++)
+			{
+				boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
+			}
+
+			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
+				   boolParams, numElements * sizeof(GLboolean)* count);
+
+			delete[] boolParams;
+		}
+		else
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		return setUniformuiv(location, count, v, 2);
+	}
+
+	bool Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		return setUniformuiv(location, count, v, 3);
+	}
+
+	bool Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		return setUniformuiv(location, count, v, 4);
+	}
+
+	bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		unsigned int count = UniformComponentCount(targetUniform->type);
+
+		// Sized query - ensure the provided buffer is large enough
+		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))
+		{
+			return false;
+		}
+
+		switch(UniformComponentType(targetUniform->type))
+		{
+		case GL_BOOL:
+			{
+				GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
+				}
+			}
+			break;
+		case GL_FLOAT:
+			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
+				   count * sizeof(GLfloat));
+			break;
+		case GL_INT:
+			{
+				GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (float)intParams[i];
+				}
+			}
+			break;
+		case GL_UNSIGNED_INT:
+			{
+				GLuint *uintParams = (GLuint*)targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (float)uintParams[i];
+				}
+			}
+			break;
+		default: UNREACHABLE(targetUniform->type);
+		}
+
+		return true;
+	}
+
+	bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		unsigned int count = UniformComponentCount(targetUniform->type);
+
+		// Sized query - ensure the provided buffer is large enough
+		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLint))
+		{
+			return false;
+		}
+
+		switch(UniformComponentType(targetUniform->type))
+		{
+		case GL_BOOL:
+			{
+				GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (GLint)boolParams[i];
+				}
+			}
+			break;
+		case GL_FLOAT:
+			{
+				GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
+
+				for(unsigned int i = 0; i < count; i++)
+				{
+					params[i] = (GLint)floatParams[i];
+				}
+			}
+			break;
+		case GL_INT:
+		case GL_UNSIGNED_INT:
+			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
+				   count * sizeof(GLint));
+			break;
+		default: UNREACHABLE(targetUniform->type);
+		}
+
+		return true;
+	}
+
+	bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
+	{
+		if(location < 0 || location >= (int)uniformIndex.size())
+		{
+			return false;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		unsigned int count = UniformComponentCount(targetUniform->type);
+
+		// Sized query - ensure the provided buffer is large enough
+		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLuint))
+		{
+			return false;
+		}
+
+		switch(UniformComponentType(targetUniform->type))
+		{
+		case GL_BOOL:
+		{
+			GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
+
+			for(unsigned int i = 0; i < count; i++)
+			{
+				params[i] = (GLuint)boolParams[i];
+			}
+		}
+			break;
+		case GL_FLOAT:
+		{
+			GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
+
+			for(unsigned int i = 0; i < count; i++)
+			{
+				params[i] = (GLuint)floatParams[i];
+			}
+		}
+			break;
+		case GL_INT:
+		case GL_UNSIGNED_INT:
+			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLuint),
+				   count * sizeof(GLuint));
+			break;
+		default: UNREACHABLE(targetUniform->type);
+		}
+
+		return true;
+	}
+
+	void Program::dirtyAllUniforms()
+	{
+		size_t numUniforms = uniforms.size();
+		for(size_t index = 0; index < numUniforms; index++)
+		{
+			uniforms[index]->dirty = true;
+		}
+	}
+
+	// Applies all the uniforms set for this program object to the device
+	void Program::applyUniforms()
+	{
+		GLint numUniforms = uniformIndex.size();
+		for(GLint location = 0; location < numUniforms; location++)
+		{
+			if(uniformIndex[location].element != 0)
+			{
+				continue;
+			}
+
+			Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+			if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))
+			{
+				GLsizei size = targetUniform->size();
+				GLfloat *f = (GLfloat*)targetUniform->data;
+				GLint *i = (GLint*)targetUniform->data;
+				GLuint *ui = (GLuint*)targetUniform->data;
+				GLboolean *b = (GLboolean*)targetUniform->data;
+
+				switch(targetUniform->type)
+				{
+				case GL_BOOL:       applyUniform1bv(location, size, b);       break;
+				case GL_BOOL_VEC2:  applyUniform2bv(location, size, b);       break;
+				case GL_BOOL_VEC3:  applyUniform3bv(location, size, b);       break;
+				case GL_BOOL_VEC4:  applyUniform4bv(location, size, b);       break;
+				case GL_FLOAT:      applyUniform1fv(location, size, f);       break;
+				case GL_FLOAT_VEC2: applyUniform2fv(location, size, f);       break;
+				case GL_FLOAT_VEC3: applyUniform3fv(location, size, f);       break;
+				case GL_FLOAT_VEC4: applyUniform4fv(location, size, f);       break;
+				case GL_FLOAT_MAT2:   applyUniformMatrix2fv(location, size, f);   break;
+				case GL_FLOAT_MAT2x3: applyUniformMatrix2x3fv(location, size, f); break;
+				case GL_FLOAT_MAT2x4: applyUniformMatrix2x4fv(location, size, f); break;
+				case GL_FLOAT_MAT3x2: applyUniformMatrix3x2fv(location, size, f); break;
+				case GL_FLOAT_MAT3:   applyUniformMatrix3fv(location, size, f);   break;
+				case GL_FLOAT_MAT3x4: applyUniformMatrix3x4fv(location, size, f); break;
+				case GL_FLOAT_MAT4x2: applyUniformMatrix4x2fv(location, size, f); break;
+				case GL_FLOAT_MAT4x3: applyUniformMatrix4x3fv(location, size, f); break;
+				case GL_FLOAT_MAT4:   applyUniformMatrix4fv(location, size, f);   break;
+				case GL_SAMPLER_2D:
+				case GL_SAMPLER_CUBE:
+				case GL_SAMPLER_EXTERNAL_OES:
+				case GL_SAMPLER_3D_OES:
+				case GL_SAMPLER_2D_ARRAY:
+				case GL_SAMPLER_2D_SHADOW:
+				case GL_SAMPLER_CUBE_SHADOW:
+				case GL_SAMPLER_2D_ARRAY_SHADOW:
+				case GL_INT_SAMPLER_2D:
+				case GL_UNSIGNED_INT_SAMPLER_2D:
+				case GL_INT_SAMPLER_CUBE:
+				case GL_UNSIGNED_INT_SAMPLER_CUBE:
+				case GL_INT_SAMPLER_3D:
+				case GL_UNSIGNED_INT_SAMPLER_3D:
+				case GL_INT_SAMPLER_2D_ARRAY:
+				case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+				case GL_INT:        applyUniform1iv(location, size, i);       break;
+				case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;
+				case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;
+				case GL_INT_VEC4:   applyUniform4iv(location, size, i);       break;
+				case GL_UNSIGNED_INT:      applyUniform1uiv(location, size, ui); break;
+				case GL_UNSIGNED_INT_VEC2: applyUniform2uiv(location, size, ui); break;
+				case GL_UNSIGNED_INT_VEC3: applyUniform3uiv(location, size, ui); break;
+				case GL_UNSIGNED_INT_VEC4: applyUniform4uiv(location, size, ui); break;
+				default:
+					UNREACHABLE(targetUniform->type);
+				}
+
+				targetUniform->dirty = false;
+			}
+		}
+	}
+
+	void Program::applyUniformBuffers(BufferBinding* uniformBuffers)
+	{
+		GLint vertexUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
+		GLint fragmentUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
+
+		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
+		{
+			vertexUniformBuffers[bufferBindingIndex] = -1;
+		}
+
+		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
+		{
+			fragmentUniformBuffers[bufferBindingIndex] = -1;
+		}
+
+		int vertexUniformBufferIndex = 0;
+		int fragmentUniformBufferIndex = 0;
+		for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
+		{
+			UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
+
+			// Unnecessary to apply an unreferenced standard or shared UBO
+			if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
+			{
+				continue;
+			}
+
+			GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
+
+			if(uniformBlock.isReferencedByVertexShader())
+			{
+				vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;
+			}
+
+			if(uniformBlock.isReferencedByFragmentShader())
+			{
+				fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;
+			}
+		}
+
+		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
+		{
+			int index = vertexUniformBuffers[bufferBindingIndex];
+			device->VertexProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? uniformBuffers[index].get()->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
+			index = fragmentUniformBuffers[bufferBindingIndex];
+			device->PixelProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? uniformBuffers[index].get()->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
+		}
+	}
+
+	void Program::applyTransformFeedback(TransformFeedback* transformFeedback)
+	{
+		// Make sure the flags will fit in a 64 bit unsigned int variable
+		ASSERT(sw::max<int>(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) <= 64);
+
+		BufferBinding* transformFeedbackBuffers = (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) ? transformFeedback->getBuffers() : nullptr;
+
+		uint64_t enableTransformFeedback = 0;
+		if(!transformFeedbackBuffers)
+		{
+			for(unsigned int index = 0; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
+			{
+				device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
+			}
+			device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
+			return;
+		}
+
+		unsigned int maxVaryings = transformFeedbackLinkedVaryings.size();
+		switch(transformFeedbackBufferMode)
+		{
+		case GL_SEPARATE_ATTRIBS:
+		{
+			maxVaryings = sw::min(maxVaryings, (unsigned int)MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
+			// Attribs go to separate buffers
+			for(unsigned int index = 0; index < maxVaryings; ++index)
+			{
+				int size = transformFeedbackLinkedVaryings[index].size;
+				int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
+				int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
+				int nbRegs = rowCount > 1 ? colCount * size : size;
+				int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
+				int componentStride = rowCount * colCount * size;
+				int baseOffset = transformFeedback->vertexOffset() * componentStride * sizeof(float);
+				device->VertexProcessor::setTransformFeedbackBuffer(index,
+					transformFeedbackBuffers[index].get()->getResource(),
+					transformFeedbackBuffers[index].getOffset() + baseOffset,
+					transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
+					nbRegs, nbComponentsPerReg, componentStride);
+				enableTransformFeedback |= 1ULL << index;
+			}
+		}
+			break;
+		case GL_INTERLEAVED_ATTRIBS:
+		{
+			// OpenGL ES 3.0.4 spec, section 2.15.2:
+			// In INTERLEAVED_ATTRIBS mode, the values of one or more output variables
+			// written by a vertex shader are written, interleaved, into the buffer object
+			// bound to the first transform feedback binding point (index = 0).
+			sw::Resource* resource = transformFeedbackBuffers[0].get()->getResource();
+			int componentStride = totalLinkedVaryingsComponents;
+			int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float));
+			maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
+			size_t totalComponents = 0;
+			for(unsigned int index = 0; index < maxVaryings; ++index)
+			{
+				int size = transformFeedbackLinkedVaryings[index].size;
+				int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
+				int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
+				int nbRegs = rowCount > 1 ? colCount * size : size;
+				int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
+				device->VertexProcessor::setTransformFeedbackBuffer(index, resource,
+					baseOffset + (totalComponents * sizeof(float)),
+					transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
+					nbRegs, nbComponentsPerReg, componentStride);
+				totalComponents += rowCount * colCount * size;
+				enableTransformFeedback |= 1ULL << index;
+			}
+		}
+			break;
+		default:
+			UNREACHABLE(transformFeedbackBufferMode);
+			break;
+		}
+
+		// Unset all other transform feedback buffers
+		for(unsigned int index = maxVaryings; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
+		{
+			device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
+		}
+
+		device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
+	}
+
+	bool Program::linkVaryings()
+	{
+		for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)
+		{
+			bool matched = false;
+
+			for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); ++output)
+			{
+				if(output->name == input->name)
+				{
+					if(output->type != input->type || output->size() != input->size())
+					{
+						appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
+
+						return false;
+					}
+
+					matched = true;
+					break;
+				}
+			}
+
+			if(!matched)
+			{
+				appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
+
+				return false;
+			}
+		}
+
+		glsl::VaryingList &psVaryings = fragmentShader->varyings;
+		glsl::VaryingList &vsVaryings = vertexShader->varyings;
+
+		for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); ++output)
+		{
+			for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); ++input)
+			{
+				if(output->name == input->name)
+				{
+					int in = input->reg;
+					int out = output->reg;
+					int components = VariableRegisterSize(output->type);
+					int registers = VariableRegisterCount(output->type) * output->size();
+
+					ASSERT(in >= 0);
+
+					if(in + registers > MAX_VARYING_VECTORS)
+					{
+						appendToInfoLog("Too many varyings");
+						return false;
+					}
+
+					if(out >= 0)
+					{
+						if(out + registers > MAX_VARYING_VECTORS)
+						{
+							appendToInfoLog("Too many varyings");
+							return false;
+						}
+
+						for(int i = 0; i < registers; i++)
+						{
+							if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+							if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+							if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+							if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+						}
+					}
+					else   // Vertex varying is declared but not written to
+					{
+						for(int i = 0; i < registers; i++)
+						{
+							if(components >= 1) pixelBinary->semantic[in + i][0] = sw::Shader::Semantic();
+							if(components >= 2) pixelBinary->semantic[in + i][1] = sw::Shader::Semantic();
+							if(components >= 3) pixelBinary->semantic[in + i][2] = sw::Shader::Semantic();
+							if(components >= 4) pixelBinary->semantic[in + i][3] = sw::Shader::Semantic();
+						}
+					}
+
+					break;
+				}
+			}
+		}
+
+		return true;
+	}
+
+	bool Program::linkTransformFeedback()
+	{
+		size_t totalComponents = 0;
+		totalLinkedVaryingsComponents = 0;
+
+		std::set<std::string> uniqueNames;
+
+		for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
+		{
+			size_t subscript = GL_INVALID_INDEX;
+			std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, &subscript);
+			bool hasSubscript = (subscript != GL_INVALID_INDEX);
+
+			if(tfVaryingName.find('[') != std::string::npos)
+			{
+				appendToInfoLog("Capture of array sub-elements is undefined and not supported.");
+				return false;
+			}
+
+			bool found = false;
+			for(const glsl::Varying varying : vertexShader->varyings)
+			{
+				if(tfVaryingName == varying.name)
+				{
+					if(uniqueNames.count(indexedTfVaryingName) > 0)
+					{
+						appendToInfoLog("Two transform feedback varyings specify the same output variable (%s)", indexedTfVaryingName.c_str());
+						return false;
+					}
+					uniqueNames.insert(indexedTfVaryingName);
+
+					if(hasSubscript && ((static_cast<int>(subscript)) >= varying.size()))
+					{
+						appendToInfoLog("Specified transform feedback varying index out of bounds (%s)", indexedTfVaryingName.c_str());
+						return false;
+					}
+
+					size_t size = hasSubscript ? 1 : varying.size();
+
+					size_t rowCount = VariableRowCount(varying.type);
+					size_t colCount = VariableColumnCount(varying.type);
+					size_t componentCount = rowCount * colCount * size;
+					if(transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
+					   componentCount > sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)
+					{
+						appendToInfoLog("Transform feedback varying's %s components (%d) exceed the maximum separate components (%d).",
+						                varying.name.c_str(), componentCount, sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
+						return false;
+					}
+
+					totalComponents += componentCount;
+
+					int reg = varying.reg;
+					if(hasSubscript)
+					{
+						reg += rowCount > 1 ? colCount * subscript : subscript;
+					}
+					int col = varying.col;
+					if(tfVaryingName == "gl_PointSize")
+					{
+						// Point size is stored in the y element of the vector, not the x element
+						col = 1; // FIXME: varying.col could already contain this information
+					}
+					transformFeedbackLinkedVaryings.push_back(LinkedVarying(varying.name, varying.type, size, reg, col));
+
+					found = true;
+					break;
+				}
+			}
+
+			if(!found)
+			{
+				appendToInfoLog("Transform feedback varying %s does not exist in the vertex shader.", tfVaryingName.c_str());
+				return false;
+			}
+		}
+
+		if(transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
+		   totalComponents > sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)
+		{
+			appendToInfoLog("Transform feedback varying total components (%d) exceed the maximum separate components (%d).",
+			                totalComponents, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
+			return false;
+		}
+
+		totalLinkedVaryingsComponents = totalComponents;
+
+		return true;
+	}
+
+	// Links the code of the vertex and pixel shader by matching up their varyings,
+	// compiling them into binaries, determining the attribute mappings, and collecting
+	// a list of uniforms
+	void Program::link()
+	{
+		unlink();
+
+		resetUniformBlockBindings();
+
+		if(!fragmentShader || !fragmentShader->isCompiled())
+		{
+			return;
+		}
+
+		if(!vertexShader || !vertexShader->isCompiled())
+		{
+			return;
+		}
+
+		vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
+		pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
+
+		if(!linkVaryings())
+		{
+			return;
+		}
+
+		if(!linkAttributes())
+		{
+			return;
+		}
+
+		// Link uniform blocks before uniforms to make it easy to assign block indices to fields
+		if(!linkUniformBlocks(vertexShader, fragmentShader))
+		{
+			return;
+		}
+
+		if(!linkUniforms(fragmentShader))
+		{
+			return;
+		}
+
+		if(!linkUniforms(vertexShader))
+		{
+			return;
+		}
+
+		if(!linkTransformFeedback())
+		{
+			return;
+		}
+
+		linked = true;   // Success
+	}
+
+	// Determines the mapping between GL attributes and vertex stream usage indices
+	bool Program::linkAttributes()
+	{
+		unsigned int usedLocations = 0;
+
+		// Link attributes that have a binding location
+		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
+		{
+			int location = getAttributeBinding(*attribute);
+
+			if(location != -1)   // Set by glBindAttribLocation
+			{
+				int rows = VariableRegisterCount(attribute->type);
+
+				if(rows + location > MAX_VERTEX_ATTRIBS)
+				{
+					appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
+					return false;
+				}
+
+				// In GLSL 3.00, attribute aliasing produces a link error
+				// In GLSL 1.00, attribute aliasing is allowed
+				if(egl::getClientVersion() >= 3)
+				{
+					for(int i = 0; i < rows; i++)
+					{
+						if(!linkedAttribute[location + i].name.empty())
+						{
+							appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute->name.c_str(), linkedAttribute[location].name.c_str(), location);
+							return false;
+						}
+					}
+				}
+
+				for(int i = 0; i < rows; i++)
+				{
+					linkedAttribute[location + i] = *attribute;
+					usedLocations |= 1 << (location + i);
+				}
+			}
+		}
+
+		// Link attributes that don't have a binding location
+		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
+		{
+			int location = getAttributeBinding(*attribute);
+
+			if(location == -1)   // Not set by glBindAttribLocation
+			{
+				int rows = VariableRegisterCount(attribute->type);
+				int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
+
+				if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
+				{
+					appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
+					return false;   // Fail to link
+				}
+
+				for(int i = 0; i < rows; i++)
+				{
+					linkedAttribute[availableIndex + i] = *attribute;
+				}
+			}
+		}
+
+		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
+		{
+			int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
+			int rows = std::max(VariableRegisterCount(linkedAttribute[attributeIndex].type), 1);
+
+			for(int r = 0; r < rows; r++)
+			{
+				attributeStream[attributeIndex++] = index++;
+			}
+		}
+
+		return true;
+	}
+
+	int Program::getAttributeBinding(const glsl::Attribute &attribute)
+	{
+		if(attribute.location != -1)
+		{
+			return attribute.location;
+		}
+
+		for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
+		{
+			if(attributeBinding[location].find(attribute.name.c_str()) != attributeBinding[location].end())
+			{
+				return location;
+			}
+		}
+
+		return -1;
+	}
+
+	bool Program::linkUniforms(const Shader *shader)
+	{
+		const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
+
+		for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
+		{
+			const glsl::Uniform &uniform = activeUniforms[uniformIndex];
+
+			unsigned int blockIndex = GL_INVALID_INDEX;
+			if(uniform.blockId >= 0)
+			{
+				const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;
+				ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());
+				blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);
+				ASSERT(blockIndex != GL_INVALID_INDEX);
+			}
+			if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex)))
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo)
+	{
+		if(IsSamplerUniform(type))
+	    {
+			int index = registerIndex;
+
+			do
+			{
+				if(shader == GL_VERTEX_SHADER)
+				{
+					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					{
+						samplersVS[index].active = true;
+
+						switch(type)
+						{
+						default:                      UNREACHABLE(type);
+						case GL_INT_SAMPLER_2D:
+						case GL_UNSIGNED_INT_SAMPLER_2D:
+						case GL_SAMPLER_2D_SHADOW:
+						case GL_SAMPLER_2D:           samplersVS[index].textureType = TEXTURE_2D;       break;
+						case GL_INT_SAMPLER_CUBE:
+						case GL_UNSIGNED_INT_SAMPLER_CUBE:
+						case GL_SAMPLER_CUBE_SHADOW:
+						case GL_SAMPLER_CUBE:         samplersVS[index].textureType = TEXTURE_CUBE;     break;
+						case GL_INT_SAMPLER_3D:
+						case GL_UNSIGNED_INT_SAMPLER_3D:
+						case GL_SAMPLER_3D_OES:       samplersVS[index].textureType = TEXTURE_3D;       break;
+						case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break;
+						case GL_INT_SAMPLER_2D_ARRAY:
+						case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+						case GL_SAMPLER_2D_ARRAY_SHADOW:
+						case GL_SAMPLER_2D_ARRAY:     samplersVS[index].textureType = TEXTURE_2D_ARRAY; break;
+						}
+
+						samplersVS[index].logicalTextureUnit = 0;
+					}
+					else
+					{
+					   appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+					   return false;
+					}
+				}
+				else if(shader == GL_FRAGMENT_SHADER)
+				{
+					if(index < MAX_TEXTURE_IMAGE_UNITS)
+					{
+						samplersPS[index].active = true;
+
+						switch(type)
+						{
+						default:                      UNREACHABLE(type);
+						case GL_INT_SAMPLER_2D:
+						case GL_UNSIGNED_INT_SAMPLER_2D:
+						case GL_SAMPLER_2D_SHADOW:
+						case GL_SAMPLER_2D:           samplersPS[index].textureType = TEXTURE_2D;       break;
+						case GL_INT_SAMPLER_CUBE:
+						case GL_UNSIGNED_INT_SAMPLER_CUBE:
+						case GL_SAMPLER_CUBE_SHADOW:
+						case GL_SAMPLER_CUBE:         samplersPS[index].textureType = TEXTURE_CUBE;     break;
+						case GL_INT_SAMPLER_3D:
+						case GL_UNSIGNED_INT_SAMPLER_3D:
+						case GL_SAMPLER_3D_OES:       samplersPS[index].textureType = TEXTURE_3D;       break;
+						case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break;
+						case GL_INT_SAMPLER_2D_ARRAY:
+						case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+						case GL_SAMPLER_2D_ARRAY_SHADOW:
+						case GL_SAMPLER_2D_ARRAY:     samplersPS[index].textureType = TEXTURE_2D_ARRAY; break;
+						}
+
+						samplersPS[index].logicalTextureUnit = 0;
+					}
+					else
+					{
+						appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
+						return false;
+					}
+				}
+				else UNREACHABLE(shader);
+
+				index++;
+			}
+			while(index < registerIndex + static_cast<int>(arraySize));
+	    }
+
+		Uniform *uniform = 0;
+		GLint location = getUniformLocation(name);
+
+		if(location >= 0)   // Previously defined, types must match
+		{
+			uniform = uniforms[uniformIndex[location].index];
+
+			if(uniform->type != type)
+			{
+				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
+				return false;
+			}
+
+			if(uniform->precision != precision)
+			{
+				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
+				return false;
+			}
+		}
+		else
+		{
+			uniform = new Uniform(type, precision, name, arraySize, blockInfo);
+		}
+
+		if(!uniform)
+		{
+			return false;
+		}
+
+		if(shader == GL_VERTEX_SHADER)
+		{
+			uniform->vsRegisterIndex = registerIndex;
+		}
+		else if(shader == GL_FRAGMENT_SHADER)
+		{
+			uniform->psRegisterIndex = registerIndex;
+		}
+		else UNREACHABLE(shader);
+
+		if(location == -1)   // Not previously defined
+		{
+			uniforms.push_back(uniform);
+			size_t index = uniforms.size() - 1;
+
+			for(int i = 0; i < uniform->size(); i++)
+			{
+				uniformIndex.push_back(UniformLocation(name, i, index));
+			}
+		}
+
+		if(shader == GL_VERTEX_SHADER)
+		{
+			if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
+			{
+				appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
+				return false;
+			}
+		}
+		else if(shader == GL_FRAGMENT_SHADER)
+		{
+			if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
+			{
+				appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
+				return false;
+			}
+		}
+		else UNREACHABLE(shader);
+
+		return true;
+	}
+
+	bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)
+	{
+		// validate blocks for the same member types
+		if(block1.fields.size() != block2.fields.size())
+		{
+			return false;
+		}
+		if(block1.arraySize != block2.arraySize)
+		{
+			return false;
+		}
+		if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)
+		{
+			return false;
+		}
+		const size_t numBlockMembers = block1.fields.size();
+		for(size_t blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+		{
+			const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]];
+			const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]];
+			if(member1.name != member2.name ||
+			   member1.arraySize != member2.arraySize ||
+			   member1.precision != member2.precision ||
+			   member1.type != member2.type)
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+
+	bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader)
+	{
+		const glsl::ActiveUniformBlocks &vertexUniformBlocks = vertexShader->activeUniformBlocks;
+		const glsl::ActiveUniformBlocks &fragmentUniformBlocks = fragmentShader->activeUniformBlocks;
+		// Check that interface blocks defined in the vertex and fragment shaders are identical
+		typedef std::map<std::string, const glsl::UniformBlock*> UniformBlockMap;
+		UniformBlockMap linkedUniformBlocks;
+		for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
+		{
+			const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex];
+			linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock;
+		}
+		for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
+		{
+			const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex];
+			UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name);
+			if(entry != linkedUniformBlocks.end())
+			{
+				const glsl::UniformBlock &vertexUniformBlock = *entry->second;
+				if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader))
+				{
+					return false;
+				}
+			}
+		}
+		for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
+		{
+			const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex];
+			if(!defineUniformBlock(vertexShader, uniformBlock))
+			{
+				return false;
+			}
+		}
+		for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
+		{
+			const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex];
+			if(!defineUniformBlock(fragmentShader, uniformBlock))
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+
+	bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)
+	{
+		GLuint blockIndex = getUniformBlockIndex(block.name);
+
+		if(blockIndex == GL_INVALID_INDEX)
+		{
+			const std::vector<int>& fields = block.fields;
+			std::vector<unsigned int> memberUniformIndexes;
+			for(size_t i = 0; i < fields.size(); ++i)
+			{
+				memberUniformIndexes.push_back(fields[i]);
+			}
+
+			if(block.arraySize > 0)
+			{
+				int regIndex = block.registerIndex;
+				int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
+				for(unsigned int i = 0; i < block.arraySize; ++i, regIndex += regInc)
+				{
+					uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes));
+					uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex);
+				}
+			}
+			else
+			{
+				uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
+				uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);
+			}
+		}
+		else
+		{
+			int regIndex = block.registerIndex;
+			int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
+			int nbBlocks = (block.arraySize > 0) ? block.arraySize : 1;
+			for(int i = 0; i < nbBlocks; ++i, regIndex += regInc)
+			{
+				uniformBlocks[blockIndex + i]->setRegisterIndex(shader->getType(), regIndex);
+			}
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform(GLint location, float* data)
+	{
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+
+		if(targetUniform->psRegisterIndex != -1)
+		{
+			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, data, targetUniform->registerCount());
+		}
+
+		if(targetUniform->vsRegisterIndex != -1)
+		{
+			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, data, targetUniform->registerCount());
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = 0;
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 1;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 2;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][3] = 0;
+
+			v += 3;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)
+	{
+		int vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+			vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
+
+			v += 4;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = 0;
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 1;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 2;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		float vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = v[2];
+			vector[i][3] = 0;
+
+			v += 3;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+	{
+		return applyUniform(location, (float*)v);
+	}
+
+	bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
+
+			value += 4;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
+
+			value += 6;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3];
+			matrix[i][1][0] = value[4];	matrix[i][1][1] = value[5];	matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7];
+
+			value += 8;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2];	matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5];	matrix[i][1][3] = 0;
+			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];	matrix[i][2][2] = value[8];	matrix[i][2][3] = 0;
+
+			value += 9;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
+			matrix[i][2][0] = value[4];	matrix[i][2][1] = value[5];	matrix[i][2][2] = 0; matrix[i][2][3] = 0;
+
+			value += 6;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; 	matrix[i][0][3] = value[3];
+			matrix[i][1][0] = value[4];	matrix[i][1][1] = value[5];	matrix[i][1][2] = value[6]; 	matrix[i][1][3] = value[7];
+			matrix[i][2][0] = value[8];	matrix[i][2][1] = value[9];	matrix[i][2][2] = value[10];	matrix[i][2][3] = value[11];
+
+			value += 12;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		return applyUniform(location, (float*)value);
+	}
+
+	bool Program::applyUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
+			matrix[i][2][0] = value[4];	matrix[i][2][1] = value[5];	matrix[i][2][2] = 0; matrix[i][2][3] = 0;
+			matrix[i][3][0] = value[6];	matrix[i][3][1] = value[7];	matrix[i][3][2] = 0; matrix[i][3][3] = 0;
+
+			value += 8;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value)
+	{
+		float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];  matrix[i][0][2] = value[2];  matrix[i][0][3] = 0;
+			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];  matrix[i][1][2] = value[5];  matrix[i][1][3] = 0;
+			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];  matrix[i][2][2] = value[8];  matrix[i][2][3] = 0;
+			matrix[i][3][0] = value[9];	matrix[i][3][1] = value[10]; matrix[i][3][2] = value[11]; matrix[i][3][3] = 0;
+
+			value += 12;
+		}
+
+		return applyUniform(location, (float*)matrix);
+	}
+
+	bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
+	{
+		GLint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[i];
+			vector[i][1] = 0;
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		if(IsSamplerUniform(targetUniform->type))
+		{
+			if(targetUniform->psRegisterIndex != -1)
+			{
+				for(int i = 0; i < count; i++)
+				{
+					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
+
+					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+					{
+						ASSERT(samplersPS[samplerIndex].active);
+						samplersPS[samplerIndex].logicalTextureUnit = v[i];
+					}
+				}
+			}
+
+			if(targetUniform->vsRegisterIndex != -1)
+			{
+				for(int i = 0; i < count; i++)
+				{
+					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
+
+					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					{
+						ASSERT(samplersVS[samplerIndex].active);
+						samplersVS[samplerIndex].logicalTextureUnit = v[i];
+					}
+				}
+			}
+		}
+		else
+		{
+			return applyUniform(location, (float*)vector);
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)
+	{
+		GLint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 2;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)
+	{
+		GLint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = v[2];
+			vector[i][3] = 0;
+
+			v += 3;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
+	{
+		GLint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = v[2];
+			vector[i][3] = v[3];
+
+			v += 4;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		GLuint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[i];
+			vector[i][1] = 0;
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+		}
+
+		Uniform *targetUniform = uniforms[uniformIndex[location].index];
+		if(IsSamplerUniform(targetUniform->type))
+		{
+			if(targetUniform->psRegisterIndex != -1)
+			{
+				for(int i = 0; i < count; i++)
+				{
+					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
+
+					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+					{
+						ASSERT(samplersPS[samplerIndex].active);
+						samplersPS[samplerIndex].logicalTextureUnit = v[i];
+					}
+				}
+			}
+
+			if(targetUniform->vsRegisterIndex != -1)
+			{
+				for(int i = 0; i < count; i++)
+				{
+					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
+
+					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+					{
+						ASSERT(samplersVS[samplerIndex].active);
+						samplersVS[samplerIndex].logicalTextureUnit = v[i];
+					}
+				}
+			}
+		}
+		else
+		{
+			return applyUniform(location, (float*)vector);
+		}
+
+		return true;
+	}
+
+	bool Program::applyUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		GLuint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = 0;
+			vector[i][3] = 0;
+
+			v += 2;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		GLuint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = v[2];
+			vector[i][3] = 0;
+
+			v += 3;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	bool Program::applyUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+	{
+		GLuint vector[MAX_UNIFORM_VECTORS][4];
+
+		for(int i = 0; i < count; i++)
+		{
+			vector[i][0] = v[0];
+			vector[i][1] = v[1];
+			vector[i][2] = v[2];
+			vector[i][3] = v[3];
+
+			v += 4;
+		}
+
+		return applyUniform(location, (float*)vector);
+	}
+
+	void Program::appendToInfoLog(const char *format, ...)
+	{
+		if(!format)
+		{
+			return;
+		}
+
+		char info[1024];
+
+		va_list vararg;
+		va_start(vararg, format);
+		vsnprintf(info, sizeof(info), format, vararg);
+		va_end(vararg);
+
+		size_t infoLength = strlen(info);
+
+		if(!infoLog)
+		{
+			infoLog = new char[infoLength + 2];
+			strcpy(infoLog, info);
+			strcpy(infoLog + infoLength, "\n");
+		}
+		else
+		{
+			size_t logLength = strlen(infoLog);
+			char *newLog = new char[logLength + infoLength + 2];
+			strcpy(newLog, infoLog);
+			strcpy(newLog + logLength, info);
+			strcpy(newLog + logLength + infoLength, "\n");
+
+			delete[] infoLog;
+			infoLog = newLog;
+		}
+	}
+
+	void Program::resetInfoLog()
+	{
+		if(infoLog)
+		{
+			delete[] infoLog;
+			infoLog = 0;
+		}
+	}
+
+	// Returns the program object to an unlinked state, before re-linking, or at destruction
+	void Program::unlink()
+	{
+		delete vertexBinary;
+		vertexBinary = 0;
+		delete pixelBinary;
+		pixelBinary = 0;
+
+		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+		{
+			linkedAttribute[index].name.clear();
+			attributeStream[index] = -1;
+		}
+
+		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
+		{
+			samplersPS[index].active = false;
+		}
+
+		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
+		{
+			samplersVS[index].active = false;
+		}
+
+		while(!uniforms.empty())
+		{
+			delete uniforms.back();
+			uniforms.pop_back();
+		}
+
+		while(!uniformBlocks.empty())
+		{
+			delete uniformBlocks.back();
+			uniformBlocks.pop_back();
+		}
+
+		uniformIndex.clear();
+		transformFeedbackLinkedVaryings.clear();
+
+		delete[] infoLog;
+		infoLog = 0;
+
+		linked = false;
+	}
+
+	bool Program::isLinked() const
+	{
+		return linked;
+	}
+
+	bool Program::isValidated() const
+	{
+		return validated;
+	}
+
+	GLint Program::getBinaryLength() const
+	{
+		UNIMPLEMENTED();
+		return 0;
+	}
+
+	void Program::release()
+	{
+		referenceCount--;
+
+		if(referenceCount == 0 && orphaned)
+		{
+			resourceManager->deleteProgram(handle);
+		}
+	}
+
+	void Program::addRef()
+	{
+		referenceCount++;
+	}
+
+	unsigned int Program::getRefCount() const
+	{
+		return referenceCount;
+	}
+
+	unsigned int Program::getSerial() const
+	{
+		return serial;
+	}
+
+	unsigned int Program::issueSerial()
+	{
+		return currentSerial++;
+	}
+
+	size_t Program::getInfoLogLength() const
+	{
+		if(!infoLog)
+		{
+			return 0;
+		}
+		else
+		{
+		   return strlen(infoLog) + 1;
+		}
+	}
+
+	void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
+	{
+		int index = 0;
+
+		if(bufSize > 0)
+		{
+			if(infoLog)
+			{
+				index = std::min(bufSize - 1, (int)strlen(infoLog));
+				memcpy(buffer, infoLog, index);
+			}
+
+			buffer[index] = '\0';
+		}
+
+		if(length)
+		{
+			*length = index;
+		}
+	}
+
+	void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
+	{
+		int total = 0;
+
+		if(vertexShader && (total < maxCount))
+		{
+			shaders[total++] = vertexShader->getName();
+		}
+
+		if(fragmentShader && (total < maxCount))
+		{
+			shaders[total++] = fragmentShader->getName();
+		}
+
+		if(count)
+		{
+			*count = total;
+		}
+	}
+
+	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
+	{
+		// Skip over inactive attributes
+		unsigned int activeAttribute = 0;
+		unsigned int attribute;
+		for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+		{
+			if(linkedAttribute[attribute].name.empty())
+			{
+				continue;
+			}
+
+			if(activeAttribute == index)
+			{
+				break;
+			}
+
+			activeAttribute++;
+		}
+
+		if(bufsize > 0)
+		{
+			const char *string = linkedAttribute[attribute].name.c_str();
+
+			strncpy(name, string, bufsize);
+			name[bufsize - 1] = '\0';
+
+			if(length)
+			{
+				*length = strlen(name);
+			}
+		}
+
+		*size = 1;   // Always a single 'type' instance
+
+		*type = linkedAttribute[attribute].type;
+	}
+
+	size_t Program::getActiveAttributeCount() const
+	{
+		int count = 0;
+
+		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+		{
+			if(!linkedAttribute[attributeIndex].name.empty())
+			{
+				count++;
+			}
+		}
+
+		return count;
+	}
+
+	GLint Program::getActiveAttributeMaxLength() const
+	{
+		int maxLength = 0;
+
+		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+		{
+			if(!linkedAttribute[attributeIndex].name.empty())
+			{
+				maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
+			}
+		}
+
+		return maxLength;
+	}
+
+	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
+	{
+		if(bufsize > 0)
+		{
+			std::string string = uniforms[index]->name;
+
+			if(uniforms[index]->isArray())
+			{
+				string += "[0]";
+			}
+
+			strncpy(name, string.c_str(), bufsize);
+			name[bufsize - 1] = '\0';
+
+			if(length)
+			{
+				*length = strlen(name);
+			}
+		}
+
+		*size = uniforms[index]->size();
+
+		*type = uniforms[index]->type;
+	}
+
+	size_t Program::getActiveUniformCount() const
+	{
+		return uniforms.size();
+	}
+
+	GLint Program::getActiveUniformMaxLength() const
+	{
+		int maxLength = 0;
+
+		size_t numUniforms = uniforms.size();
+		for(size_t uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
+		{
+			if(!uniforms[uniformIndex]->name.empty())
+			{
+				int length = (int)(uniforms[uniformIndex]->name.length() + 1);
+				if(uniforms[uniformIndex]->isArray())
+				{
+					length += 3;  // Counting in "[0]".
+				}
+				maxLength = std::max(length, maxLength);
+			}
+		}
+
+		return maxLength;
+	}
+
+	GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
+	{
+		const Uniform& uniform = *uniforms[index];
+		switch(pname)
+		{
+		case GL_UNIFORM_TYPE:         return static_cast<GLint>(uniform.type);
+		case GL_UNIFORM_SIZE:         return static_cast<GLint>(uniform.size());
+		case GL_UNIFORM_NAME_LENGTH:  return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
+		case GL_UNIFORM_BLOCK_INDEX:  return uniform.blockInfo.index;
+		case GL_UNIFORM_OFFSET:       return uniform.blockInfo.offset;
+		case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
+		case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
+		case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
+		default:
+			UNREACHABLE(pname);
+			break;
+		}
+		return 0;
+	}
+
+	void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const
+	{
+		ASSERT(index < getActiveUniformBlockCount());
+
+		const UniformBlock &uniformBlock = *uniformBlocks[index];
+
+		if(bufSize > 0)
+		{
+			std::string string = uniformBlock.name;
+
+			if(uniformBlock.isArrayElement())
+			{
+				std::ostringstream elementIndex;
+				elementIndex << uniformBlock.elementIndex;
+				string += "[" + elementIndex.str()  + "]";
+			}
+
+			strncpy(name, string.c_str(), bufSize);
+			name[bufSize - 1] = '\0';
+
+			if(length)
+			{
+				*length = strlen(name);
+			}
+		}
+	}
+
+	size_t Program::getActiveUniformBlockCount() const
+	{
+		return uniformBlocks.size();
+	}
+
+	GLint Program::getActiveUniformBlockMaxLength() const
+	{
+		size_t maxLength = 0;
+
+		if(isLinked())
+		{
+			size_t numUniformBlocks = getActiveUniformBlockCount();
+			for(size_t uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
+			{
+				const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
+				if(!uniformBlock.name.empty())
+				{
+					size_t length = uniformBlock.name.length() + 1;
+
+					// Counting in "[0]".
+					const int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
+
+					maxLength = std::max(length + arrayLength, maxLength);
+				}
+			}
+		}
+
+		return maxLength;
+	}
+
+	void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
+	{
+		transformFeedbackVaryings.resize(count);
+		for(GLsizei i = 0; i < count; i++)
+		{
+			transformFeedbackVaryings[i] = varyings[i];
+		}
+
+		transformFeedbackBufferMode = bufferMode;
+	}
+
+	void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
+	{
+		if(linked)
+		{
+			ASSERT(index < transformFeedbackLinkedVaryings.size());
+			const LinkedVarying &varying = transformFeedbackLinkedVaryings[index];
+			GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
+			if(length)
+			{
+				*length = lastNameIdx;
+			}
+			if(size)
+			{
+				*size = varying.size;
+			}
+			if(type)
+			{
+				*type = varying.type;
+			}
+			if(name)
+			{
+				memcpy(name, varying.name.c_str(), lastNameIdx);
+				name[lastNameIdx] = '\0';
+			}
+		}
+	}
+
+	GLsizei Program::getTransformFeedbackVaryingCount() const
+	{
+		if(linked)
+		{
+			return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size());
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	GLsizei Program::getTransformFeedbackVaryingMaxLength() const
+	{
+		if(linked)
+		{
+			GLsizei maxSize = 0;
+			for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++)
+			{
+				const LinkedVarying &varying = transformFeedbackLinkedVaryings[i];
+				maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
+			}
+
+			return maxSize;
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	GLenum Program::getTransformFeedbackBufferMode() const
+	{
+		return transformFeedbackBufferMode;
+	}
+
+	void Program::flagForDeletion()
+	{
+		orphaned = true;
+	}
+
+	bool Program::isFlaggedForDeletion() const
+	{
+		return orphaned;
+	}
+
+	void Program::validate()
+	{
+		resetInfoLog();
+
+		if(!isLinked())
+		{
+			appendToInfoLog("Program has not been successfully linked.");
+			validated = false;
+		}
+		else
+		{
+			applyUniforms();
+			if(!validateSamplers(true))
+			{
+				validated = false;
+			}
+			else
+			{
+				validated = true;
+			}
+		}
+	}
+
+	bool Program::validateSamplers(bool logErrors)
+	{
+		// if any two active samplers in a program are of different types, but refer to the same
+		// texture image unit, and this is the current program, then ValidateProgram will fail, and
+		// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
+
+		TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+
+		for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
+		{
+			textureUnitType[i] = TEXTURE_UNKNOWN;
+		}
+
+		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+		{
+			if(samplersPS[i].active)
+			{
+				unsigned int unit = samplersPS[i].logicalTextureUnit;
+
+				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+				{
+					if(logErrors)
+					{
+						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+					}
+
+					return false;
+				}
+
+				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
+				{
+					if(samplersPS[i].textureType != textureUnitType[unit])
+					{
+						if(logErrors)
+						{
+							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+						}
+
+						return false;
+					}
+				}
+				else
+				{
+					textureUnitType[unit] = samplersPS[i].textureType;
+				}
+			}
+		}
+
+		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+		{
+			if(samplersVS[i].active)
+			{
+				unsigned int unit = samplersVS[i].logicalTextureUnit;
+
+				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+				{
+					if(logErrors)
+					{
+						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+					}
+
+					return false;
+				}
+
+				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
+				{
+					if(samplersVS[i].textureType != textureUnitType[unit])
+					{
+						if(logErrors)
+						{
+							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+						}
+
+						return false;
+					}
+				}
+				else
+				{
+					textureUnitType[unit] = samplersVS[i].textureType;
+				}
+			}
+		}
+
+		return true;
+	}
+}
diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h
index 2d08d89..15b5cf3 100644
--- a/src/OpenGL/libGLESv2/Program.h
+++ b/src/OpenGL/libGLESv2/Program.h
@@ -1,322 +1,325 @@
-// 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.

-//

-

-// Program.h: Defines the Program class. Implements GL program objects

-// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.

-

-#ifndef LIBGLESV2_PROGRAM_H_

-#define LIBGLESV2_PROGRAM_H_

-

-#include "Shader.h"

-#include "Context.h"

-#include "Shader/PixelShader.hpp"

-#include "Shader/VertexShader.hpp"

-

-#include <string>

-#include <vector>

-#include <set>

-

-namespace es2

-{

-	class Device;

-	class ResourceManager;

-	class FragmentShader;

-	class VertexShader;

-

-	// Helper struct representing a single shader uniform

-	struct Uniform

-	{

-		struct BlockInfo

-		{

-			BlockInfo(const glsl::Uniform& uniform, int blockIndex);

-

-			int index;

-			int offset;

-			int arrayStride;

-			int matrixStride;

-			bool isRowMajorMatrix;

-		};

-

-		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,

-		        const BlockInfo &blockInfo);

-

-		~Uniform();

-

-		bool isArray() const;

-		int size() const;

-		int registerCount() const;

-

-		const GLenum type;

-		const GLenum precision;

-		const std::string name;

-		const unsigned int arraySize;

-		const BlockInfo blockInfo;

-

-		unsigned char *data;

-		bool dirty;

-

-		short psRegisterIndex;

-		short vsRegisterIndex;

-	};

-

-	// Helper struct representing a single shader uniform block

-	struct UniformBlock

-	{

-		// use GL_INVALID_INDEX for non-array elements

-		UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes);

-

-		void setRegisterIndex(GLenum shader, unsigned int registerIndex);

-

-		bool isArrayElement() const;

-		bool isReferencedByVertexShader() const;

-		bool isReferencedByFragmentShader() const;

-

-		const std::string name;

-		const unsigned int elementIndex;

-		const unsigned int dataSize;

-

-		std::vector<unsigned int> memberUniformIndexes;

-

-		unsigned int psRegisterIndex;

-		unsigned int vsRegisterIndex;

-	};

-

-	// Struct used for correlating uniforms/elements of uniform arrays to handles

-	struct UniformLocation

-	{

-		UniformLocation(const std::string &name, unsigned int element, unsigned int index);

-

-		std::string name;

-		unsigned int element;

-		unsigned int index;

-	};

-

-	struct LinkedVarying

-	{

-		LinkedVarying();

-		LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col);

-

-		// Original GL name

-		std::string name;

-

-		GLenum type;

-		GLsizei size;

-

-		int reg;    // First varying register, assigned during link

-		int col;    // First register element, assigned during link

-	};

-

-	class Program

-	{

-	public:

-		Program(ResourceManager *manager, GLuint handle);

-

-		~Program();

-

-		bool attachShader(Shader *shader);

-		bool detachShader(Shader *shader);

-		int getAttachedShadersCount() const;

-

-		sw::PixelShader *getPixelShader();

-		sw::VertexShader *getVertexShader();

-

-		void bindAttributeLocation(GLuint index, const char *name);

-		GLuint getAttributeLocation(const char *name);

-		int getAttributeStream(int attributeIndex);

-

-		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);

-		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);

-

-		GLuint getUniformIndex(const std::string &name) const;

-		GLuint getUniformBlockIndex(const std::string &name) const;

-		void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);

-		GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;

-		void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;

-

-		GLint getUniformLocation(const std::string &name) const;

-		bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);

-		bool setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

-		bool setUniform1iv(GLint location, GLsizei count, const GLint *v);

-		bool setUniform2iv(GLint location, GLsizei count, const GLint *v);

-		bool setUniform3iv(GLint location, GLsizei count, const GLint *v);

-		bool setUniform4iv(GLint location, GLsizei count, const GLint *v);

-		bool setUniform1uiv(GLint location, GLsizei count, const GLuint *v);

-		bool setUniform2uiv(GLint location, GLsizei count, const GLuint *v);

-		bool setUniform3uiv(GLint location, GLsizei count, const GLuint *v);

-		bool setUniform4uiv(GLint location, GLsizei count, const GLuint *v);

-

-		bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);

-		bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);

-		bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params);

-

-		void dirtyAllUniforms();

-		void applyUniforms();

-		void applyUniformBuffers(BufferBinding* uniformBuffers);

-		void applyTransformFeedback(TransformFeedback* transformFeedback);

-

-		void link();

-		bool isLinked() const;

-		size_t getInfoLogLength() const;

-		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);

-		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);

-

-		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;

-		size_t getActiveAttributeCount() const;

-		GLint getActiveAttributeMaxLength() const;

-

-		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;

-		size_t getActiveUniformCount() const;

-		GLint getActiveUniformMaxLength() const;

-		GLint getActiveUniformi(GLuint index, GLenum pname) const;

-

-		void getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;

-		size_t getActiveUniformBlockCount() const;

-		GLint getActiveUniformBlockMaxLength() const;

-

-		void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);

-		void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;

-		GLsizei getTransformFeedbackVaryingCount() const;

-		GLsizei getTransformFeedbackVaryingMaxLength() const;

-		GLenum getTransformFeedbackBufferMode() const;

-

-		void addRef();

-		void release();

-		unsigned int getRefCount() const;

-		void flagForDeletion();

-		bool isFlaggedForDeletion() const;

-

-		void validate();

-		bool validateSamplers(bool logErrors);

-		bool isValidated() const;

-

-		unsigned int getSerial() const;

-

-		bool getBinaryRetrievableHint() const { return retrievableBinary; }

-		void setBinaryRetrievable(bool retrievable) { retrievableBinary = retrievable; }

-		GLint getBinaryLength() const;

-

-	private:

-		void unlink();

-		void resetUniformBlockBindings();

-

-		bool linkVaryings();

-		bool linkTransformFeedback();

-

-		bool linkAttributes();

-		int getAttributeBinding(const glsl::Attribute &attribute);

-

-		bool linkUniforms(const Shader *shader);

-		bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader);

-		bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2);

-		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo);

-		bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block);

-		bool applyUniform(GLint location, float* data);

-		bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v);

-		bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v);

-		bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value);

-		bool applyUniform1iv(GLint location, GLsizei count, const GLint *v);

-		bool applyUniform2iv(GLint location, GLsizei count, const GLint *v);

-		bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);

-		bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);

-		bool applyUniform1uiv(GLint location, GLsizei count, const GLuint *v);

-		bool applyUniform2uiv(GLint location, GLsizei count, const GLuint *v);

-		bool applyUniform3uiv(GLint location, GLsizei count, const GLuint *v);

-		bool applyUniform4uiv(GLint location, GLsizei count, const GLuint *v);

-

-		bool setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements);

-		bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type);

-		bool setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements);

-		bool setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements);

-

-		void appendToInfoLog(const char *info, ...);

-		void resetInfoLog();

-

-		static unsigned int issueSerial();

-

-	private:

-		es2::Device *device;

-		FragmentShader *fragmentShader;

-		VertexShader *vertexShader;

-

-		sw::PixelShader *pixelBinary;

-		sw::VertexShader *vertexBinary;

-

-		std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];

-		glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];

-		int attributeStream[MAX_VERTEX_ATTRIBS];

-

-		GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS];

-

-		std::vector<std::string> transformFeedbackVaryings;

-		GLenum transformFeedbackBufferMode;

-		size_t totalLinkedVaryingsComponents;

-

-		struct Sampler

-		{

-			bool active;

-			GLint logicalTextureUnit;

-			TextureType textureType;

-		};

-

-		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];

-		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];

-

-		typedef std::vector<Uniform*> UniformArray;

-		UniformArray uniforms;

-		typedef std::vector<UniformLocation> UniformIndex;

-		UniformIndex uniformIndex;

-		typedef std::vector<UniformBlock*> UniformBlockArray;

-		UniformBlockArray uniformBlocks;

-		typedef std::vector<LinkedVarying> LinkedVaryingArray;

-		LinkedVaryingArray transformFeedbackLinkedVaryings;

-

-		bool linked;

-		bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use

-		char *infoLog;

-		bool validated;

-		bool retrievableBinary;

-

-		unsigned int referenceCount;

-		const unsigned int serial;

-

-		static unsigned int currentSerial;

-

-		ResourceManager *resourceManager;

-		const GLuint handle;

-	};

-}

-

-#endif   // LIBGLESV2_PROGRAM_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Program.h: Defines the Program class. Implements GL program objects
+// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
+
+#ifndef LIBGLESV2_PROGRAM_H_
+#define LIBGLESV2_PROGRAM_H_
+
+#include "Shader.h"
+#include "Context.h"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+
+#include <string>
+#include <vector>
+#include <set>
+
+namespace es2
+{
+	class Device;
+	class ResourceManager;
+	class FragmentShader;
+	class VertexShader;
+
+	// Helper struct representing a single shader uniform
+	struct Uniform
+	{
+		struct BlockInfo
+		{
+			BlockInfo(const glsl::Uniform& uniform, int blockIndex);
+
+			int index;
+			int offset;
+			int arrayStride;
+			int matrixStride;
+			bool isRowMajorMatrix;
+		};
+
+		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
+		        const BlockInfo &blockInfo);
+
+		~Uniform();
+
+		bool isArray() const;
+		int size() const;
+		int registerCount() const;
+
+		const GLenum type;
+		const GLenum precision;
+		const std::string name;
+		const unsigned int arraySize;
+		const BlockInfo blockInfo;
+
+		unsigned char *data;
+		bool dirty;
+
+		short psRegisterIndex;
+		short vsRegisterIndex;
+	};
+
+	// Helper struct representing a single shader uniform block
+	struct UniformBlock
+	{
+		// use GL_INVALID_INDEX for non-array elements
+		UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes);
+
+		void setRegisterIndex(GLenum shader, unsigned int registerIndex);
+
+		bool isArrayElement() const;
+		bool isReferencedByVertexShader() const;
+		bool isReferencedByFragmentShader() const;
+
+		const std::string name;
+		const unsigned int elementIndex;
+		const unsigned int dataSize;
+
+		std::vector<unsigned int> memberUniformIndexes;
+
+		unsigned int psRegisterIndex;
+		unsigned int vsRegisterIndex;
+	};
+
+	// Struct used for correlating uniforms/elements of uniform arrays to handles
+	struct UniformLocation
+	{
+		UniformLocation(const std::string &name, unsigned int element, unsigned int index);
+
+		std::string name;
+		unsigned int element;
+		unsigned int index;
+	};
+
+	struct LinkedVarying
+	{
+		LinkedVarying();
+		LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col);
+
+		// Original GL name
+		std::string name;
+
+		GLenum type;
+		GLsizei size;
+
+		int reg;    // First varying register, assigned during link
+		int col;    // First register element, assigned during link
+	};
+
+	class Program
+	{
+	public:
+		Program(ResourceManager *manager, GLuint handle);
+
+		~Program();
+
+		bool attachShader(Shader *shader);
+		bool detachShader(Shader *shader);
+		int getAttachedShadersCount() const;
+
+		sw::PixelShader *getPixelShader();
+		sw::VertexShader *getVertexShader();
+
+		void bindAttributeLocation(GLuint index, const char *name);
+		GLuint getAttributeLocation(const char *name);
+		int getAttributeStream(int attributeIndex);
+
+		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);
+		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);
+
+		GLuint getUniformIndex(const std::string &name) const;
+		GLuint getUniformBlockIndex(const std::string &name) const;
+		void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+		GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
+		void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
+
+		GLint getUniformLocation(const std::string &name) const;
+		bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
+		bool setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+		bool setUniform1iv(GLint location, GLsizei count, const GLint *v);
+		bool setUniform2iv(GLint location, GLsizei count, const GLint *v);
+		bool setUniform3iv(GLint location, GLsizei count, const GLint *v);
+		bool setUniform4iv(GLint location, GLsizei count, const GLint *v);
+		bool setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
+		bool setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
+		bool setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
+		bool setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
+
+		bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
+		bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
+		bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params);
+
+		void dirtyAllUniforms();
+		void applyUniforms();
+		void applyUniformBuffers(BufferBinding* uniformBuffers);
+		void applyTransformFeedback(TransformFeedback* transformFeedback);
+
+		void link();
+		bool isLinked() const;
+		size_t getInfoLogLength() const;
+		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
+		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
+
+		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
+		size_t getActiveAttributeCount() const;
+		GLint getActiveAttributeMaxLength() const;
+
+		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
+		size_t getActiveUniformCount() const;
+		GLint getActiveUniformMaxLength() const;
+		GLint getActiveUniformi(GLuint index, GLenum pname) const;
+
+		void getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
+		size_t getActiveUniformBlockCount() const;
+		GLint getActiveUniformBlockMaxLength() const;
+
+		void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);
+		void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
+		GLsizei getTransformFeedbackVaryingCount() const;
+		GLsizei getTransformFeedbackVaryingMaxLength() const;
+		GLenum getTransformFeedbackBufferMode() const;
+
+		void addRef();
+		void release();
+		unsigned int getRefCount() const;
+		void flagForDeletion();
+		bool isFlaggedForDeletion() const;
+
+		void validate();
+		bool validateSamplers(bool logErrors);
+		bool isValidated() const;
+
+		unsigned int getSerial() const;
+
+		bool getBinaryRetrievableHint() const { return retrievableBinary; }
+		void setBinaryRetrievable(bool retrievable) { retrievableBinary = retrievable; }
+		GLint getBinaryLength() const;
+
+	private:
+		void unlink();
+		void resetUniformBlockBindings();
+
+		bool linkVaryings();
+		bool linkTransformFeedback();
+
+		bool linkAttributes();
+		int getAttributeBinding(const glsl::Attribute &attribute);
+
+		bool linkUniforms(const Shader *shader);
+		bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader);
+		bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2);
+		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo);
+		bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block);
+		bool applyUniform(GLint location, float* data);
+		bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v);
+		bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v);
+		bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value);
+		bool applyUniform1iv(GLint location, GLsizei count, const GLint *v);
+		bool applyUniform2iv(GLint location, GLsizei count, const GLint *v);
+		bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
+		bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);
+		bool applyUniform1uiv(GLint location, GLsizei count, const GLuint *v);
+		bool applyUniform2uiv(GLint location, GLsizei count, const GLuint *v);
+		bool applyUniform3uiv(GLint location, GLsizei count, const GLuint *v);
+		bool applyUniform4uiv(GLint location, GLsizei count, const GLuint *v);
+
+		bool setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements);
+		bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type);
+		bool setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements);
+		bool setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements);
+
+		void appendToInfoLog(const char *info, ...);
+		void resetInfoLog();
+
+		static unsigned int issueSerial();
+
+	private:
+		es2::Device *device;
+		FragmentShader *fragmentShader;
+		VertexShader *vertexShader;
+
+		sw::PixelShader *pixelBinary;
+		sw::VertexShader *vertexBinary;
+
+		std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];
+		glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];
+		int attributeStream[MAX_VERTEX_ATTRIBS];
+
+		GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS];
+
+		std::vector<std::string> transformFeedbackVaryings;
+		GLenum transformFeedbackBufferMode;
+		size_t totalLinkedVaryingsComponents;
+
+		struct Sampler
+		{
+			bool active;
+			GLint logicalTextureUnit;
+			TextureType textureType;
+		};
+
+		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];
+		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+
+		typedef std::vector<Uniform*> UniformArray;
+		UniformArray uniforms;
+		typedef std::vector<UniformLocation> UniformIndex;
+		UniformIndex uniformIndex;
+		typedef std::vector<UniformBlock*> UniformBlockArray;
+		UniformBlockArray uniformBlocks;
+		typedef std::vector<LinkedVarying> LinkedVaryingArray;
+		LinkedVaryingArray transformFeedbackLinkedVaryings;
+
+		bool linked;
+		bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use
+		char *infoLog;
+		bool validated;
+		bool retrievableBinary;
+
+		unsigned int referenceCount;
+		const unsigned int serial;
+
+		static unsigned int currentSerial;
+
+		ResourceManager *resourceManager;
+		const GLuint handle;
+	};
+}
+
+#endif   // LIBGLESV2_PROGRAM_H_
diff --git a/src/OpenGL/libGLESv2/Query.cpp b/src/OpenGL/libGLESv2/Query.cpp
index 223cfc3..027f8ab 100644
--- a/src/OpenGL/libGLESv2/Query.cpp
+++ b/src/OpenGL/libGLESv2/Query.cpp
@@ -1,167 +1,167 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Query.cpp: Implements the es2::Query class

-

-#include "Query.h"

-

-#include "main.h"

-#include "Common/Thread.hpp"

-

-namespace es2

-{

-

-Query::Query(GLuint name, GLenum type) : NamedObject(name)

-{

-    mQuery = nullptr;

-    mStatus = GL_FALSE;

-    mResult = GL_FALSE;

-    mType = type;

-}

-

-Query::~Query()

-{

-    if(mQuery)

-    {

-        delete mQuery;

-    }

-}

-

-void Query::begin()

-{

-    if(!mQuery)

-    {

-		sw::Query::Type type;

-		switch(mType)

-		{

-		case GL_ANY_SAMPLES_PASSED_EXT:

-		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-			type = sw::Query::FRAGMENTS_PASSED;

-			break;

-		case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:

-			type = sw::Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;

-			break;

-		default:

-			UNREACHABLE(mType);

-			return;

-		}

-

-		mQuery = new sw::Query(type);

-

-		if(!mQuery)

-        {

-            return error(GL_OUT_OF_MEMORY);

-        }

-    }

-

-	Device *device = getDevice();

-

-	mQuery->begin();

-	device->addQuery(mQuery);

-	switch(mType)

-	{

-	case GL_ANY_SAMPLES_PASSED_EXT:

-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-		device->setOcclusionEnabled(true);

-		break;

-	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:

-		device->setTransformFeedbackQueryEnabled(true);

-		break;

-	default:

-		ASSERT(false);

-	}

-}

-

-void Query::end()

-{

-    if(!mQuery)

-    {

-        return error(GL_INVALID_OPERATION);

-	}

-

-	Device *device = getDevice();

-

-    mQuery->end();

-	device->removeQuery(mQuery);

-	switch(mType)

-	{

-	case GL_ANY_SAMPLES_PASSED_EXT:

-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-		device->setOcclusionEnabled(false);

-		break;

-	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:

-		device->setTransformFeedbackQueryEnabled(false);

-		break;

-	default:

-		ASSERT(false);

-	}

-

-    mStatus = GL_FALSE;

-    mResult = GL_FALSE;

-}

-

-GLuint Query::getResult()

-{

-    if(mQuery)

-    {

-        while(!testQuery())

-        {

-            sw::Thread::yield();

-        }

-    }

-

-    return (GLuint)mResult;

-}

-

-GLboolean Query::isResultAvailable()

-{

-    if(mQuery)

-    {

-        testQuery();

-    }

-

-    return mStatus;

-}

-

-GLenum Query::getType() const

-{

-    return mType;

-}

-

-GLboolean Query::testQuery()

-{

-    if(mQuery != nullptr && mStatus != GL_TRUE)

-    {

-        if(!mQuery->building && mQuery->reference == 0)

-        {

-			unsigned int resultSum = mQuery->data;

-            mStatus = GL_TRUE;

-

-            switch(mType)

-            {

-            case GL_ANY_SAMPLES_PASSED_EXT:

-            case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-				mResult = (resultSum > 0) ? GL_TRUE : GL_FALSE;

-                break;

-            case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:

-				mResult = resultSum;

-                break;

-            default:

-                ASSERT(false);

-            }

-        }

-

-        return mStatus;

-    }

-

-    return GL_TRUE;   // Prevent blocking when query is nullptr

-}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Query.cpp: Implements the es2::Query class
+
+#include "Query.h"
+
+#include "main.h"
+#include "Common/Thread.hpp"
+
+namespace es2
+{
+
+Query::Query(GLuint name, GLenum type) : NamedObject(name)
+{
+	mQuery = nullptr;
+	mStatus = GL_FALSE;
+	mResult = GL_FALSE;
+	mType = type;
+}
+
+Query::~Query()
+{
+	delete mQuery;
+}
+
+void Query::begin()
+{
+	if(!mQuery)
+	{
+		sw::Query::Type type;
+		switch(mType)
+		{
+		case GL_ANY_SAMPLES_PASSED_EXT:
+		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+			type = sw::Query::FRAGMENTS_PASSED;
+			break;
+		case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+			type = sw::Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
+			break;
+		default:
+			UNREACHABLE(mType);
+			return;
+		}
+
+		mQuery = new sw::Query(type);
+
+		if(!mQuery)
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+	}
+
+	Device *device = getDevice();
+
+	mQuery->begin();
+	device->addQuery(mQuery);
+	switch(mType)
+	{
+	case GL_ANY_SAMPLES_PASSED_EXT:
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+		device->setOcclusionEnabled(true);
+		break;
+	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+		device->setTransformFeedbackQueryEnabled(true);
+		break;
+	default:
+		ASSERT(false);
+	}
+}
+
+void Query::end()
+{
+	if(!mQuery)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	Device *device = getDevice();
+
+	mQuery->end();
+	device->removeQuery(mQuery);
+	switch(mType)
+	{
+	case GL_ANY_SAMPLES_PASSED_EXT:
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+		device->setOcclusionEnabled(false);
+		break;
+	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+		device->setTransformFeedbackQueryEnabled(false);
+		break;
+	default:
+		ASSERT(false);
+	}
+
+	mStatus = GL_FALSE;
+	mResult = GL_FALSE;
+}
+
+GLuint Query::getResult()
+{
+	if(mQuery)
+	{
+		while(!testQuery())
+		{
+			sw::Thread::yield();
+		}
+	}
+
+	return (GLuint)mResult;
+}
+
+GLboolean Query::isResultAvailable()
+{
+	if(mQuery)
+	{
+		testQuery();
+	}
+
+	return mStatus;
+}
+
+GLenum Query::getType() const
+{
+	return mType;
+}
+
+GLboolean Query::testQuery()
+{
+	if(mQuery != nullptr && mStatus != GL_TRUE)
+	{
+		if(!mQuery->building && mQuery->reference == 0)
+		{
+			unsigned int resultSum = mQuery->data;
+			mStatus = GL_TRUE;
+
+			switch(mType)
+			{
+			case GL_ANY_SAMPLES_PASSED_EXT:
+			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+				mResult = (resultSum > 0) ? GL_TRUE : GL_FALSE;
+				break;
+			case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+				mResult = resultSum;
+				break;
+			default:
+				ASSERT(false);
+			}
+		}
+
+		return mStatus;
+	}
+
+	return GL_TRUE;   // Prevent blocking when query is nullptr
+}
+}
diff --git a/src/OpenGL/libGLESv2/Query.h b/src/OpenGL/libGLESv2/Query.h
index 04967ba..b9e0c52 100644
--- a/src/OpenGL/libGLESv2/Query.h
+++ b/src/OpenGL/libGLESv2/Query.h
@@ -1,49 +1,52 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// Query.h: Defines the es2::Query class

-

-#ifndef LIBGLESV2_QUERY_H_

-#define LIBGLESV2_QUERY_H_

-

-#include "common/Object.hpp"

-#include "Renderer/Renderer.hpp"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-

-class Query : public gl::NamedObject

-{

-  public:

-    Query(GLuint name, GLenum type);

-    virtual ~Query();

-

-    void begin();

-    void end();

-    GLuint getResult();

-    GLboolean isResultAvailable();

-

-    GLenum getType() const;

-

-  private:

-    GLboolean testQuery();

-

-    sw::Query* mQuery;

-    GLenum mType;

-    GLboolean mStatus;

-    GLint mResult;

-};

-

-}

-

-#endif   // LIBGLESV2_QUERY_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Query.h: Defines the es2::Query class
+
+#ifndef LIBGLESV2_QUERY_H_
+#define LIBGLESV2_QUERY_H_
+
+#include "common/Object.hpp"
+#include "Renderer/Renderer.hpp"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+
+class Query : public gl::NamedObject
+{
+public:
+	Query(GLuint name, GLenum type);
+	virtual ~Query();
+
+	void begin();
+	void end();
+	GLuint getResult();
+	GLboolean isResultAvailable();
+
+	GLenum getType() const;
+
+private:
+	GLboolean testQuery();
+
+	sw::Query* mQuery;
+	GLenum mType;
+	GLboolean mStatus;
+	GLint mResult;
+};
+
+}
+
+#endif   // LIBGLESV2_QUERY_H_
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.cpp b/src/OpenGL/libGLESv2/Renderbuffer.cpp
index d297046..9b92698 100644
--- a/src/OpenGL/libGLESv2/Renderbuffer.cpp
+++ b/src/OpenGL/libGLESv2/Renderbuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
@@ -27,7 +30,7 @@
 
 // The default case for classes inherited from RenderbufferInterface is not to
 // need to do anything upon the reference count to the parent Renderbuffer incrementing
-// or decrementing. 
+// or decrementing.
 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
 {
 }
@@ -227,12 +230,12 @@
 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
 {
-    mTextureCubeMap->addProxyRef(proxy);
+	mTextureCubeMap->addProxyRef(proxy);
 }
 
 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
 {
-    mTextureCubeMap->releaseProxy(proxy);
+	mTextureCubeMap->releaseProxy(proxy);
 }
 
 // Increments refcount on image.
@@ -283,7 +286,7 @@
 
 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
 {
-	ASSERT(instance != NULL);
+	ASSERT(instance);
 	mInstance = instance;
 }
 
@@ -296,16 +299,16 @@
 // its own reference count, so we pass it on here.
 void Renderbuffer::addRef()
 {
-    mInstance->addProxyRef(this);
+	mInstance->addProxyRef(this);
 
-    Object::addRef();
+	Object::addRef();
 }
 
 void Renderbuffer::release()
 {
-    mInstance->releaseProxy(this);
+	mInstance->releaseProxy(this);
 
-    Object::release();
+	Object::release();
 }
 
 // Increments refcount on image.
@@ -319,12 +322,12 @@
 // caller must Release() the returned image
 egl::Image *Renderbuffer::createSharedImage()
 {
-    return mInstance->createSharedImage();
+	return mInstance->createSharedImage();
 }
 
 bool Renderbuffer::isShared() const
 {
-    return mInstance->isShared();
+	return mInstance->isShared();
 }
 
 GLsizei Renderbuffer::getWidth() const
@@ -458,7 +461,7 @@
 	if(renderTarget)
 	{
 		renderTarget->addRef();
-		
+
 		mWidth = renderTarget->getWidth();
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
@@ -516,18 +519,18 @@
 // caller must release() the returned image
 egl::Image *Colorbuffer::createSharedImage()
 {
-    if(mRenderTarget)
-    {
-        mRenderTarget->addRef();
-        mRenderTarget->markShared();
-    }
+	if(mRenderTarget)
+	{
+		mRenderTarget->addRef();
+		mRenderTarget->markShared();
+	}
 
-    return mRenderTarget;
+	return mRenderTarget;
 }
 
 bool Colorbuffer::isShared() const
 {
-    return mRenderTarget->isShared();
+	return mRenderTarget->isShared();
 }
 
 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
@@ -616,18 +619,18 @@
 // caller must release() the returned image
 egl::Image *DepthStencilbuffer::createSharedImage()
 {
-    if(mDepthStencil)
-    {
-        mDepthStencil->addRef();
-        mDepthStencil->markShared();
-    }
+	if(mDepthStencil)
+	{
+		mDepthStencil->addRef();
+		mDepthStencil->markShared();
+	}
 
-    return mDepthStencil;
+	return mDepthStencil;
 }
 
 bool DepthStencilbuffer::isShared() const
 {
-    return mDepthStencil->isShared();
+	return mDepthStencil->isShared();
 }
 
 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.h b/src/OpenGL/libGLESv2/Renderbuffer.h
index d40d141..5e3f124 100644
--- a/src/OpenGL/libGLESv2/Renderbuffer.h
+++ b/src/OpenGL/libGLESv2/Renderbuffer.h
@@ -1,280 +1,283 @@
-// 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.

-//

-

-// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the

-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,

-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer

-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.

-

-#ifndef LIBGLESV2_RENDERBUFFER_H_

-#define LIBGLESV2_RENDERBUFFER_H_

-

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-class Texture2D;

-class Texture3D;

-class TextureCubeMap;

-class Renderbuffer;

-class Colorbuffer;

-class DepthStencilbuffer;

-

-class RenderbufferInterface

-{

-public:

-	RenderbufferInterface();

-

-	virtual ~RenderbufferInterface() {};

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget() = 0;

-    virtual egl::Image *createSharedImage() = 0;

-    virtual bool isShared() const = 0;

-

-	virtual GLsizei getWidth() const = 0;

-	virtual GLsizei getHeight() const = 0;

-	virtual GLsizei getDepth() const { return 1; }

-	virtual GLint getLayer() const { return 0; }

-	virtual GLint getLevel() const { return 0; }

-	virtual GLenum getFormat() const = 0;

-	virtual sw::Format getInternalFormat() const = 0;

-	virtual GLsizei getSamples() const = 0;

-

-	virtual void setLayer(GLint) {}

-	virtual void setLevel(GLint) {}

-

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-};

-

-class RenderbufferTexture2D : public RenderbufferInterface

-{

-public:

-	RenderbufferTexture2D(Texture2D *texture, GLint level);

-

-	virtual ~RenderbufferTexture2D();

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLint getLevel() const { return mLevel; }

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-	virtual void setLevel(GLint level) { mLevel = level; }

-

-private:

-	gl::BindingPointer<Texture2D> mTexture2D;

-	GLint mLevel;

-};

-

-class RenderbufferTexture3D : public RenderbufferInterface

-{

-public:

-	RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer);

-

-	virtual ~RenderbufferTexture3D();

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-	virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget();

-	virtual egl::Image *createSharedImage();

-	virtual bool isShared() const;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLsizei getDepth() const;

-	virtual GLint getLayer() const { return mLayer; }

-	virtual GLint getLevel() const { return mLevel; }

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-	virtual void setLayer(GLint layer) { mLayer = layer; }

-	virtual void setLevel(GLint level) { mLevel = level; }

-

-private:

-	gl::BindingPointer<Texture3D> mTexture3D;

-	GLint mLevel;

-	GLint mLayer;

-};

-

-class RenderbufferTextureCubeMap : public RenderbufferInterface

-{

-public:

-	RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level);

-

-	virtual ~RenderbufferTextureCubeMap();

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLint getLevel() const { return mLevel; }

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-	virtual void setLevel(GLint level) { mLevel = level; }

-

-private:

-	gl::BindingPointer<TextureCubeMap> mTextureCubeMap;

-	GLenum mTarget;

-	GLint mLevel;

-};

-

-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage

-// is called. The specific concrete type depends on whether the internal format is

-// colour depth, stencil or packed depth/stencil.

-class RenderbufferStorage : public RenderbufferInterface

-{

-public:

-	RenderbufferStorage();

-

-	virtual ~RenderbufferStorage() = 0;

-

-	virtual egl::Image *getRenderTarget() = 0;

-    virtual egl::Image *createSharedImage() = 0;

-    virtual bool isShared() const = 0;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-protected:

-	GLsizei mWidth;

-	GLsizei mHeight;

-	GLenum format;

-	sw::Format internalFormat;

-	GLsizei mSamples;

-};

-

-// Renderbuffer implements the GL renderbuffer object.

-// It's only a proxy for a RenderbufferInterface instance; the internal object

-// can change whenever glRenderbufferStorage is called.

-class Renderbuffer : public gl::NamedObject

-{

-public:

-	Renderbuffer(GLuint name, RenderbufferInterface *storage);

-

-	virtual ~Renderbuffer();

-

-	// These functions from Object are overloaded here because

-    // Textures need to maintain their own count of references to them via

-    // Renderbuffers/RenderbufferTextures. These functions invoke those

-    // reference counting functions on the RenderbufferInterface.

-    virtual void addRef();

-    virtual void release();

-

-	egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-	GLsizei getWidth() const;

-	GLsizei getHeight() const;

-	GLsizei getDepth() const;

-	GLint getLayer() const;

-	GLint getLevel() const;

-	GLenum getFormat() const;

-	sw::Format getInternalFormat() const;

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-	GLsizei getSamples() const;

-

-	void setLayer(GLint layer);

-	void setLevel(GLint level);

-	void setStorage(RenderbufferStorage *newStorage);

-

-private:

-	RenderbufferInterface *mInstance;

-};

-

-class Colorbuffer : public RenderbufferStorage

-{

-public:

-	explicit Colorbuffer(egl::Image *renderTarget);

-	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);

-

-	virtual ~Colorbuffer();

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-private:

-	egl::Image *mRenderTarget;

-};

-

-class DepthStencilbuffer : public RenderbufferStorage

-{

-public:

-	explicit DepthStencilbuffer(egl::Image *depthStencil);

-	DepthStencilbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);

-

-	~DepthStencilbuffer();

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-protected:

-	egl::Image *mDepthStencil;

-};

-

-class Depthbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Depthbuffer(egl::Image *depthStencil);

-	Depthbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);

-

-	virtual ~Depthbuffer();

-};

-

-class Stencilbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Stencilbuffer(egl::Image *depthStencil);

-	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	virtual ~Stencilbuffer();

-};

-}

-

-#endif   // LIBGLESV2_RENDERBUFFER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the
+// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
+// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+
+#ifndef LIBGLESV2_RENDERBUFFER_H_
+#define LIBGLESV2_RENDERBUFFER_H_
+
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+class Texture2D;
+class Texture3D;
+class TextureCubeMap;
+class Renderbuffer;
+class Colorbuffer;
+class DepthStencilbuffer;
+
+class RenderbufferInterface
+{
+public:
+	RenderbufferInterface();
+
+	virtual ~RenderbufferInterface() {};
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+    virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget() = 0;
+    virtual egl::Image *createSharedImage() = 0;
+    virtual bool isShared() const = 0;
+
+	virtual GLsizei getWidth() const = 0;
+	virtual GLsizei getHeight() const = 0;
+	virtual GLsizei getDepth() const { return 1; }
+	virtual GLint getLayer() const { return 0; }
+	virtual GLint getLevel() const { return 0; }
+	virtual GLenum getFormat() const = 0;
+	virtual sw::Format getInternalFormat() const = 0;
+	virtual GLsizei getSamples() const = 0;
+
+	virtual void setLayer(GLint) {}
+	virtual void setLevel(GLint) {}
+
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+};
+
+class RenderbufferTexture2D : public RenderbufferInterface
+{
+public:
+	RenderbufferTexture2D(Texture2D *texture, GLint level);
+
+	virtual ~RenderbufferTexture2D();
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+    virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLint getLevel() const { return mLevel; }
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+	virtual void setLevel(GLint level) { mLevel = level; }
+
+private:
+	gl::BindingPointer<Texture2D> mTexture2D;
+	GLint mLevel;
+};
+
+class RenderbufferTexture3D : public RenderbufferInterface
+{
+public:
+	RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer);
+
+	virtual ~RenderbufferTexture3D();
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+	virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget();
+	virtual egl::Image *createSharedImage();
+	virtual bool isShared() const;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLsizei getDepth() const;
+	virtual GLint getLayer() const { return mLayer; }
+	virtual GLint getLevel() const { return mLevel; }
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+	virtual void setLayer(GLint layer) { mLayer = layer; }
+	virtual void setLevel(GLint level) { mLevel = level; }
+
+private:
+	gl::BindingPointer<Texture3D> mTexture3D;
+	GLint mLevel;
+	GLint mLayer;
+};
+
+class RenderbufferTextureCubeMap : public RenderbufferInterface
+{
+public:
+	RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level);
+
+	virtual ~RenderbufferTextureCubeMap();
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+    virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLint getLevel() const { return mLevel; }
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+	virtual void setLevel(GLint level) { mLevel = level; }
+
+private:
+	gl::BindingPointer<TextureCubeMap> mTextureCubeMap;
+	GLenum mTarget;
+	GLint mLevel;
+};
+
+// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
+// is called. The specific concrete type depends on whether the internal format is
+// colour depth, stencil or packed depth/stencil.
+class RenderbufferStorage : public RenderbufferInterface
+{
+public:
+	RenderbufferStorage();
+
+	virtual ~RenderbufferStorage() = 0;
+
+	virtual egl::Image *getRenderTarget() = 0;
+    virtual egl::Image *createSharedImage() = 0;
+    virtual bool isShared() const = 0;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+protected:
+	GLsizei mWidth;
+	GLsizei mHeight;
+	GLenum format;
+	sw::Format internalFormat;
+	GLsizei mSamples;
+};
+
+// Renderbuffer implements the GL renderbuffer object.
+// It's only a proxy for a RenderbufferInterface instance; the internal object
+// can change whenever glRenderbufferStorage is called.
+class Renderbuffer : public gl::NamedObject
+{
+public:
+	Renderbuffer(GLuint name, RenderbufferInterface *storage);
+
+	virtual ~Renderbuffer();
+
+	// These functions from Object are overloaded here because
+    // Textures need to maintain their own count of references to them via
+    // Renderbuffers/RenderbufferTextures. These functions invoke those
+    // reference counting functions on the RenderbufferInterface.
+    virtual void addRef();
+    virtual void release();
+
+	egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+	GLsizei getWidth() const;
+	GLsizei getHeight() const;
+	GLsizei getDepth() const;
+	GLint getLayer() const;
+	GLint getLevel() const;
+	GLenum getFormat() const;
+	sw::Format getInternalFormat() const;
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+	GLsizei getSamples() const;
+
+	void setLayer(GLint layer);
+	void setLevel(GLint level);
+	void setStorage(RenderbufferStorage *newStorage);
+
+private:
+	RenderbufferInterface *mInstance;
+};
+
+class Colorbuffer : public RenderbufferStorage
+{
+public:
+	explicit Colorbuffer(egl::Image *renderTarget);
+	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+
+	virtual ~Colorbuffer();
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+private:
+	egl::Image *mRenderTarget;
+};
+
+class DepthStencilbuffer : public RenderbufferStorage
+{
+public:
+	explicit DepthStencilbuffer(egl::Image *depthStencil);
+	DepthStencilbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+
+	~DepthStencilbuffer();
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+protected:
+	egl::Image *mDepthStencil;
+};
+
+class Depthbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Depthbuffer(egl::Image *depthStencil);
+	Depthbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+
+	virtual ~Depthbuffer();
+};
+
+class Stencilbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Stencilbuffer(egl::Image *depthStencil);
+	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	virtual ~Stencilbuffer();
+};
+}
+
+#endif   // LIBGLESV2_RENDERBUFFER_H_
diff --git a/src/OpenGL/libGLESv2/ResourceManager.cpp b/src/OpenGL/libGLESv2/ResourceManager.cpp
index 934b455..e5c5492 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.cpp
+++ b/src/OpenGL/libGLESv2/ResourceManager.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // ResourceManager.cpp: Implements the ResourceManager class, which tracks and
 // retrieves objects which may be shared by multiple Contexts.
@@ -26,35 +29,35 @@
 {
 ResourceManager::ResourceManager()
 {
-    mRefCount = 1;
+	mRefCount = 1;
 }
 
 ResourceManager::~ResourceManager()
 {
-    while(!mBufferNameSpace.empty())
-    {
-        deleteBuffer(mBufferNameSpace.firstName());
-    }
+	while(!mBufferNameSpace.empty())
+	{
+		deleteBuffer(mBufferNameSpace.firstName());
+	}
 
 	while(!mProgramNameSpace.empty())
-    {
+	{
 		deleteProgram(mProgramNameSpace.firstName());
-    }
+	}
 
 	while(!mShaderNameSpace.empty())
-    {
+	{
 		deleteShader(mShaderNameSpace.firstName());
-    }
+	}
 
-    while(!mRenderbufferNameSpace.empty())
-    {
-        deleteRenderbuffer(mRenderbufferNameSpace.firstName());
-    }
+	while(!mRenderbufferNameSpace.empty())
+	{
+		deleteRenderbuffer(mRenderbufferNameSpace.firstName());
+	}
 
-    while(!mTextureNameSpace.empty())
-    {
-        deleteTexture(mTextureNameSpace.firstName());
-    }
+	while(!mTextureNameSpace.empty())
+	{
+		deleteTexture(mTextureNameSpace.firstName());
+	}
 
 	while(!mSamplerNameSpace.empty())
 	{
@@ -69,21 +72,21 @@
 
 void ResourceManager::addRef()
 {
-    mRefCount++;
+	mRefCount++;
 }
 
 void ResourceManager::release()
 {
-    if(--mRefCount == 0)
-    {
-        delete this;
-    }
+	if(--mRefCount == 0)
+	{
+		delete this;
+	}
 }
 
 // Returns an unused buffer name
 GLuint ResourceManager::createBuffer()
 {
-    return mBufferNameSpace.allocate();
+	return mBufferNameSpace.allocate();
 }
 
 // Returns an unused shader name
@@ -91,15 +94,15 @@
 {
 	GLuint name = mProgramShaderNameSpace.allocate();
 
-    if(type == GL_VERTEX_SHADER)
-    {
+	if(type == GL_VERTEX_SHADER)
+	{
 		mShaderNameSpace.insert(name, new VertexShader(this, name));
-    }
-    else if(type == GL_FRAGMENT_SHADER)
-    {
+	}
+	else if(type == GL_FRAGMENT_SHADER)
+	{
 		mShaderNameSpace.insert(name, new FragmentShader(this, name));
-    }
-    else UNREACHABLE(type);
+	}
+	else UNREACHABLE(type);
 
 	return name;
 }
@@ -149,68 +152,68 @@
 {
 	Buffer *bufferObject = mBufferNameSpace.remove(buffer);
 
-    if(bufferObject)
-    {
+	if(bufferObject)
+	{
 		bufferObject->release();
-    }
+	}
 }
 
 void ResourceManager::deleteShader(GLuint shader)
 {
-    Shader *shaderObject = mShaderNameSpace.find(shader);
+	Shader *shaderObject = mShaderNameSpace.find(shader);
 
-    if(shaderObject)
-    {
-        if(shaderObject->getRefCount() == 0)
-        {
+	if(shaderObject)
+	{
+		if(shaderObject->getRefCount() == 0)
+		{
 			delete shaderObject;
 			mShaderNameSpace.remove(shader);
 			mProgramShaderNameSpace.remove(shader);
-        }
-        else
-        {
-            shaderObject->flagForDeletion();
-        }
-    }
+		}
+		else
+		{
+			shaderObject->flagForDeletion();
+		}
+	}
 }
 
 void ResourceManager::deleteProgram(GLuint program)
 {
-    Program *programObject = mProgramNameSpace.find(program);
+	Program *programObject = mProgramNameSpace.find(program);
 
-    if(programObject)
-    {
-        if(programObject->getRefCount() == 0)
-        {
+	if(programObject)
+	{
+		if(programObject->getRefCount() == 0)
+		{
 			delete programObject;
 			mProgramNameSpace.remove(program);
 			mProgramShaderNameSpace.remove(program);
-        }
-        else
-        {
-            programObject->flagForDeletion();
-        }
-    }
+		}
+		else
+		{
+			programObject->flagForDeletion();
+		}
+	}
 }
 
 void ResourceManager::deleteTexture(GLuint texture)
 {
-    Texture *textureObject = mTextureNameSpace.remove(texture);
+	Texture *textureObject = mTextureNameSpace.remove(texture);
 
-    if(textureObject)
-    {
+	if(textureObject)
+	{
 		textureObject->release();
-    }
+	}
 }
 
 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
 {
-    Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
+	Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
 
-    if(renderbufferObject)
-    {
+	if(renderbufferObject)
+	{
 		renderbufferObject->release();
-    }
+	}
 }
 
 void ResourceManager::deleteSampler(GLuint sampler)
@@ -235,27 +238,27 @@
 
 Buffer *ResourceManager::getBuffer(unsigned int handle)
 {
-    return mBufferNameSpace.find(handle);
+	return mBufferNameSpace.find(handle);
 }
 
 Shader *ResourceManager::getShader(unsigned int handle)
 {
-    return mShaderNameSpace.find(handle);
+	return mShaderNameSpace.find(handle);
 }
 
 Texture *ResourceManager::getTexture(unsigned int handle)
 {
-    return mTextureNameSpace.find(handle);
+	return mTextureNameSpace.find(handle);
 }
 
 Program *ResourceManager::getProgram(unsigned int handle)
 {
-    return mProgramNameSpace.find(handle);
+	return mProgramNameSpace.find(handle);
 }
 
 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
 {
-    return mRenderbufferNameSpace.find(handle);
+	return mRenderbufferNameSpace.find(handle);
 }
 
 Sampler *ResourceManager::getSampler(unsigned int handle)
@@ -270,29 +273,29 @@
 
 void ResourceManager::checkBufferAllocation(unsigned int buffer)
 {
-    if(buffer != 0 && !getBuffer(buffer))
-    {
-        Buffer *bufferObject = new Buffer(buffer);
+	if(buffer != 0 && !getBuffer(buffer))
+	{
+		Buffer *bufferObject = new Buffer(buffer);
 		bufferObject->addRef();
 
 		mBufferNameSpace.insert(buffer, bufferObject);
-    }
+	}
 }
 
 void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
 {
-    if(!getTexture(texture) && texture != 0)
-    {
-        Texture *textureObject;
+	if(!getTexture(texture) && texture != 0)
+	{
+		Texture *textureObject;
 
-        if(type == TEXTURE_2D)
-        {
-            textureObject = new Texture2D(texture);
-        }
-        else if(type == TEXTURE_CUBE)
-        {
-            textureObject = new TextureCubeMap(texture);
-        }
+		if(type == TEXTURE_2D)
+		{
+			textureObject = new Texture2D(texture);
+		}
+		else if(type == TEXTURE_CUBE)
+		{
+			textureObject = new TextureCubeMap(texture);
+		}
 		else if(type == TEXTURE_EXTERNAL)
 		{
 			textureObject = new TextureExternal(texture);
@@ -306,15 +309,15 @@
 			textureObject = new Texture2DArray(texture);
 		}
 		else
-        {
-            UNREACHABLE(type);
-            return;
-        }
+		{
+			UNREACHABLE(type);
+			return;
+		}
 
 		textureObject->addRef();
 
 		mTextureNameSpace.insert(texture, textureObject);
-    }
+	}
 }
 
 void ResourceManager::checkRenderbufferAllocation(GLuint handle)
diff --git a/src/OpenGL/libGLESv2/ResourceManager.h b/src/OpenGL/libGLESv2/ResourceManager.h
index b12e4ea..efd0e20 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.h
+++ b/src/OpenGL/libGLESv2/ResourceManager.h
@@ -1,101 +1,104 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// ResourceManager.h : Defines the ResourceManager class, which tracks objects

-// shared by multiple GL contexts.

-

-#ifndef LIBGLESV2_RESOURCEMANAGER_H_

-#define LIBGLESV2_RESOURCEMANAGER_H_

-

-#include "common/NameSpace.hpp"

-

-#include <GLES2/gl2.h>

-

-#include <map>

-

-namespace es2

-{

-class Buffer;

-class Shader;

-class Program;

-class Texture;

-class Renderbuffer;

-class Sampler;

-class FenceSync;

-

-enum TextureType

-{

-    TEXTURE_2D,

-	TEXTURE_3D,

-	TEXTURE_2D_ARRAY,

-    TEXTURE_CUBE,

-    TEXTURE_EXTERNAL,

-

-    TEXTURE_TYPE_COUNT,

-    TEXTURE_UNKNOWN

-};

-

-class ResourceManager

-{

-public:

-    ResourceManager();

-    ~ResourceManager();

-

-    void addRef();

-    void release();

-

-    GLuint createBuffer();

-    GLuint createShader(GLenum type);

-    GLuint createProgram();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-    GLuint createSampler();

-    GLuint createFenceSync(GLenum condition, GLbitfield flags);

-

-    void deleteBuffer(GLuint buffer);

-    void deleteShader(GLuint shader);

-    void deleteProgram(GLuint program);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-    void deleteSampler(GLuint sampler);

-    void deleteFenceSync(GLuint fenceSync);

-

-    Buffer *getBuffer(GLuint handle);

-    Shader *getShader(GLuint handle);

-    Program *getProgram(GLuint handle);

-    Texture *getTexture(GLuint handle);

-    Renderbuffer *getRenderbuffer(GLuint handle);

-    Sampler *getSampler(GLuint handle);

-    FenceSync *getFenceSync(GLuint handle);

-

-    void checkBufferAllocation(unsigned int buffer);

-    void checkTextureAllocation(GLuint texture, TextureType type);

-    void checkRenderbufferAllocation(GLuint handle);

-    void checkSamplerAllocation(GLuint sampler);

-

-    bool isSampler(GLuint sampler);

-

-private:

-    std::size_t mRefCount;

-

-    gl::NameSpace<Buffer> mBufferNameSpace;

-    gl::NameSpace<Program> mProgramNameSpace;

-	gl::NameSpace<Shader> mShaderNameSpace;

-	gl::NameSpace<void> mProgramShaderNameSpace;   // Shaders and programs share a namespace

-    gl::NameSpace<Texture> mTextureNameSpace;

-    gl::NameSpace<Renderbuffer> mRenderbufferNameSpace;

-	gl::NameSpace<Sampler> mSamplerNameSpace;

-	gl::NameSpace<FenceSync> mFenceSyncNameSpace;

-};

-

-}

-

-#endif // LIBGLESV2_RESOURCEMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// ResourceManager.h : Defines the ResourceManager class, which tracks objects
+// shared by multiple GL contexts.
+
+#ifndef LIBGLESV2_RESOURCEMANAGER_H_
+#define LIBGLESV2_RESOURCEMANAGER_H_
+
+#include "common/NameSpace.hpp"
+
+#include <GLES2/gl2.h>
+
+#include <map>
+
+namespace es2
+{
+class Buffer;
+class Shader;
+class Program;
+class Texture;
+class Renderbuffer;
+class Sampler;
+class FenceSync;
+
+enum TextureType
+{
+	TEXTURE_2D,
+	TEXTURE_3D,
+	TEXTURE_2D_ARRAY,
+	TEXTURE_CUBE,
+	TEXTURE_EXTERNAL,
+
+	TEXTURE_TYPE_COUNT,
+	TEXTURE_UNKNOWN
+};
+
+class ResourceManager
+{
+public:
+	ResourceManager();
+	~ResourceManager();
+
+	void addRef();
+	void release();
+
+	GLuint createBuffer();
+	GLuint createShader(GLenum type);
+	GLuint createProgram();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+	GLuint createSampler();
+	GLuint createFenceSync(GLenum condition, GLbitfield flags);
+
+	void deleteBuffer(GLuint buffer);
+	void deleteShader(GLuint shader);
+	void deleteProgram(GLuint program);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+	void deleteSampler(GLuint sampler);
+	void deleteFenceSync(GLuint fenceSync);
+
+	Buffer *getBuffer(GLuint handle);
+	Shader *getShader(GLuint handle);
+	Program *getProgram(GLuint handle);
+	Texture *getTexture(GLuint handle);
+	Renderbuffer *getRenderbuffer(GLuint handle);
+	Sampler *getSampler(GLuint handle);
+	FenceSync *getFenceSync(GLuint handle);
+
+	void checkBufferAllocation(unsigned int buffer);
+	void checkTextureAllocation(GLuint texture, TextureType type);
+	void checkRenderbufferAllocation(GLuint handle);
+	void checkSamplerAllocation(GLuint sampler);
+
+	bool isSampler(GLuint sampler);
+
+private:
+	std::size_t mRefCount;
+
+	gl::NameSpace<Buffer> mBufferNameSpace;
+	gl::NameSpace<Program> mProgramNameSpace;
+	gl::NameSpace<Shader> mShaderNameSpace;
+	gl::NameSpace<void> mProgramShaderNameSpace;   // Shaders and programs share a namespace
+	gl::NameSpace<Texture> mTextureNameSpace;
+	gl::NameSpace<Renderbuffer> mRenderbufferNameSpace;
+	gl::NameSpace<Sampler> mSamplerNameSpace;
+	gl::NameSpace<FenceSync> mFenceSyncNameSpace;
+};
+
+}
+
+#endif // LIBGLESV2_RESOURCEMANAGER_H_
diff --git a/src/OpenGL/libGLESv2/Sampler.h b/src/OpenGL/libGLESv2/Sampler.h
index ba8e528..12ed6da 100644
--- a/src/OpenGL/libGLESv2/Sampler.h
+++ b/src/OpenGL/libGLESv2/Sampler.h
@@ -1,79 +1,82 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Sampler.h: Defines the es2::Sampler class

-

-#ifndef LIBGLESV2_SAMPLER_H_

-#define LIBGLESV2_SAMPLER_H_

-

-#include "common/Object.hpp"

-#include "Renderer/Renderer.hpp"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-

-class Sampler : public gl::NamedObject

-{

-public:

-	Sampler(GLuint name) : NamedObject(name)

-	{

-		mMinFilter = GL_NEAREST_MIPMAP_LINEAR;

-		mMagFilter = GL_LINEAR;

-

-		mWrapModeS = GL_REPEAT;

-		mWrapModeT = GL_REPEAT;

-		mWrapModeR = GL_REPEAT;

-

-		mMinLod = -1000.0f;

-		mMaxLod = 1000.0f;

-		mCompareMode = GL_NONE;

-		mCompareFunc = GL_LEQUAL;

-	}

-

-	void setMinFilter(GLenum minFilter) { mMinFilter = minFilter; }

-	void setMagFilter(GLenum magFilter) { mMagFilter = magFilter; }

-	void setWrapS(GLenum wrapS) { mWrapModeS = wrapS; }

-	void setWrapT(GLenum wrapT) { mWrapModeT = wrapT; }

-	void setWrapR(GLenum wrapR) { mWrapModeR = wrapR; }

-	void setMinLod(GLfloat minLod) { mMinLod = minLod; }

-	void setMaxLod(GLfloat maxLod) { mMaxLod = maxLod; }

-	void setComparisonMode(GLenum comparisonMode) { mCompareMode = comparisonMode; }

-	void setComparisonFunc(GLenum comparisonFunc) { mCompareFunc = comparisonFunc; }

-

-	GLenum getMinFilter() const { return mMinFilter; }

-	GLenum getMagFilter() const { return mMagFilter; }

-	GLenum getWrapS() const { return mWrapModeS; }

-	GLenum getWrapT() const { return mWrapModeT; }

-	GLenum getWrapR() const { return mWrapModeR; }

-	GLfloat getMinLod() const { return mMinLod; }

-	GLfloat getMaxLod() const { return mMaxLod; }

-	GLenum getComparisonMode() const { return mCompareMode; }

-	GLenum getComparisonFunc() const { return mCompareFunc; }

-

-private:

-	GLenum mMinFilter;

-	GLenum mMagFilter;

-

-	GLenum mWrapModeS;

-	GLenum mWrapModeT;

-	GLenum mWrapModeR;

-

-	GLfloat mMinLod;

-	GLfloat mMaxLod;

-	GLenum mCompareMode;

-	GLenum mCompareFunc;

-};

-

-}

-

-#endif // LIBGLESV2_SAMPLER_H_

+// 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.
+
+// Sampler.h: Defines the es2::Sampler class
+
+#ifndef LIBGLESV2_SAMPLER_H_
+#define LIBGLESV2_SAMPLER_H_
+
+#include "common/Object.hpp"
+#include "Renderer/Renderer.hpp"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+
+class Sampler : public gl::NamedObject
+{
+public:
+	Sampler(GLuint name) : NamedObject(name)
+	{
+		mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
+		mMagFilter = GL_LINEAR;
+
+		mWrapModeS = GL_REPEAT;
+		mWrapModeT = GL_REPEAT;
+		mWrapModeR = GL_REPEAT;
+
+		mMinLod = -1000.0f;
+		mMaxLod = 1000.0f;
+		mCompareMode = GL_NONE;
+		mCompareFunc = GL_LEQUAL;
+	}
+
+	void setMinFilter(GLenum minFilter) { mMinFilter = minFilter; }
+	void setMagFilter(GLenum magFilter) { mMagFilter = magFilter; }
+	void setWrapS(GLenum wrapS) { mWrapModeS = wrapS; }
+	void setWrapT(GLenum wrapT) { mWrapModeT = wrapT; }
+	void setWrapR(GLenum wrapR) { mWrapModeR = wrapR; }
+	void setMinLod(GLfloat minLod) { mMinLod = minLod; }
+	void setMaxLod(GLfloat maxLod) { mMaxLod = maxLod; }
+	void setComparisonMode(GLenum comparisonMode) { mCompareMode = comparisonMode; }
+	void setComparisonFunc(GLenum comparisonFunc) { mCompareFunc = comparisonFunc; }
+
+	GLenum getMinFilter() const { return mMinFilter; }
+	GLenum getMagFilter() const { return mMagFilter; }
+	GLenum getWrapS() const { return mWrapModeS; }
+	GLenum getWrapT() const { return mWrapModeT; }
+	GLenum getWrapR() const { return mWrapModeR; }
+	GLfloat getMinLod() const { return mMinLod; }
+	GLfloat getMaxLod() const { return mMaxLod; }
+	GLenum getComparisonMode() const { return mCompareMode; }
+	GLenum getComparisonFunc() const { return mCompareFunc; }
+
+private:
+	GLenum mMinFilter;
+	GLenum mMagFilter;
+
+	GLenum mWrapModeS;
+	GLenum mWrapModeT;
+	GLenum mWrapModeR;
+
+	GLfloat mMinLod;
+	GLfloat mMaxLod;
+	GLenum mCompareMode;
+	GLenum mCompareFunc;
+};
+
+}
+
+#endif // LIBGLESV2_SAMPLER_H_
diff --git a/src/OpenGL/libGLESv2/Shader.cpp b/src/OpenGL/libGLESv2/Shader.cpp
index 62cac22..5a4c578 100644
--- a/src/OpenGL/libGLESv2/Shader.cpp
+++ b/src/OpenGL/libGLESv2/Shader.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // Shader.cpp: Implements the Shader class and its  derived classes
 // VertexShader and FragmentShader. Implements GL shader objects and related
@@ -26,79 +29,79 @@
 
 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
 {
-    mSource = NULL;
+	mSource = nullptr;
 
 	clear();
 
-    mRefCount = 0;
-    mDeleteStatus = false;
+	mRefCount = 0;
+	mDeleteStatus = false;
 }
 
 Shader::~Shader()
 {
-    delete[] mSource;
+	delete[] mSource;
 }
 
 GLuint Shader::getName() const
 {
-    return mHandle;
+	return mHandle;
 }
 
 void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
 {
-    delete[] mSource;
-    int totalLength = 0;
+	delete[] mSource;
+	int totalLength = 0;
 
-    for(int i = 0; i < count; i++)
-    {
-        if(length && length[i] >= 0)
-        {
-            totalLength += length[i];
-        }
-        else
-        {
-            totalLength += (int)strlen(string[i]);
-        }
-    }
+	for(int i = 0; i < count; i++)
+	{
+		if(length && length[i] >= 0)
+		{
+			totalLength += length[i];
+		}
+		else
+		{
+			totalLength += (int)strlen(string[i]);
+		}
+	}
 
-    mSource = new char[totalLength + 1];
-    char *code = mSource;
+	mSource = new char[totalLength + 1];
+	char *code = mSource;
 
-    for(int i = 0; i < count; i++)
-    {
-        int stringLength;
+	for(int i = 0; i < count; i++)
+	{
+		int stringLength;
 
-        if(length && length[i] >= 0)
-        {
-            stringLength = length[i];
-        }
-        else
-        {
-            stringLength = (int)strlen(string[i]);
-        }
+		if(length && length[i] >= 0)
+		{
+			stringLength = length[i];
+		}
+		else
+		{
+			stringLength = (int)strlen(string[i]);
+		}
 
-        strncpy(code, string[i], stringLength);
-        code += stringLength;
-    }
+		strncpy(code, string[i], stringLength);
+		code += stringLength;
+	}
 
-    mSource[totalLength] = '\0';
+	mSource[totalLength] = '\0';
 }
 
 size_t Shader::getInfoLogLength() const
 {
-    if(infoLog.empty())
-    {
-        return 0;
-    }
-    else
-    {
-       return infoLog.size() + 1;
-    }
+	if(infoLog.empty())
+	{
+		return 0;
+	}
+	else
+	{
+	   return infoLog.size() + 1;
+	}
 }
 
 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
 {
-    int index = 0;
+	int index = 0;
 
 	if(bufSize > 0)
 	{
@@ -108,30 +111,30 @@
 			memcpy(infoLogOut, infoLog.c_str(), index);
 		}
 
-        infoLogOut[index] = '\0';
-    }
+		infoLogOut[index] = '\0';
+	}
 
-    if(length)
-    {
-        *length = index;
-    }
+	if(length)
+	{
+		*length = index;
+	}
 }
 
 size_t Shader::getSourceLength() const
 {
-    if(!mSource)
-    {
-        return 0;
-    }
-    else
-    {
-       return strlen(mSource) + 1;
-    }
+	if(!mSource)
+	{
+		return 0;
+	}
+	else
+	{
+	   return strlen(mSource) + 1;
+	}
 }
 
 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
 {
-    int index = 0;
+	int index = 0;
 
 	if(bufSize > 0)
 	{
@@ -141,13 +144,13 @@
 			memcpy(source, mSource, index);
 		}
 
-        source[index] = '\0';
-    }
+		source[index] = '\0';
+	}
 
-    if(length)
-    {
-        *length = index;
-    }
+	if(length)
+	{
+		*length = index;
+	}
 }
 
 TranslatorASM *Shader::createCompiler(GLenum shaderType)
@@ -199,12 +202,12 @@
 	createShader();
 	TranslatorASM *compiler = createCompiler(getType());
 
-	// Ensure we don't pass a NULL source to the compiler
-    const char *source = "\0";
+	// Ensure we don't pass a nullptr source to the compiler
+	const char *source = "\0";
 	if(mSource)
-    {
-        source = mSource;
-    }
+	{
+		source = mSource;
+	}
 
 	bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);
 
@@ -234,7 +237,7 @@
 		deleteShader();
 
 		infoLog += compiler->getInfoSink().info.c_str();
-        TRACE("\n%s", infoLog.c_str());
+		TRACE("\n%s", infoLog.c_str());
 	}
 
 	delete compiler;
@@ -242,126 +245,126 @@
 
 bool Shader::isCompiled()
 {
-    return getShader() != 0;
+	return getShader() != 0;
 }
 
 void Shader::addRef()
 {
-    mRefCount++;
+	mRefCount++;
 }
 
 void Shader::release()
 {
-    mRefCount--;
+	mRefCount--;
 
-    if(mRefCount == 0 && mDeleteStatus)
-    {
-        mResourceManager->deleteShader(mHandle);
-    }
+	if(mRefCount == 0 && mDeleteStatus)
+	{
+		mResourceManager->deleteShader(mHandle);
+	}
 }
 
 unsigned int Shader::getRefCount() const
 {
-    return mRefCount;
+	return mRefCount;
 }
 
 bool Shader::isFlaggedForDeletion() const
 {
-    return mDeleteStatus;
+	return mDeleteStatus;
 }
 
 void Shader::flagForDeletion()
 {
-    mDeleteStatus = true;
+	mDeleteStatus = true;
 }
 
 void Shader::releaseCompiler()
 {
-    FreeCompilerGlobals();
+	FreeCompilerGlobals();
 	compilerInitialized = false;
 }
 
 // true if varying x has a higher priority in packing than y
 bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
 {
-    if(x.type == y.type)
-    {
-        return x.size() > y.size();
-    }
+	if(x.type == y.type)
+	{
+		return x.size() > y.size();
+	}
 
-    switch (x.type)
-    {
-    case GL_FLOAT_MAT4: return true;
-    case GL_FLOAT_MAT2:
-        switch(y.type)
-        {
-        case GL_FLOAT_MAT4: return false;
-        case GL_FLOAT_MAT2: return true;
-        case GL_FLOAT_VEC4: return true;
-        case GL_FLOAT_MAT3: return true;
-        case GL_FLOAT_VEC3: return true;
-        case GL_FLOAT_VEC2: return true;
-        case GL_FLOAT:      return true;
-        default: UNREACHABLE(y.type);
-        }
-        break;
-    case GL_FLOAT_VEC4:
-        switch(y.type)
-        {
-        case GL_FLOAT_MAT4: return false;
-        case GL_FLOAT_MAT2: return false;
-        case GL_FLOAT_VEC4: return true;
-        case GL_FLOAT_MAT3: return true;
-        case GL_FLOAT_VEC3: return true;
-        case GL_FLOAT_VEC2: return true;
-        case GL_FLOAT:      return true;
-        default: UNREACHABLE(y.type);
-        }
-        break;
-    case GL_FLOAT_MAT3:
-        switch(y.type)
-        {
-        case GL_FLOAT_MAT4: return false;
-        case GL_FLOAT_MAT2: return false;
-        case GL_FLOAT_VEC4: return false;
-        case GL_FLOAT_MAT3: return true;
-        case GL_FLOAT_VEC3: return true;
-        case GL_FLOAT_VEC2: return true;
-        case GL_FLOAT:      return true;
-        default: UNREACHABLE(y.type);
-        }
-        break;
-    case GL_FLOAT_VEC3:
-        switch(y.type)
-        {
-        case GL_FLOAT_MAT4: return false;
-        case GL_FLOAT_MAT2: return false;
-        case GL_FLOAT_VEC4: return false;
-        case GL_FLOAT_MAT3: return false;
-        case GL_FLOAT_VEC3: return true;
-        case GL_FLOAT_VEC2: return true;
-        case GL_FLOAT:      return true;
-        default: UNREACHABLE(y.type);
-        }
-        break;
-    case GL_FLOAT_VEC2:
-        switch(y.type)
-        {
-        case GL_FLOAT_MAT4: return false;
-        case GL_FLOAT_MAT2: return false;
-        case GL_FLOAT_VEC4: return false;
-        case GL_FLOAT_MAT3: return false;
-        case GL_FLOAT_VEC3: return false;
-        case GL_FLOAT_VEC2: return true;
-        case GL_FLOAT:      return true;
-        default: UNREACHABLE(y.type);
-        }
-        break;
-    case GL_FLOAT: return false;
-    default: UNREACHABLE(x.type);
-    }
+	switch(x.type)
+	{
+	case GL_FLOAT_MAT4: return true;
+	case GL_FLOAT_MAT2:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return true;
+		case GL_FLOAT_VEC4: return true;
+		case GL_FLOAT_MAT3: return true;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_VEC4:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return true;
+		case GL_FLOAT_MAT3: return true;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_MAT3:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return false;
+		case GL_FLOAT_MAT3: return true;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_VEC3:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return false;
+		case GL_FLOAT_MAT3: return false;
+		case GL_FLOAT_VEC3: return true;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT_VEC2:
+		switch(y.type)
+		{
+		case GL_FLOAT_MAT4: return false;
+		case GL_FLOAT_MAT2: return false;
+		case GL_FLOAT_VEC4: return false;
+		case GL_FLOAT_MAT3: return false;
+		case GL_FLOAT_VEC3: return false;
+		case GL_FLOAT_VEC2: return true;
+		case GL_FLOAT:      return true;
+		default: UNREACHABLE(y.type);
+		}
+		break;
+	case GL_FLOAT: return false;
+	default: UNREACHABLE(x.type);
+	}
 
-    return false;
+	return false;
 }
 
 VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
@@ -376,23 +379,23 @@
 
 GLenum VertexShader::getType() const
 {
-    return GL_VERTEX_SHADER;
+	return GL_VERTEX_SHADER;
 }
 
 int VertexShader::getSemanticIndex(const std::string &attributeName)
 {
-    if(!attributeName.empty())
-    {
+	if(!attributeName.empty())
+	{
 		for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
-        {
-            if(attribute->name == attributeName)
-            {
+		{
+			if(attribute->name == attributeName)
+			{
 				return attribute->registerIndex;
-            }
-        }
-    }
+			}
+		}
+	}
 
-    return -1;
+	return -1;
 }
 
 sw::Shader *VertexShader::getShader() const
@@ -429,7 +432,7 @@
 
 GLenum FragmentShader::getType() const
 {
-    return GL_FRAGMENT_SHADER;
+	return GL_FRAGMENT_SHADER;
 }
 
 sw::Shader *FragmentShader::getShader() const
diff --git a/src/OpenGL/libGLESv2/Shader.h b/src/OpenGL/libGLESv2/Shader.h
index 9b0ab79..0c29e4b 100644
--- a/src/OpenGL/libGLESv2/Shader.h
+++ b/src/OpenGL/libGLESv2/Shader.h
@@ -1,131 +1,134 @@
-// 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.

-//

-

-// Shader.h: Defines the abstract Shader class and its concrete derived

-// classes VertexShader and FragmentShader. Implements GL shader objects and

-// related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section

-// 3.8 page 84.

-

-#ifndef LIBGLESV2_SHADER_H_

-#define LIBGLESV2_SHADER_H_

-

-#include "ResourceManager.h"

-

-#include "compiler/TranslatorASM.h"

-

-#include <GLES2/gl2.h>

-

-#include <string>

-#include <list>

-#include <vector>

-

-namespace glsl

-{

-	class OutputASM;

-}

-

-namespace es2

-{

-

-class Shader : public glsl::Shader

-{

-    friend class Program;

-

-public:

-    Shader(ResourceManager *manager, GLuint handle);

-

-    virtual ~Shader();

-

-    virtual GLenum getType() const = 0;

-    GLuint getName() const;

-

-    void deleteSource();

-    void setSource(GLsizei count, const char *const *string, const GLint *length);

-    size_t getInfoLogLength() const;

-    void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);

-    size_t getSourceLength() const;

-    void getSource(GLsizei bufSize, GLsizei *length, char *source);

-

-    void compile();

-    bool isCompiled();

-    

-    void addRef();

-    void release();

-    unsigned int getRefCount() const;

-    bool isFlaggedForDeletion() const;

-    void flagForDeletion();

-

-    static void releaseCompiler();

-

-protected:

-	static bool compilerInitialized;

-	TranslatorASM *createCompiler(GLenum shaderType);

-	void clear();

-

-    static bool compareVarying(const glsl::Varying &x, const glsl::Varying &y);

-

-	char *mSource;

-	std::string infoLog;

-

-private:

-	virtual void createShader() = 0;

-	virtual void deleteShader() = 0;

-

-	const GLuint mHandle;

-    unsigned int mRefCount;     // Number of program objects this shader is attached to

-    bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use

-

-	ResourceManager *mResourceManager;

-};

-

-class VertexShader : public Shader

-{

-    friend class Program;

-

-public:

-    VertexShader(ResourceManager *manager, GLuint handle);

-

-    ~VertexShader();

-

-    virtual GLenum getType() const;

-    int getSemanticIndex(const std::string &attributeName);

-

-	virtual sw::Shader *getShader() const;

-	virtual sw::VertexShader *getVertexShader() const;

-

-private:

-	virtual void createShader();

-	virtual void deleteShader();

-

-	sw::VertexShader *vertexShader;

-};

-

-class FragmentShader : public Shader

-{

-public:

-    FragmentShader(ResourceManager *manager, GLuint handle);

-

-    ~FragmentShader();

-

-    virtual GLenum getType() const;

-

-	virtual sw::Shader *getShader() const;

-	virtual sw::PixelShader *getPixelShader() const;

-

-private:

-	virtual void createShader();

-	virtual void deleteShader();

-

-	sw::PixelShader *pixelShader;

-};

-}

-

-#endif   // LIBGLESV2_SHADER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Shader.h: Defines the abstract Shader class and its concrete derived
+// classes VertexShader and FragmentShader. Implements GL shader objects and
+// related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section
+// 3.8 page 84.
+
+#ifndef LIBGLESV2_SHADER_H_
+#define LIBGLESV2_SHADER_H_
+
+#include "ResourceManager.h"
+
+#include "compiler/TranslatorASM.h"
+
+#include <GLES2/gl2.h>
+
+#include <string>
+#include <list>
+#include <vector>
+
+namespace glsl
+{
+	class OutputASM;
+}
+
+namespace es2
+{
+
+class Shader : public glsl::Shader
+{
+	friend class Program;
+
+public:
+	Shader(ResourceManager *manager, GLuint handle);
+
+	virtual ~Shader();
+
+	virtual GLenum getType() const = 0;
+	GLuint getName() const;
+
+	void deleteSource();
+	void setSource(GLsizei count, const char *const *string, const GLint *length);
+	size_t getInfoLogLength() const;
+	void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
+	size_t getSourceLength() const;
+	void getSource(GLsizei bufSize, GLsizei *length, char *source);
+
+	void compile();
+	bool isCompiled();
+
+	void addRef();
+	void release();
+	unsigned int getRefCount() const;
+	bool isFlaggedForDeletion() const;
+	void flagForDeletion();
+
+	static void releaseCompiler();
+
+protected:
+	static bool compilerInitialized;
+	TranslatorASM *createCompiler(GLenum shaderType);
+	void clear();
+
+	static bool compareVarying(const glsl::Varying &x, const glsl::Varying &y);
+
+	char *mSource;
+	std::string infoLog;
+
+private:
+	virtual void createShader() = 0;
+	virtual void deleteShader() = 0;
+
+	const GLuint mHandle;
+	unsigned int mRefCount;     // Number of program objects this shader is attached to
+	bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use
+
+	ResourceManager *mResourceManager;
+};
+
+class VertexShader : public Shader
+{
+	friend class Program;
+
+public:
+	VertexShader(ResourceManager *manager, GLuint handle);
+
+	~VertexShader();
+
+	virtual GLenum getType() const;
+	int getSemanticIndex(const std::string &attributeName);
+
+	virtual sw::Shader *getShader() const;
+	virtual sw::VertexShader *getVertexShader() const;
+
+private:
+	virtual void createShader();
+	virtual void deleteShader();
+
+	sw::VertexShader *vertexShader;
+};
+
+class FragmentShader : public Shader
+{
+public:
+	FragmentShader(ResourceManager *manager, GLuint handle);
+
+	~FragmentShader();
+
+	virtual GLenum getType() const;
+
+	virtual sw::Shader *getShader() const;
+	virtual sw::PixelShader *getPixelShader() const;
+
+private:
+	virtual void createShader();
+	virtual void deleteShader();
+
+	sw::PixelShader *pixelShader;
+};
+}
+
+#endif   // LIBGLESV2_SHADER_H_
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index c27c113..d1a0cde 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -1,2078 +1,2081 @@
-// 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.

-//

-

-// Texture.cpp: Implements the Texture class and its derived classes

-// Texture2D, TextureCubeMap, Texture3D and Texture2DArray. Implements GL texture objects

-// and related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

-

-#include "Texture.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "Framebuffer.h"

-#include "Device.hpp"

-#include "libEGL/Display.h"

-#include "libEGL/Surface.h"

-#include "common/debug.h"

-

-#include <algorithm>

-

-namespace es2

-{

-

-Texture::Texture(GLuint name) : egl::Texture(name)

-{

-    mMinFilter = GL_NEAREST_MIPMAP_LINEAR;

-    mMagFilter = GL_LINEAR;

-    mWrapS = GL_REPEAT;

-    mWrapT = GL_REPEAT;

-	mWrapR = GL_REPEAT;

-	mMaxAnisotropy = 1.0f;

-	mBaseLevel = 0;

-	mCompareFunc = GL_LEQUAL;

-	mCompareMode = GL_NONE;

-	mImmutableFormat = GL_FALSE;

-	mImmutableLevels = 0;

-	mMaxLevel = 1000;

-	mMaxLOD = 1000;

-	mMinLOD = -1000;

-	mSwizzleR = GL_RED;

-	mSwizzleG = GL_GREEN;

-	mSwizzleB = GL_BLUE;

-	mSwizzleA = GL_ALPHA;

-

-	resource = new sw::Resource(0);

-}

-

-Texture::~Texture()

-{

-	resource->destruct();

-}

-

-sw::Resource *Texture::getResource() const

-{

-	return resource;

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMinFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_NEAREST:

-    case GL_LINEAR:

-        mMinFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMagFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        mMagFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapS(GLenum wrap)

-{

-    switch(wrap)

-    {

-    case GL_REPEAT:

-    case GL_MIRRORED_REPEAT:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_CLAMP_TO_EDGE:

-        mWrapS = wrap;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapT(GLenum wrap)

-{

-	switch(wrap)

-	{

-	case GL_REPEAT:

-	case GL_MIRRORED_REPEAT:

-		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-		{

-			return false;

-		}

-		// Fall through

-	case GL_CLAMP_TO_EDGE:

-		mWrapT = wrap;

-		return true;

-	default:

-		return false;

-	}

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapR(GLenum wrap)

-{

-	switch(wrap)

-	{

-	case GL_REPEAT:

-	case GL_MIRRORED_REPEAT:

-		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-		{

-			return false;

-		}

-		// Fall through

-	case GL_CLAMP_TO_EDGE:

-		mWrapR = wrap;

-		return true;

-	default:

-		return false;

-	}

-}

-

-// Returns true on successful max anisotropy update (valid anisotropy value)

-bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)

-{

-    textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);

-

-    if(textureMaxAnisotropy < 1.0f)

-    {

-        return false;

-    }

-

-	if(mMaxAnisotropy != textureMaxAnisotropy)

-    {

-        mMaxAnisotropy = textureMaxAnisotropy;

-    }

-

-    return true;

-}

-

-bool Texture::setBaseLevel(GLint baseLevel)

-{

-	mBaseLevel = baseLevel;

-	return true;

-}

-

-bool Texture::setCompareFunc(GLenum compareFunc)

-{

-	switch(compareFunc)

-	{

-	case GL_LEQUAL:

-	case GL_GEQUAL:

-	case GL_LESS:

-	case GL_GREATER:

-	case GL_EQUAL:

-	case GL_NOTEQUAL:

-	case GL_ALWAYS:

-	case GL_NEVER:

-		mCompareFunc = compareFunc;

-		return true;

-	default:

-		return false;

-	}

-}

-

-bool Texture::setCompareMode(GLenum compareMode)

-{

-	switch(compareMode)

-	{

-	case GL_COMPARE_REF_TO_TEXTURE:

-	case GL_NONE:

-		mCompareMode = compareMode;

-		return true;

-	default:

-		return false;

-	}

-}

-

-void Texture::makeImmutable(GLsizei levels)

-{

-	mImmutableFormat = GL_TRUE;

-	mImmutableLevels = levels;

-}

-

-bool Texture::setMaxLevel(GLint maxLevel)

-{

-	mMaxLevel = maxLevel;

-	return true;

-}

-

-bool Texture::setMaxLOD(GLfloat maxLOD)

-{

-	mMaxLOD = maxLOD;

-	return true;

-}

-

-bool Texture::setMinLOD(GLfloat minLOD)

-{

-	mMinLOD = minLOD;

-	return true;

-}

-

-bool Texture::setSwizzleR(GLenum swizzleR)

-{

-	switch(swizzleR)

-	{

-	case GL_RED:

-	case GL_GREEN:

-	case GL_BLUE:

-	case GL_ALPHA:

-	case GL_ZERO:

-	case GL_ONE:

-		mSwizzleR = swizzleR;

-		return true;

-	default:

-		return false;

-	}

-}

-

-bool Texture::setSwizzleG(GLenum swizzleG)

-{

-	switch(swizzleG)

-	{

-	case GL_RED:

-	case GL_GREEN:

-	case GL_BLUE:

-	case GL_ALPHA:

-	case GL_ZERO:

-	case GL_ONE:

-		mSwizzleG = swizzleG;

-		return true;

-	default:

-		return false;

-	}

-}

-

-bool Texture::setSwizzleB(GLenum swizzleB)

-{

-	switch(swizzleB)

-	{

-	case GL_RED:

-	case GL_GREEN:

-	case GL_BLUE:

-	case GL_ALPHA:

-	case GL_ZERO:

-	case GL_ONE:

-		mSwizzleB = swizzleB;

-		return true;

-	default:

-		return false;

-	}

-}

-

-bool Texture::setSwizzleA(GLenum swizzleA)

-{

-	switch(swizzleA)

-	{

-	case GL_RED:

-	case GL_GREEN:

-	case GL_BLUE:

-	case GL_ALPHA:

-	case GL_ZERO:

-	case GL_ONE:

-		mSwizzleA = swizzleA;

-		return true;

-	default:

-		return false;

-	}

-}

-

-GLenum Texture::getMinFilter() const

-{

-    return mMinFilter;

-}

-

-GLenum Texture::getMagFilter() const

-{

-    return mMagFilter;

-}

-

-GLenum Texture::getWrapS() const

-{

-    return mWrapS;

-}

-

-GLenum Texture::getWrapT() const

-{

-	return mWrapT;

-}

-

-GLenum Texture::getWrapR() const

-{

-	return mWrapR;

-}

-

-GLfloat Texture::getMaxAnisotropy() const

-{

-    return mMaxAnisotropy;

-}

-

-GLint Texture::getBaseLevel() const

-{

-	return mBaseLevel;

-}

-GLenum Texture::getCompareFunc() const

-{

-	return mCompareFunc;

-}

-GLenum Texture::getCompareMode() const

-{

-	return mCompareMode;

-}

-GLboolean Texture::getImmutableFormat() const

-{

-	return mImmutableFormat;

-}

-GLsizei Texture::getImmutableLevels() const

-{

-	return mImmutableLevels;

-}

-GLint Texture::getMaxLevel() const

-{

-	return mMaxLevel;

-}

-GLfloat Texture::getMaxLOD() const

-{

-	return mMaxLOD;

-}

-GLfloat Texture::getMinLOD() const

-{

-	return mMinLOD;

-}

-GLenum Texture::getSwizzleR() const

-{

-	return mSwizzleR;

-}

-GLenum Texture::getSwizzleG() const

-{

-	return mSwizzleG;

-}

-GLenum Texture::getSwizzleB() const

-{

-	return mSwizzleB;

-}

-GLenum Texture::getSwizzleA() const

-{

-	return mSwizzleA;

-}

-

-GLsizei Texture::getDepth(GLenum target, GLint level) const

-{

-	return 1;

-}

-

-egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)

-{

-    egl::Image *image = getRenderTarget(target, level);   // Increments reference count

-

-    if(image)

-    {

-        image->markShared();

-    }

-

-    return image;

-}

-

-void Texture::setImage(GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image)

-{

-    if(pixels && image)

-    {

-		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;

-		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), depth, format, type, unpackInfo, pixels);

-    }

-}

-

-void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)

-{

-    if(pixels && image)

-    {

-		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;

-		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), depth, imageSize, pixels);

-    }

-}

-

-void Texture::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(IsCompressed(image->getFormat(), egl::getClientVersion()))

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-		image->loadImageData(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels);

-    }

-}

-

-void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-		image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels);

-    }

-}

-

-bool Texture::copy(egl::Image *source, const sw::SliceRect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest)

-{

-    Device *device = getDevice();

-

-    sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), zoffset);

-    bool success = device->stretchRect(source, &sourceRect, dest, &destRect, false);

-

-    if(!success)

-    {

-        return error(GL_OUT_OF_MEMORY, false);

-    }

-

-    return true;

-}

-

-bool Texture::isMipmapFiltered() const

-{

-	switch(mMinFilter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        return false;

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        return true;

-    default: UNREACHABLE(mMinFilter);

-    }

-

-	return false;

-}

-

-Texture2D::Texture2D(GLuint name) : Texture(name)

-{

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		image[i] = nullptr;

-	}

-

-    mSurface = nullptr;

-

-	mColorbufferProxy = nullptr;

-	mProxyRefs = 0;

-}

-

-Texture2D::~Texture2D()

-{

-	resource->lock(sw::DESTRUCT);

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i])

-		{

-			image[i]->unbind(this);

-			image[i] = nullptr;

-		}

-	}

-

-	resource->unlock();

-

-    if(mSurface)

-    {

-        mSurface->setBoundTexture(nullptr);

-        mSurface = nullptr;

-    }

-

-	mColorbufferProxy = nullptr;

-}

-

-// We need to maintain a count of references to renderbuffers acting as

-// proxies for this texture, so that we do not attempt to use a pointer

-// to a renderbuffer proxy which has been deleted.

-void Texture2D::addProxyRef(const Renderbuffer *proxy)

-{

-    mProxyRefs++;

-}

-

-void Texture2D::releaseProxy(const Renderbuffer *proxy)

-{

-    if(mProxyRefs > 0)

-	{

-        mProxyRefs--;

-	}

-

-    if(mProxyRefs == 0)

-	{

-		mColorbufferProxy = nullptr;

-	}

-}

-

-void Texture2D::sweep()

-{

-	int imageCount = 0;

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i] && image[i]->isChildOf(this))

-		{

-			if(!image[i]->hasSingleReference())

-			{

-				return;

-			}

-

-			imageCount++;

-		}

-	}

-

-	if(imageCount == referenceCount)

-	{

-		destroy();

-	}

-}

-

-GLenum Texture2D::getTarget() const

-{

-    return GL_TEXTURE_2D;

-}

-

-GLsizei Texture2D::getWidth(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getWidth() : 0;

-}

-

-GLsizei Texture2D::getHeight(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getHeight() : 0;

-}

-

-GLenum Texture2D::getFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getFormat() : GL_NONE;

-}

-

-GLenum Texture2D::getType(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getType() : GL_NONE;

-}

-

-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;

-}

-

-int Texture2D::getLevelCount() const

-{

-	ASSERT(isSamplerComplete());

-	int levels = 0;

-

-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])

-	{

-		levels++;

-	}

-

-	return levels;

-}

-

-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, format, type);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-	Texture::setImage(format, type, unpackInfo, pixels, image[level]);

-}

-

-void Texture2D::bindTexImage(egl::Surface *surface)

-{

-    GLenum format;

-

-    switch(surface->getInternalFormat())

-    {

-    case sw::FORMAT_A8R8G8B8:

-	case sw::FORMAT_SRGB8_A8:

-		format = GL_BGRA_EXT;

-        break;

-	case sw::FORMAT_A8B8G8R8:

-        format = GL_RGBA;

-        break;

-    case sw::FORMAT_X8B8G8R8:

-	case sw::FORMAT_X8R8G8B8:

-	case sw::FORMAT_SRGB8_X8:

-		format = GL_RGB;

-        break;

-    default:

-        UNIMPLEMENTED();

-        return;

-    }

-

-	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-

-	image[0] = surface->getRenderTarget();

-

-    mSurface = surface;

-    mSurface->setBoundTexture(this);

-}

-

-void Texture2D::releaseTexImage()

-{

-    for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-}

-

-void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

-	image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setCompressedImage(imageSize, pixels, image[level]);

-}

-

-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)

-{

-	Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels, image[level]);

-}

-

-void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

-{

-    Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[level]);

-}

-

-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-    egl::Image *renderTarget = source->getRenderTarget(0);

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

-	image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    if(width != 0 && height != 0)

-    {

-		Renderbuffer* renderbuffer = source->getReadColorbuffer();

-

-		if(!renderbuffer)

-		{

-			ERR("Failed to retrieve the source colorbuffer.");

-			return;

-		}

-

-		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);

-		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

-

-		copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[level]);

-    }

-

-	renderTarget->release();

-}

-

-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	if(!image[level])

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight() || zoffset != 0)

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    egl::Image *renderTarget = source->getRenderTarget(0);

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	Renderbuffer* renderbuffer = source->getReadColorbuffer();

-

-	if(!renderbuffer)

-	{

-		ERR("Failed to retrieve the source colorbuffer.");

-		return;

-	}

-

-	sw::SliceRect sourceRect(x, y, x + width, y + height, 0);

-	sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

-

-	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);

-

-	renderTarget->release();

-}

-

-void Texture2D::setImage(egl::Image *sharedImage)

-{

-	if (sharedImage == image[0])

-	{

-		return;

-	}

-

-	sharedImage->addRef();

-

-    if(image[0])

-    {

-        image[0]->release();

-    }

-

-    image[0] = sharedImage;

-}

-

-// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.

-bool Texture2D::isSamplerComplete() const

-{

-	if(!image[0])

-	{

-		return false;

-	}

-

-    GLsizei width = image[0]->getWidth();

-    GLsizei height = image[0]->getHeight();

-

-    if(width <= 0 || height <= 0)

-    {

-        return false;

-    }

-

-    if(isMipmapFiltered())

-    {

-        if(!isMipmapComplete())

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.

-bool Texture2D::isMipmapComplete() const

-{

-    GLsizei width = image[mBaseLevel]->getWidth();

-    GLsizei height = image[mBaseLevel]->getHeight();

-

-    int q = std::min(log2(std::max(width, height)), mMaxLevel);

-

-    for(int level = mBaseLevel + 1; level <= q; level++)

-    {

-		if(!image[level])

-		{

-			return false;

-		}

-

-        if(image[level]->getFormat() != image[0]->getFormat())

-        {

-            return false;

-        }

-

-        if(image[level]->getType() != image[0]->getType())

-        {

-            return false;

-        }

-

-        if(image[level]->getWidth() != std::max(1, width >> level))

-        {

-            return false;

-        }

-

-        if(image[level]->getHeight() != std::max(1, height >> level))

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-bool Texture2D::isCompressed(GLenum target, GLint level) const

-{

-    return IsCompressed(getFormat(target, level), egl::getClientVersion());

-}

-

-bool Texture2D::isDepth(GLenum target, GLint level) const

-{

-    return IsDepthTexture(getFormat(target, level));

-}

-

-void Texture2D::generateMipmaps()

-{

-	if(!image[0])

-	{

-		return;   // FIXME: error?

-	}

-

-    unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));

-

-	for(unsigned int i = 1; i <= q; i++)

-    {

-		if(image[i])

-		{

-			image[i]->release();

-		}

-

-		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());

-

-		if(!image[i])

-		{

-			return error(GL_OUT_OF_MEMORY);

-		}

-

-		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);

-    }

-}

-

-egl::Image *Texture2D::getImage(unsigned int level)

-{

-	return image[level];

-}

-

-Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level, GLint layer)

-{

-    if(target != GL_TEXTURE_2D)

-    {

-        return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);

-    }

-

-    if(!mColorbufferProxy)

-    {

-        mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this, level));

-    }

-	else

-	{

-		mColorbufferProxy->setLevel(level);

-	}

-

-    return mColorbufferProxy;

-}

-

-egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)

-{

-    ASSERT(target == GL_TEXTURE_2D);

-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-	if(image[level])

-	{

-		image[level]->addRef();

-	}

-

-	return image[level];

-}

-

-bool Texture2D::isShared(GLenum target, unsigned int level) const

-{

-    ASSERT(target == GL_TEXTURE_2D);

-    ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-    if(mSurface)   // Bound to an EGLSurface

-    {

-        return true;

-    }

-

-    if(!image[level])

-    {

-        return false;

-    }

-

-    return image[level]->isShared();

-}

-

-TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)

-{

-	for(int f = 0; f < 6; f++)

-	{

-		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-		{

-			image[f][i] = nullptr;

-		}

-	}

-

-	for(int f = 0; f < 6; f++)

-    {

-        mFaceProxies[f] = nullptr;

-        mFaceProxyRefs[f] = 0;

-	}

-}

-

-TextureCubeMap::~TextureCubeMap()

-{

-	resource->lock(sw::DESTRUCT);

-

-	for(int f = 0; f < 6; f++)

-	{

-		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-		{

-			if(image[f][i])

-			{

-				image[f][i]->unbind(this);

-				image[f][i] = nullptr;

-			}

-		}

-	}

-

-	resource->unlock();

-

-    for(int i = 0; i < 6; i++)

-    {

-        mFaceProxies[i] = nullptr;

-    }

-}

-

-// We need to maintain a count of references to renderbuffers acting as

-// proxies for this texture, so that the texture is not deleted while

-// proxy references still exist. If the reference count drops to zero,

-// we set our proxy pointer null, so that a new attempt at referencing

-// will cause recreation.

-void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)

-{

-    for(int f = 0; f < 6; f++)

-    {

-        if(mFaceProxies[f] == proxy)

-        {

-			mFaceProxyRefs[f]++;

-		}

-	}

-}

-

-void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)

-{

-    for(int f = 0; f < 6; f++)

-    {

-        if(mFaceProxies[f] == proxy)

-        {

-            if(mFaceProxyRefs[f] > 0)

-			{

-				mFaceProxyRefs[f]--;

-			}

-

-            if(mFaceProxyRefs[f] == 0)

-			{

-				mFaceProxies[f] = nullptr;

-			}

-		}

-    }

-}

-

-void TextureCubeMap::sweep()

-{

-	int imageCount = 0;

-

-	for(int f = 0; f < 6; f++)

-	{

-		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-		{

-			if(image[f][i] && image[f][i]->isChildOf(this))

-			{

-				if(!image[f][i]->hasSingleReference())

-				{

-					return;

-				}

-

-				imageCount++;

-			}

-		}

-	}

-

-	if(imageCount == referenceCount)

-	{

-		destroy();

-	}

-}

-

-GLenum TextureCubeMap::getTarget() const

-{

-    return GL_TEXTURE_CUBE_MAP;

-}

-

-GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getWidth() : 0;

-}

-

-GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getHeight() : 0;

-}

-

-GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getFormat() : 0;

-}

-

-GLenum TextureCubeMap::getType(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getType() : 0;

-}

-

-sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const

-{

-	int face = CubeFaceIndex(target);

-    return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;

-}

-

-int TextureCubeMap::getLevelCount() const

-{

-	ASSERT(isSamplerComplete());

-	int levels = 0;

-

-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][levels])

-	{

-		levels++;

-	}

-

-	return levels;

-}

-

-void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)

-{

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->release();

-	}

-

-	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

-	image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

-

-	if(!image[face][level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setCompressedImage(imageSize, pixels, image[face][level]);

-}

-

-void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)

-{

-	Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels, image[CubeFaceIndex(target)][level]);

-}

-

-void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

-{

-    Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);

-}

-

-// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.

-bool TextureCubeMap::isSamplerComplete() const

-{

-	for(int face = 0; face < 6; face++)

-    {

-		if(!image[face][0])

-		{

-			return false;

-		}

-	}

-

-    int size = image[0][0]->getWidth();

-

-    if(size <= 0)

-    {

-        return false;

-    }

-

-    if(!isMipmapFiltered())

-    {

-        if(!isCubeComplete())

-        {

-            return false;

-        }

-    }

-    else

-    {

-        if(!isMipmapCubeComplete())   // Also tests for isCubeComplete()

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.

-bool TextureCubeMap::isCubeComplete() const

-{

-    if(image[0][mBaseLevel]->getWidth() <= 0 || image[0][mBaseLevel]->getHeight() != image[0][mBaseLevel]->getWidth())

-    {

-        return false;

-    }

-

-    for(unsigned int face = 1; face < 6; face++)

-    {

-        if(image[face][mBaseLevel]->getWidth()  != image[0][mBaseLevel]->getWidth() ||

-           image[face][mBaseLevel]->getWidth()  != image[0][mBaseLevel]->getHeight() ||

-           image[face][mBaseLevel]->getFormat() != image[0][mBaseLevel]->getFormat() ||

-           image[face][mBaseLevel]->getType()   != image[0][mBaseLevel]->getType())

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-bool TextureCubeMap::isMipmapCubeComplete() const

-{

-    if(!isCubeComplete())

-    {

-        return false;

-    }

-

-    GLsizei size = image[0][mBaseLevel]->getWidth();

-    int q = std::min(log2(size), mMaxLevel);

-

-    for(int face = 0; face < 6; face++)

-    {

-        for(int level = mBaseLevel + 1; level <= q; level++)

-        {

-			if(!image[face][level])

-			{

-				return false;

-			}

-

-            if(image[face][level]->getFormat() != image[0][mBaseLevel]->getFormat())

-            {

-                return false;

-            }

-

-            if(image[face][level]->getType() != image[0][mBaseLevel]->getType())

-            {

-                return false;

-            }

-

-            if(image[face][level]->getWidth() != std::max(1, size >> level))

-            {

-                return false;

-            }

-        }

-    }

-

-    return true;

-}

-

-bool TextureCubeMap::isCompressed(GLenum target, GLint level) const

-{

-    return IsCompressed(getFormat(target, level), egl::getClientVersion());

-}

-

-bool TextureCubeMap::isDepth(GLenum target, GLint level) const

-{

-    return IsDepthTexture(getFormat(target, level));

-}

-

-void TextureCubeMap::releaseTexImage()

-{

-    UNREACHABLE(0);   // Cube maps cannot have an EGL surface bound as an image

-}

-

-void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)

-{

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->release();

-	}

-

-	image[face][level] = new egl::Image(this, width, height, format, type);

-

-	if(!image[face][level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-	Texture::setImage(format, type, unpackInfo, pixels, image[face][level]);

-}

-

-void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	egl::Image *renderTarget = source->getRenderTarget(0);

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->release();

-	}

-

-	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

-	image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);

-

-	if(!image[face][level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    if(width != 0 && height != 0)

-    {

-		Renderbuffer* renderbuffer = source->getReadColorbuffer();

-

-		if(!renderbuffer)

-		{

-			ERR("Failed to retrieve the source colorbuffer.");

-			return;

-		}

-

-		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);

-		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

-

-		copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[face][level]);

-    }

-

-	renderTarget->release();

-}

-

-egl::Image *TextureCubeMap::getImage(int face, unsigned int level)

-{

-	return image[face][level];

-}

-

-egl::Image *TextureCubeMap::getImage(GLenum face, unsigned int level)

-{

-    return image[CubeFaceIndex(face)][level];

-}

-

-void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	int face = CubeFaceIndex(target);

-

-	if(!image[face][level])

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    GLsizei size = image[face][level]->getWidth();

-

-    if(xoffset + width > size || yoffset + height > size || zoffset != 0)

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    egl::Image *renderTarget = source->getRenderTarget(0);

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	Renderbuffer* renderbuffer = source->getReadColorbuffer();

-

-	if(!renderbuffer)

-	{

-		ERR("Failed to retrieve the source colorbuffer.");

-		return;

-	}

-

-	sw::SliceRect sourceRect(x, y, x + width, y + height, 0);

-	sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

-

-	copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]);

-

-	renderTarget->release();

-}

-

-void TextureCubeMap::generateMipmaps()

-{

-    if(!isCubeComplete())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    unsigned int q = log2(image[0][0]->getWidth());

-

-	for(unsigned int f = 0; f < 6; f++)

-    {

-		for(unsigned int i = 1; i <= q; i++)

-		{

-			if(image[f][i])

-			{

-				image[f][i]->release();

-			}

-

-			image[f][i] = new egl::Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());

-

-			if(!image[f][i])

-			{

-				return error(GL_OUT_OF_MEMORY);

-			}

-

-			getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, true);

-		}

-	}

-}

-

-Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level, GLint layer)

-{

-    if(!IsCubemapTextureTarget(target))

-    {

-        return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);

-    }

-

-    int face = CubeFaceIndex(target);

-

-    if(!mFaceProxies[face])

-    {

-        mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target, level));

-    }

-	else

-	{

-		mFaceProxies[face]->setLevel(level);

-	}

-

-    return mFaceProxies[face];

-}

-

-egl::Image *TextureCubeMap::getRenderTarget(GLenum target, unsigned int level)

-{

-    ASSERT(IsCubemapTextureTarget(target));

-    ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-	int face = CubeFaceIndex(target);

-

-	if(image[face][level])

-	{

-		image[face][level]->addRef();

-	}

-

-	return image[face][level];

-}

-

-bool TextureCubeMap::isShared(GLenum target, unsigned int level) const

-{

-    ASSERT(IsCubemapTextureTarget(target));

-    ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-    int face = CubeFaceIndex(target);

-

-    if(!image[face][level])

-    {

-        return false;

-    }

-

-    return image[face][level]->isShared();

-}

-

-Texture3D::Texture3D(GLuint name) : Texture(name)

-{

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		image[i] = nullptr;

-	}

-

-	mSurface = nullptr;

-

-	mColorbufferProxy = nullptr;

-	mProxyRefs = 0;

-}

-

-Texture3D::~Texture3D()

-{

-	resource->lock(sw::DESTRUCT);

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i])

-		{

-			image[i]->unbind(this);

-			image[i] = nullptr;

-		}

-	}

-

-	resource->unlock();

-

-	if(mSurface)

-	{

-		mSurface->setBoundTexture(nullptr);

-		mSurface = nullptr;

-	}

-

-	mColorbufferProxy = nullptr;

-}

-

-// We need to maintain a count of references to renderbuffers acting as

-// proxies for this texture, so that we do not attempt to use a pointer

-// to a renderbuffer proxy which has been deleted.

-void Texture3D::addProxyRef(const Renderbuffer *proxy)

-{

-	mProxyRefs++;

-}

-

-void Texture3D::releaseProxy(const Renderbuffer *proxy)

-{

-	if(mProxyRefs > 0)

-	{

-		mProxyRefs--;

-	}

-

-	if(mProxyRefs == 0)

-	{

-		mColorbufferProxy = nullptr;

-	}

-}

-

-void Texture3D::sweep()

-{

-	int imageCount = 0;

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i] && image[i]->isChildOf(this))

-		{

-			if(!image[i]->hasSingleReference())

-			{

-				return;

-			}

-

-			imageCount++;

-		}

-	}

-

-	if(imageCount == referenceCount)

-	{

-		destroy();

-	}

-}

-

-GLenum Texture3D::getTarget() const

-{

-	return GL_TEXTURE_3D_OES;

-}

-

-GLsizei Texture3D::getWidth(GLenum target, GLint level) const

-{

-	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getWidth() : 0;

-}

-

-GLsizei Texture3D::getHeight(GLenum target, GLint level) const

-{

-	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getHeight() : 0;

-}

-

-GLsizei Texture3D::getDepth(GLenum target, GLint level) const

-{

-	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getDepth() : 0;

-}

-

-GLenum Texture3D::getFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getFormat() : GL_NONE;

-}

-

-GLenum Texture3D::getType(GLenum target, GLint level) const

-{

-	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getType() : GL_NONE;

-}

-

-sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == getTarget());

-	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;

-}

-

-int Texture3D::getLevelCount() const

-{

-	ASSERT(isSamplerComplete());

-	int levels = 0;

-

-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])

-	{

-		levels++;

-	}

-

-	return levels;

-}

-

-void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, depth, format, type);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-	Texture::setImage(format, type, unpackInfo, pixels, image[level]);

-}

-

-void Texture3D::bindTexImage(egl::Surface *surface)

-{

-	GLenum format;

-

-	switch(surface->getInternalFormat())

-	{

-	case sw::FORMAT_A8R8G8B8:

-		format = GL_RGBA;

-		break;

-	case sw::FORMAT_X8R8G8B8:

-		format = GL_RGB;

-		break;

-	default:

-		UNIMPLEMENTED();

-		return;

-	}

-

-	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-

-	image[0] = surface->getRenderTarget();

-

-	mSurface = surface;

-	mSurface->setBoundTexture(this);

-}

-

-void Texture3D::releaseTexImage()

-{

-	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-}

-

-void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

-	image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-	Texture::setCompressedImage(imageSize, pixels, image[level]);

-}

-

-void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)

-{

-	Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels, image[level]);

-}

-

-void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)

-{

-	Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, image[level]);

-}

-

-void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source)

-{

-	egl::Image *renderTarget = source->getRenderTarget(0);

-

-	if(!renderTarget)

-	{

-		ERR("Failed to retrieve the render target.");

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);

-	image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-	if(width != 0 && height != 0 && depth != 0)

-	{

-		Renderbuffer* renderbuffer = source->getReadColorbuffer();

-

-		if(!renderbuffer)

-		{

-			ERR("Failed to retrieve the source colorbuffer.");

-			return;

-		}

-

-		sw::SliceRect sourceRect(x, y, x + width, y + height, z);

-		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

-		for(GLint sliceZ = 0; sliceZ < depth; ++sliceZ, ++sourceRect.slice)

-		{

-			copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, sliceZ, image[level]);

-		}

-	}

-

-	renderTarget->release();

-}

-

-void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	if(!image[level])

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight() || zoffset >= image[level]->getDepth())

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	egl::Image *renderTarget = source->getRenderTarget(0);

-

-	if(!renderTarget)

-	{

-		ERR("Failed to retrieve the render target.");

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-	Renderbuffer* renderbuffer = source->getReadColorbuffer();

-

-	if(!renderbuffer)

-	{

-		ERR("Failed to retrieve the source colorbuffer.");

-		return;

-	}

-

-	sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};

-	sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());

-

-	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);

-

-	renderTarget->release();

-}

-

-void Texture3D::setImage(egl::Image *sharedImage)

-{

-	sharedImage->addRef();

-

-	if(image[0])

-	{

-		image[0]->release();

-	}

-

-	image[0] = sharedImage;

-}

-

-// Tests for 3D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.

-bool Texture3D::isSamplerComplete() const

-{

-	if(!image[0])

-	{

-		return false;

-	}

-

-	GLsizei width = image[0]->getWidth();

-	GLsizei height = image[0]->getHeight();

-	GLsizei depth = image[0]->getDepth();

-

-	if(width <= 0 || height <= 0 || depth <= 0)

-	{

-		return false;

-	}

-

-	if(isMipmapFiltered())

-	{

-		if(!isMipmapComplete())

-		{

-			return false;

-		}

-	}

-

-	return true;

-}

-

-// Tests for 3D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.

-bool Texture3D::isMipmapComplete() const

-{

-	GLsizei width = image[mBaseLevel]->getWidth();

-	GLsizei height = image[mBaseLevel]->getHeight();

-	GLsizei depth = image[mBaseLevel]->getDepth();

-	bool isTexture2DArray = getTarget() == GL_TEXTURE_2D_ARRAY;

-

-	int q = isTexture2DArray ? std::min(log2(std::max(width, height)), mMaxLevel) :

-	        std::min(log2(std::max(std::max(width, height), depth)), mMaxLevel);

-

-	for(int level = mBaseLevel + 1; level <= q; level++)

-	{

-		if(!image[level])

-		{

-			return false;

-		}

-

-		if(image[level]->getFormat() != image[0]->getFormat())

-		{

-			return false;

-		}

-

-		if(image[level]->getType() != image[0]->getType())

-		{

-			return false;

-		}

-

-		if(image[level]->getWidth() != std::max(1, width >> level))

-		{

-			return false;

-		}

-

-		if(image[level]->getHeight() != std::max(1, height >> level))

-		{

-			return false;

-		}

-

-		int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> level);

-		if(image[level]->getDepth() != levelDepth)

-		{

-			return false;

-		}

-	}

-

-	return true;

-}

-

-bool Texture3D::isCompressed(GLenum target, GLint level) const

-{

-	return IsCompressed(getFormat(target, level), egl::getClientVersion());

-}

-

-bool Texture3D::isDepth(GLenum target, GLint level) const

-{

-	return IsDepthTexture(getFormat(target, level));

-}

-

-void Texture3D::generateMipmaps()

-{

-	if(!image[0])

-	{

-		return;   // FIXME: error?

-	}

-

-	unsigned int q = log2(std::max(std::max(image[0]->getWidth(), image[0]->getHeight()), image[0]->getDepth()));

-

-	for(unsigned int i = 1; i <= q; i++)

-	{

-		if(image[i])

-		{

-			image[i]->release();

-		}

-

-		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), image[0]->getFormat(), image[0]->getType());

-

-		if(!image[i])

-		{

-			return error(GL_OUT_OF_MEMORY);

-		}

-

-		getDevice()->stretchCube(image[i - 1], image[i]);

-	}

-}

-

-egl::Image *Texture3D::getImage(unsigned int level)

-{

-	return image[level];

-}

-

-Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level, GLint layer)

-{

-	if(target != getTarget())

-	{

-		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);

-	}

-

-	if(!mColorbufferProxy)

-	{

-		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level, layer));

-	}

-	else

-	{

-		mColorbufferProxy->setLevel(level);

-		mColorbufferProxy->setLayer(layer);

-	}

-

-	return mColorbufferProxy;

-}

-

-egl::Image *Texture3D::getRenderTarget(GLenum target, unsigned int level)

-{

-	ASSERT(target == getTarget());

-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-	if(image[level])

-	{

-		image[level]->addRef();

-	}

-

-	return image[level];

-}

-

-bool Texture3D::isShared(GLenum target, unsigned int level) const

-{

-	ASSERT(target == getTarget());

-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-	if(mSurface)   // Bound to an EGLSurface

-	{

-		return true;

-	}

-

-	if(!image[level])

-	{

-		return false;

-	}

-

-	return image[level]->isShared();

-}

-

-Texture2DArray::Texture2DArray(GLuint name) : Texture3D(name)

-{

-}

-

-Texture2DArray::~Texture2DArray()

-{

-}

-

-GLenum Texture2DArray::getTarget() const

-{

-	return GL_TEXTURE_2D_ARRAY;

-}

-

-void Texture2DArray::generateMipmaps()

-{

-	int depth = image[0] ? image[0]->getDepth() : 0;

-	if(!depth)

-	{

-		return;   // FIXME: error?

-	}

-

-	unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));

-

-	for(unsigned int i = 1; i <= q; i++)

-	{

-		if(image[i])

-		{

-			image[i]->release();

-		}

-

-		GLsizei w = std::max(image[0]->getWidth() >> i, 1);

-		GLsizei h = std::max(image[0]->getHeight() >> i, 1);

-		image[i] = new egl::Image(this, w, h, depth, image[0]->getFormat(), image[0]->getType());

-

-		if(!image[i])

-		{

-			return error(GL_OUT_OF_MEMORY);

-		}

-

-		GLsizei srcw = image[i - 1]->getWidth();

-		GLsizei srch = image[i - 1]->getHeight();

-		for(int z = 0; z < depth; ++z)

-		{

-			sw::SliceRect srcRect(0, 0, srcw, srch, z);

-			sw::SliceRect dstRect(0, 0, w, h, z);

-			getDevice()->stretchRect(image[i - 1], &srcRect, image[i], &dstRect, true);

-		}

-	}

-}

-

-TextureExternal::TextureExternal(GLuint name) : Texture2D(name)

-{

-    mMinFilter = GL_LINEAR;

-    mMagFilter = GL_LINEAR;

-    mWrapS = GL_CLAMP_TO_EDGE;

-	mWrapT = GL_CLAMP_TO_EDGE;

-	mWrapR = GL_CLAMP_TO_EDGE;

-}

-

-TextureExternal::~TextureExternal()

-{

-}

-

-GLenum TextureExternal::getTarget() const

-{

-    return GL_TEXTURE_EXTERNAL_OES;

-}

-

-}

-

-egl::Image *createBackBuffer(int width, int height, const egl::Config *config)

-{

-	if(config)

-	{

-		return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);

-	}

-

-	return nullptr;

-}

-

-egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-{

-	if(width == 0 || height == 0 || height > sw::OUTLINE_RESOLUTION)

-	{

-		ERR("Invalid parameters: %dx%d", width, height);

-		return nullptr;

-	}

-

-	bool lockable = true;

-

-	switch(format)

-	{

-//	case sw::FORMAT_D15S1:

-	case sw::FORMAT_D24S8:

-	case sw::FORMAT_D24X8:

-//	case sw::FORMAT_D24X4S4:

-	case sw::FORMAT_D24FS8:

-	case sw::FORMAT_D32:

-	case sw::FORMAT_D16:

-		lockable = false;

-		break;

-//	case sw::FORMAT_S8_LOCKABLE:

-//	case sw::FORMAT_D16_LOCKABLE:

-	case sw::FORMAT_D32F_LOCKABLE:

-//	case sw::FORMAT_D32_LOCKABLE:

-	case sw::FORMAT_DF24S8:

-	case sw::FORMAT_DF16S8:

-		lockable = true;

-		break;

-	default:

-		UNREACHABLE(format);

-	}

-

-	egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-	if(!surface)

-	{

-		ERR("Out of memory");

-		return nullptr;

-	}

-

-	return surface;

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Texture.cpp: Implements the Texture class and its derived classes
+// Texture2D, TextureCubeMap, Texture3D and Texture2DArray. Implements GL texture objects
+// and related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#include "Texture.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "Framebuffer.h"
+#include "Device.hpp"
+#include "libEGL/Display.h"
+#include "libEGL/Surface.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+namespace es2
+{
+
+Texture::Texture(GLuint name) : egl::Texture(name)
+{
+	mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
+	mMagFilter = GL_LINEAR;
+	mWrapS = GL_REPEAT;
+	mWrapT = GL_REPEAT;
+	mWrapR = GL_REPEAT;
+	mMaxAnisotropy = 1.0f;
+	mBaseLevel = 0;
+	mCompareFunc = GL_LEQUAL;
+	mCompareMode = GL_NONE;
+	mImmutableFormat = GL_FALSE;
+	mImmutableLevels = 0;
+	mMaxLevel = 1000;
+	mMaxLOD = 1000;
+	mMinLOD = -1000;
+	mSwizzleR = GL_RED;
+	mSwizzleG = GL_GREEN;
+	mSwizzleB = GL_BLUE;
+	mSwizzleA = GL_ALPHA;
+
+	resource = new sw::Resource(0);
+}
+
+Texture::~Texture()
+{
+	resource->destruct();
+}
+
+sw::Resource *Texture::getResource() const
+{
+	return resource;
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMinFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_NEAREST:
+	case GL_LINEAR:
+		mMinFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMagFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		mMagFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapS(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_REPEAT:
+	case GL_MIRRORED_REPEAT:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_CLAMP_TO_EDGE:
+		mWrapS = wrap;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapT(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_REPEAT:
+	case GL_MIRRORED_REPEAT:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_CLAMP_TO_EDGE:
+		mWrapT = wrap;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapR(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_REPEAT:
+	case GL_MIRRORED_REPEAT:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_CLAMP_TO_EDGE:
+		mWrapR = wrap;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful max anisotropy update (valid anisotropy value)
+bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)
+{
+	textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);
+
+	if(textureMaxAnisotropy < 1.0f)
+	{
+		return false;
+	}
+
+	if(mMaxAnisotropy != textureMaxAnisotropy)
+	{
+		mMaxAnisotropy = textureMaxAnisotropy;
+	}
+
+	return true;
+}
+
+bool Texture::setBaseLevel(GLint baseLevel)
+{
+	mBaseLevel = baseLevel;
+	return true;
+}
+
+bool Texture::setCompareFunc(GLenum compareFunc)
+{
+	switch(compareFunc)
+	{
+	case GL_LEQUAL:
+	case GL_GEQUAL:
+	case GL_LESS:
+	case GL_GREATER:
+	case GL_EQUAL:
+	case GL_NOTEQUAL:
+	case GL_ALWAYS:
+	case GL_NEVER:
+		mCompareFunc = compareFunc;
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool Texture::setCompareMode(GLenum compareMode)
+{
+	switch(compareMode)
+	{
+	case GL_COMPARE_REF_TO_TEXTURE:
+	case GL_NONE:
+		mCompareMode = compareMode;
+		return true;
+	default:
+		return false;
+	}
+}
+
+void Texture::makeImmutable(GLsizei levels)
+{
+	mImmutableFormat = GL_TRUE;
+	mImmutableLevels = levels;
+}
+
+bool Texture::setMaxLevel(GLint maxLevel)
+{
+	mMaxLevel = maxLevel;
+	return true;
+}
+
+bool Texture::setMaxLOD(GLfloat maxLOD)
+{
+	mMaxLOD = maxLOD;
+	return true;
+}
+
+bool Texture::setMinLOD(GLfloat minLOD)
+{
+	mMinLOD = minLOD;
+	return true;
+}
+
+bool Texture::setSwizzleR(GLenum swizzleR)
+{
+	switch(swizzleR)
+	{
+	case GL_RED:
+	case GL_GREEN:
+	case GL_BLUE:
+	case GL_ALPHA:
+	case GL_ZERO:
+	case GL_ONE:
+		mSwizzleR = swizzleR;
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool Texture::setSwizzleG(GLenum swizzleG)
+{
+	switch(swizzleG)
+	{
+	case GL_RED:
+	case GL_GREEN:
+	case GL_BLUE:
+	case GL_ALPHA:
+	case GL_ZERO:
+	case GL_ONE:
+		mSwizzleG = swizzleG;
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool Texture::setSwizzleB(GLenum swizzleB)
+{
+	switch(swizzleB)
+	{
+	case GL_RED:
+	case GL_GREEN:
+	case GL_BLUE:
+	case GL_ALPHA:
+	case GL_ZERO:
+	case GL_ONE:
+		mSwizzleB = swizzleB;
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool Texture::setSwizzleA(GLenum swizzleA)
+{
+	switch(swizzleA)
+	{
+	case GL_RED:
+	case GL_GREEN:
+	case GL_BLUE:
+	case GL_ALPHA:
+	case GL_ZERO:
+	case GL_ONE:
+		mSwizzleA = swizzleA;
+		return true;
+	default:
+		return false;
+	}
+}
+
+GLenum Texture::getMinFilter() const
+{
+	return mMinFilter;
+}
+
+GLenum Texture::getMagFilter() const
+{
+	return mMagFilter;
+}
+
+GLenum Texture::getWrapS() const
+{
+	return mWrapS;
+}
+
+GLenum Texture::getWrapT() const
+{
+	return mWrapT;
+}
+
+GLenum Texture::getWrapR() const
+{
+	return mWrapR;
+}
+
+GLfloat Texture::getMaxAnisotropy() const
+{
+	return mMaxAnisotropy;
+}
+
+GLint Texture::getBaseLevel() const
+{
+	return mBaseLevel;
+}
+GLenum Texture::getCompareFunc() const
+{
+	return mCompareFunc;
+}
+GLenum Texture::getCompareMode() const
+{
+	return mCompareMode;
+}
+GLboolean Texture::getImmutableFormat() const
+{
+	return mImmutableFormat;
+}
+GLsizei Texture::getImmutableLevels() const
+{
+	return mImmutableLevels;
+}
+GLint Texture::getMaxLevel() const
+{
+	return mMaxLevel;
+}
+GLfloat Texture::getMaxLOD() const
+{
+	return mMaxLOD;
+}
+GLfloat Texture::getMinLOD() const
+{
+	return mMinLOD;
+}
+GLenum Texture::getSwizzleR() const
+{
+	return mSwizzleR;
+}
+GLenum Texture::getSwizzleG() const
+{
+	return mSwizzleG;
+}
+GLenum Texture::getSwizzleB() const
+{
+	return mSwizzleB;
+}
+GLenum Texture::getSwizzleA() const
+{
+	return mSwizzleA;
+}
+
+GLsizei Texture::getDepth(GLenum target, GLint level) const
+{
+	return 1;
+}
+
+egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)
+{
+	egl::Image *image = getRenderTarget(target, level);   // Increments reference count
+
+	if(image)
+	{
+		image->markShared();
+	}
+
+	return image;
+}
+
+void Texture::setImage(GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image)
+{
+	if(pixels && image)
+	{
+		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
+		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), depth, format, type, unpackInfo, pixels);
+	}
+}
+
+void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)
+{
+	if(pixels && image)
+	{
+		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
+		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), depth, imageSize, pixels);
+	}
+}
+
+void Texture::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(IsCompressed(image->getFormat(), egl::getClientVersion()))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		image->loadImageData(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels);
+	}
+}
+
+void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels);
+	}
+}
+
+bool Texture::copy(egl::Image *source, const sw::SliceRect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest)
+{
+	Device *device = getDevice();
+
+	sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), zoffset);
+	bool success = device->stretchRect(source, &sourceRect, dest, &destRect, false);
+
+	if(!success)
+	{
+		return error(GL_OUT_OF_MEMORY, false);
+	}
+
+	return true;
+}
+
+bool Texture::isMipmapFiltered() const
+{
+	switch(mMinFilter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		return false;
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		return true;
+	default: UNREACHABLE(mMinFilter);
+	}
+
+	return false;
+}
+
+Texture2D::Texture2D(GLuint name) : Texture(name)
+{
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		image[i] = nullptr;
+	}
+
+	mSurface = nullptr;
+
+	mColorbufferProxy = nullptr;
+	mProxyRefs = 0;
+}
+
+Texture2D::~Texture2D()
+{
+	resource->lock(sw::DESTRUCT);
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i])
+		{
+			image[i]->unbind(this);
+			image[i] = nullptr;
+		}
+	}
+
+	resource->unlock();
+
+	if(mSurface)
+	{
+		mSurface->setBoundTexture(nullptr);
+		mSurface = nullptr;
+	}
+
+	mColorbufferProxy = nullptr;
+}
+
+// We need to maintain a count of references to renderbuffers acting as
+// proxies for this texture, so that we do not attempt to use a pointer
+// to a renderbuffer proxy which has been deleted.
+void Texture2D::addProxyRef(const Renderbuffer *proxy)
+{
+	mProxyRefs++;
+}
+
+void Texture2D::releaseProxy(const Renderbuffer *proxy)
+{
+	if(mProxyRefs > 0)
+	{
+		mProxyRefs--;
+	}
+
+	if(mProxyRefs == 0)
+	{
+		mColorbufferProxy = nullptr;
+	}
+}
+
+void Texture2D::sweep()
+{
+	int imageCount = 0;
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i] && image[i]->isChildOf(this))
+		{
+			if(!image[i]->hasSingleReference())
+			{
+				return;
+			}
+
+			imageCount++;
+		}
+	}
+
+	if(imageCount == referenceCount)
+	{
+		destroy();
+	}
+}
+
+GLenum Texture2D::getTarget() const
+{
+	return GL_TEXTURE_2D;
+}
+
+GLsizei Texture2D::getWidth(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getWidth() : 0;
+}
+
+GLsizei Texture2D::getHeight(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getHeight() : 0;
+}
+
+GLenum Texture2D::getFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getFormat() : GL_NONE;
+}
+
+GLenum Texture2D::getType(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getType() : GL_NONE;
+}
+
+sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
+}
+
+int Texture2D::getLevelCount() const
+{
+	ASSERT(isSamplerComplete());
+	int levels = 0;
+
+	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	{
+		levels++;
+	}
+
+	return levels;
+}
+
+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, format, type);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setImage(format, type, unpackInfo, pixels, image[level]);
+}
+
+void Texture2D::bindTexImage(egl::Surface *surface)
+{
+	GLenum format;
+
+	switch(surface->getInternalFormat())
+	{
+	case sw::FORMAT_A8R8G8B8:
+	case sw::FORMAT_SRGB8_A8:
+		format = GL_BGRA_EXT;
+		break;
+	case sw::FORMAT_A8B8G8R8:
+		format = GL_RGBA;
+		break;
+	case sw::FORMAT_X8B8G8R8:
+	case sw::FORMAT_X8R8G8B8:
+	case sw::FORMAT_SRGB8_X8:
+		format = GL_RGB;
+		break;
+	default:
+		UNIMPLEMENTED();
+		return;
+	}
+
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+
+	image[0] = surface->getRenderTarget();
+
+	mSurface = surface;
+	mSurface->setBoundTexture(this);
+}
+
+void Texture2D::releaseTexImage()
+{
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+}
+
+void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+	image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setCompressedImage(imageSize, pixels, image[level]);
+}
+
+void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+{
+	Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels, image[level]);
+}
+
+void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+	Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[level]);
+}
+
+void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	egl::Image *renderTarget = source->getRenderTarget(0);
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+	image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(width != 0 && height != 0)
+	{
+		Renderbuffer* renderbuffer = source->getReadColorbuffer();
+
+		if(!renderbuffer)
+		{
+			ERR("Failed to retrieve the source colorbuffer.");
+			return;
+		}
+
+		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
+		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+
+		copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[level]);
+	}
+
+	renderTarget->release();
+}
+
+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	if(!image[level])
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight() || zoffset != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	egl::Image *renderTarget = source->getRenderTarget(0);
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Renderbuffer* renderbuffer = source->getReadColorbuffer();
+
+	if(!renderbuffer)
+	{
+		ERR("Failed to retrieve the source colorbuffer.");
+		return;
+	}
+
+	sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
+	sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+
+	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
+
+	renderTarget->release();
+}
+
+void Texture2D::setImage(egl::Image *sharedImage)
+{
+	if(sharedImage == image[0])
+	{
+		return;
+	}
+
+	sharedImage->addRef();
+
+	if(image[0])
+	{
+		image[0]->release();
+	}
+
+	image[0] = sharedImage;
+}
+
+// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+bool Texture2D::isSamplerComplete() const
+{
+	if(!image[0])
+	{
+		return false;
+	}
+
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+
+	if(width <= 0 || height <= 0)
+	{
+		return false;
+	}
+
+	if(isMipmapFiltered())
+	{
+		if(!isMipmapComplete())
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool Texture2D::isMipmapComplete() const
+{
+	GLsizei width = image[mBaseLevel]->getWidth();
+	GLsizei height = image[mBaseLevel]->getHeight();
+
+	int q = std::min(log2(std::max(width, height)), mMaxLevel);
+
+	for(int level = mBaseLevel + 1; level <= q; level++)
+	{
+		if(!image[level])
+		{
+			return false;
+		}
+
+		if(image[level]->getFormat() != image[0]->getFormat())
+		{
+			return false;
+		}
+
+		if(image[level]->getType() != image[0]->getType())
+		{
+			return false;
+		}
+
+		if(image[level]->getWidth() != std::max(1, width >> level))
+		{
+			return false;
+		}
+
+		if(image[level]->getHeight() != std::max(1, height >> level))
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool Texture2D::isCompressed(GLenum target, GLint level) const
+{
+	return IsCompressed(getFormat(target, level), egl::getClientVersion());
+}
+
+bool Texture2D::isDepth(GLenum target, GLint level) const
+{
+	return IsDepthTexture(getFormat(target, level));
+}
+
+void Texture2D::generateMipmaps()
+{
+	if(!image[0])
+	{
+		return;   // FIXME: error?
+	}
+
+	unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+
+	for(unsigned int i = 1; i <= q; i++)
+	{
+		if(image[i])
+		{
+			image[i]->release();
+		}
+
+		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
+
+		if(!image[i])
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+
+		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);
+	}
+}
+
+egl::Image *Texture2D::getImage(unsigned int level)
+{
+	return image[level];
+}
+
+Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level, GLint layer)
+{
+	if(target != GL_TEXTURE_2D)
+	{
+		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
+	}
+
+	if(!mColorbufferProxy)
+	{
+		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this, level));
+	}
+	else
+	{
+		mColorbufferProxy->setLevel(level);
+	}
+
+	return mColorbufferProxy;
+}
+
+egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(image[level])
+	{
+		image[level]->addRef();
+	}
+
+	return image[level];
+}
+
+bool Texture2D::isShared(GLenum target, unsigned int level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(mSurface)   // Bound to an EGLSurface
+	{
+		return true;
+	}
+
+	if(!image[level])
+	{
+		return false;
+	}
+
+	return image[level]->isShared();
+}
+
+TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
+{
+	for(int f = 0; f < 6; f++)
+	{
+		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+		{
+			image[f][i] = nullptr;
+		}
+	}
+
+	for(int f = 0; f < 6; f++)
+	{
+		mFaceProxies[f] = nullptr;
+		mFaceProxyRefs[f] = 0;
+	}
+}
+
+TextureCubeMap::~TextureCubeMap()
+{
+	resource->lock(sw::DESTRUCT);
+
+	for(int f = 0; f < 6; f++)
+	{
+		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+		{
+			if(image[f][i])
+			{
+				image[f][i]->unbind(this);
+				image[f][i] = nullptr;
+			}
+		}
+	}
+
+	resource->unlock();
+
+	for(int i = 0; i < 6; i++)
+	{
+		mFaceProxies[i] = nullptr;
+	}
+}
+
+// We need to maintain a count of references to renderbuffers acting as
+// proxies for this texture, so that the texture is not deleted while
+// proxy references still exist. If the reference count drops to zero,
+// we set our proxy pointer null, so that a new attempt at referencing
+// will cause recreation.
+void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)
+{
+	for(int f = 0; f < 6; f++)
+	{
+		if(mFaceProxies[f] == proxy)
+		{
+			mFaceProxyRefs[f]++;
+		}
+	}
+}
+
+void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)
+{
+	for(int f = 0; f < 6; f++)
+	{
+		if(mFaceProxies[f] == proxy)
+		{
+			if(mFaceProxyRefs[f] > 0)
+			{
+				mFaceProxyRefs[f]--;
+			}
+
+			if(mFaceProxyRefs[f] == 0)
+			{
+				mFaceProxies[f] = nullptr;
+			}
+		}
+	}
+}
+
+void TextureCubeMap::sweep()
+{
+	int imageCount = 0;
+
+	for(int f = 0; f < 6; f++)
+	{
+		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+		{
+			if(image[f][i] && image[f][i]->isChildOf(this))
+			{
+				if(!image[f][i]->hasSingleReference())
+				{
+					return;
+				}
+
+				imageCount++;
+			}
+		}
+	}
+
+	if(imageCount == referenceCount)
+	{
+		destroy();
+	}
+}
+
+GLenum TextureCubeMap::getTarget() const
+{
+	return GL_TEXTURE_CUBE_MAP;
+}
+
+GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getWidth() : 0;
+}
+
+GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getHeight() : 0;
+}
+
+GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getFormat() : 0;
+}
+
+GLenum TextureCubeMap::getType(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getType() : 0;
+}
+
+sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
+{
+	int face = CubeFaceIndex(target);
+	return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;
+}
+
+int TextureCubeMap::getLevelCount() const
+{
+	ASSERT(isSamplerComplete());
+	int levels = 0;
+
+	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][levels])
+	{
+		levels++;
+	}
+
+	return levels;
+}
+
+void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->release();
+	}
+
+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+	image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+
+	if(!image[face][level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setCompressedImage(imageSize, pixels, image[face][level]);
+}
+
+void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+{
+	Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels, image[CubeFaceIndex(target)][level]);
+}
+
+void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+	Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);
+}
+
+// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.
+bool TextureCubeMap::isSamplerComplete() const
+{
+	for(int face = 0; face < 6; face++)
+	{
+		if(!image[face][0])
+		{
+			return false;
+		}
+	}
+
+	int size = image[0][0]->getWidth();
+
+	if(size <= 0)
+	{
+		return false;
+	}
+
+	if(!isMipmapFiltered())
+	{
+		if(!isCubeComplete())
+		{
+			return false;
+		}
+	}
+	else
+	{
+		if(!isMipmapCubeComplete())   // Also tests for isCubeComplete()
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool TextureCubeMap::isCubeComplete() const
+{
+	if(image[0][mBaseLevel]->getWidth() <= 0 || image[0][mBaseLevel]->getHeight() != image[0][mBaseLevel]->getWidth())
+	{
+		return false;
+	}
+
+	for(unsigned int face = 1; face < 6; face++)
+	{
+		if(image[face][mBaseLevel]->getWidth()  != image[0][mBaseLevel]->getWidth() ||
+		   image[face][mBaseLevel]->getWidth()  != image[0][mBaseLevel]->getHeight() ||
+		   image[face][mBaseLevel]->getFormat() != image[0][mBaseLevel]->getFormat() ||
+		   image[face][mBaseLevel]->getType()   != image[0][mBaseLevel]->getType())
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool TextureCubeMap::isMipmapCubeComplete() const
+{
+	if(!isCubeComplete())
+	{
+		return false;
+	}
+
+	GLsizei size = image[0][mBaseLevel]->getWidth();
+	int q = std::min(log2(size), mMaxLevel);
+
+	for(int face = 0; face < 6; face++)
+	{
+		for(int level = mBaseLevel + 1; level <= q; level++)
+		{
+			if(!image[face][level])
+			{
+				return false;
+			}
+
+			if(image[face][level]->getFormat() != image[0][mBaseLevel]->getFormat())
+			{
+				return false;
+			}
+
+			if(image[face][level]->getType() != image[0][mBaseLevel]->getType())
+			{
+				return false;
+			}
+
+			if(image[face][level]->getWidth() != std::max(1, size >> level))
+			{
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
+{
+	return IsCompressed(getFormat(target, level), egl::getClientVersion());
+}
+
+bool TextureCubeMap::isDepth(GLenum target, GLint level) const
+{
+	return IsDepthTexture(getFormat(target, level));
+}
+
+void TextureCubeMap::releaseTexImage()
+{
+	UNREACHABLE(0);   // Cube maps cannot have an EGL surface bound as an image
+}
+
+void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+{
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->release();
+	}
+
+	image[face][level] = new egl::Image(this, width, height, format, type);
+
+	if(!image[face][level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setImage(format, type, unpackInfo, pixels, image[face][level]);
+}
+
+void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	egl::Image *renderTarget = source->getRenderTarget(0);
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->release();
+	}
+
+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+	image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+
+	if(!image[face][level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(width != 0 && height != 0)
+	{
+		Renderbuffer* renderbuffer = source->getReadColorbuffer();
+
+		if(!renderbuffer)
+		{
+			ERR("Failed to retrieve the source colorbuffer.");
+			return;
+		}
+
+		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
+		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+
+		copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[face][level]);
+	}
+
+	renderTarget->release();
+}
+
+egl::Image *TextureCubeMap::getImage(int face, unsigned int level)
+{
+	return image[face][level];
+}
+
+egl::Image *TextureCubeMap::getImage(GLenum face, unsigned int level)
+{
+	return image[CubeFaceIndex(face)][level];
+}
+
+void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	int face = CubeFaceIndex(target);
+
+	if(!image[face][level])
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	GLsizei size = image[face][level]->getWidth();
+
+	if(xoffset + width > size || yoffset + height > size || zoffset != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	egl::Image *renderTarget = source->getRenderTarget(0);
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Renderbuffer* renderbuffer = source->getReadColorbuffer();
+
+	if(!renderbuffer)
+	{
+		ERR("Failed to retrieve the source colorbuffer.");
+		return;
+	}
+
+	sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
+	sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+
+	copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]);
+
+	renderTarget->release();
+}
+
+void TextureCubeMap::generateMipmaps()
+{
+	if(!isCubeComplete())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	unsigned int q = log2(image[0][0]->getWidth());
+
+	for(unsigned int f = 0; f < 6; f++)
+	{
+		for(unsigned int i = 1; i <= q; i++)
+		{
+			if(image[f][i])
+			{
+				image[f][i]->release();
+			}
+
+			image[f][i] = new egl::Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());
+
+			if(!image[f][i])
+			{
+				return error(GL_OUT_OF_MEMORY);
+			}
+
+			getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, true);
+		}
+	}
+}
+
+Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level, GLint layer)
+{
+	if(!IsCubemapTextureTarget(target))
+	{
+		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
+	}
+
+	int face = CubeFaceIndex(target);
+
+	if(!mFaceProxies[face])
+	{
+		mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target, level));
+	}
+	else
+	{
+		mFaceProxies[face]->setLevel(level);
+	}
+
+	return mFaceProxies[face];
+}
+
+egl::Image *TextureCubeMap::getRenderTarget(GLenum target, unsigned int level)
+{
+	ASSERT(IsCubemapTextureTarget(target));
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	int face = CubeFaceIndex(target);
+
+	if(image[face][level])
+	{
+		image[face][level]->addRef();
+	}
+
+	return image[face][level];
+}
+
+bool TextureCubeMap::isShared(GLenum target, unsigned int level) const
+{
+	ASSERT(IsCubemapTextureTarget(target));
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	int face = CubeFaceIndex(target);
+
+	if(!image[face][level])
+	{
+		return false;
+	}
+
+	return image[face][level]->isShared();
+}
+
+Texture3D::Texture3D(GLuint name) : Texture(name)
+{
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		image[i] = nullptr;
+	}
+
+	mSurface = nullptr;
+
+	mColorbufferProxy = nullptr;
+	mProxyRefs = 0;
+}
+
+Texture3D::~Texture3D()
+{
+	resource->lock(sw::DESTRUCT);
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i])
+		{
+			image[i]->unbind(this);
+			image[i] = nullptr;
+		}
+	}
+
+	resource->unlock();
+
+	if(mSurface)
+	{
+		mSurface->setBoundTexture(nullptr);
+		mSurface = nullptr;
+	}
+
+	mColorbufferProxy = nullptr;
+}
+
+// We need to maintain a count of references to renderbuffers acting as
+// proxies for this texture, so that we do not attempt to use a pointer
+// to a renderbuffer proxy which has been deleted.
+void Texture3D::addProxyRef(const Renderbuffer *proxy)
+{
+	mProxyRefs++;
+}
+
+void Texture3D::releaseProxy(const Renderbuffer *proxy)
+{
+	if(mProxyRefs > 0)
+	{
+		mProxyRefs--;
+	}
+
+	if(mProxyRefs == 0)
+	{
+		mColorbufferProxy = nullptr;
+	}
+}
+
+void Texture3D::sweep()
+{
+	int imageCount = 0;
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i] && image[i]->isChildOf(this))
+		{
+			if(!image[i]->hasSingleReference())
+			{
+				return;
+			}
+
+			imageCount++;
+		}
+	}
+
+	if(imageCount == referenceCount)
+	{
+		destroy();
+	}
+}
+
+GLenum Texture3D::getTarget() const
+{
+	return GL_TEXTURE_3D_OES;
+}
+
+GLsizei Texture3D::getWidth(GLenum target, GLint level) const
+{
+	ASSERT(target == getTarget());
+	return image[level] ? image[level]->getWidth() : 0;
+}
+
+GLsizei Texture3D::getHeight(GLenum target, GLint level) const
+{
+	ASSERT(target == getTarget());
+	return image[level] ? image[level]->getHeight() : 0;
+}
+
+GLsizei Texture3D::getDepth(GLenum target, GLint level) const
+{
+	ASSERT(target == getTarget());
+	return image[level] ? image[level]->getDepth() : 0;
+}
+
+GLenum Texture3D::getFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == getTarget());
+	return image[level] ? image[level]->getFormat() : GL_NONE;
+}
+
+GLenum Texture3D::getType(GLenum target, GLint level) const
+{
+	ASSERT(target == getTarget());
+	return image[level] ? image[level]->getType() : GL_NONE;
+}
+
+sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == getTarget());
+	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
+}
+
+int Texture3D::getLevelCount() const
+{
+	ASSERT(isSamplerComplete());
+	int levels = 0;
+
+	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	{
+		levels++;
+	}
+
+	return levels;
+}
+
+void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, depth, format, type);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setImage(format, type, unpackInfo, pixels, image[level]);
+}
+
+void Texture3D::bindTexImage(egl::Surface *surface)
+{
+	GLenum format;
+
+	switch(surface->getInternalFormat())
+	{
+	case sw::FORMAT_A8R8G8B8:
+		format = GL_RGBA;
+		break;
+	case sw::FORMAT_X8R8G8B8:
+		format = GL_RGB;
+		break;
+	default:
+		UNIMPLEMENTED();
+		return;
+	}
+
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+
+	image[0] = surface->getRenderTarget();
+
+	mSurface = surface;
+	mSurface->setBoundTexture(this);
+}
+
+void Texture3D::releaseTexImage()
+{
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+}
+
+void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+	image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setCompressedImage(imageSize, pixels, image[level]);
+}
+
+void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+{
+	Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels, image[level]);
+}
+
+void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+{
+	Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, image[level]);
+}
+
+void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source)
+{
+	egl::Image *renderTarget = source->getRenderTarget(0);
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+	image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(width != 0 && height != 0 && depth != 0)
+	{
+		Renderbuffer* renderbuffer = source->getReadColorbuffer();
+
+		if(!renderbuffer)
+		{
+			ERR("Failed to retrieve the source colorbuffer.");
+			return;
+		}
+
+		sw::SliceRect sourceRect(x, y, x + width, y + height, z);
+		sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+		for(GLint sliceZ = 0; sliceZ < depth; ++sliceZ, ++sourceRect.slice)
+		{
+			copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, sliceZ, image[level]);
+		}
+	}
+
+	renderTarget->release();
+}
+
+void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	if(!image[level])
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight() || zoffset >= image[level]->getDepth())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	egl::Image *renderTarget = source->getRenderTarget(0);
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Renderbuffer* renderbuffer = source->getReadColorbuffer();
+
+	if(!renderbuffer)
+	{
+		ERR("Failed to retrieve the source colorbuffer.");
+		return;
+	}
+
+	sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
+	sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+
+	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
+
+	renderTarget->release();
+}
+
+void Texture3D::setImage(egl::Image *sharedImage)
+{
+	sharedImage->addRef();
+
+	if(image[0])
+	{
+		image[0]->release();
+	}
+
+	image[0] = sharedImage;
+}
+
+// Tests for 3D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+bool Texture3D::isSamplerComplete() const
+{
+	if(!image[0])
+	{
+		return false;
+	}
+
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+	GLsizei depth = image[0]->getDepth();
+
+	if(width <= 0 || height <= 0 || depth <= 0)
+	{
+		return false;
+	}
+
+	if(isMipmapFiltered())
+	{
+		if(!isMipmapComplete())
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// Tests for 3D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool Texture3D::isMipmapComplete() const
+{
+	GLsizei width = image[mBaseLevel]->getWidth();
+	GLsizei height = image[mBaseLevel]->getHeight();
+	GLsizei depth = image[mBaseLevel]->getDepth();
+	bool isTexture2DArray = getTarget() == GL_TEXTURE_2D_ARRAY;
+
+	int q = isTexture2DArray ? std::min(log2(std::max(width, height)), mMaxLevel) :
+	        std::min(log2(std::max(std::max(width, height), depth)), mMaxLevel);
+
+	for(int level = mBaseLevel + 1; level <= q; level++)
+	{
+		if(!image[level])
+		{
+			return false;
+		}
+
+		if(image[level]->getFormat() != image[0]->getFormat())
+		{
+			return false;
+		}
+
+		if(image[level]->getType() != image[0]->getType())
+		{
+			return false;
+		}
+
+		if(image[level]->getWidth() != std::max(1, width >> level))
+		{
+			return false;
+		}
+
+		if(image[level]->getHeight() != std::max(1, height >> level))
+		{
+			return false;
+		}
+
+		int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> level);
+		if(image[level]->getDepth() != levelDepth)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool Texture3D::isCompressed(GLenum target, GLint level) const
+{
+	return IsCompressed(getFormat(target, level), egl::getClientVersion());
+}
+
+bool Texture3D::isDepth(GLenum target, GLint level) const
+{
+	return IsDepthTexture(getFormat(target, level));
+}
+
+void Texture3D::generateMipmaps()
+{
+	if(!image[0])
+	{
+		return;   // FIXME: error?
+	}
+
+	unsigned int q = log2(std::max(std::max(image[0]->getWidth(), image[0]->getHeight()), image[0]->getDepth()));
+
+	for(unsigned int i = 1; i <= q; i++)
+	{
+		if(image[i])
+		{
+			image[i]->release();
+		}
+
+		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), image[0]->getFormat(), image[0]->getType());
+
+		if(!image[i])
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+
+		getDevice()->stretchCube(image[i - 1], image[i]);
+	}
+}
+
+egl::Image *Texture3D::getImage(unsigned int level)
+{
+	return image[level];
+}
+
+Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level, GLint layer)
+{
+	if(target != getTarget())
+	{
+		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
+	}
+
+	if(!mColorbufferProxy)
+	{
+		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level, layer));
+	}
+	else
+	{
+		mColorbufferProxy->setLevel(level);
+		mColorbufferProxy->setLayer(layer);
+	}
+
+	return mColorbufferProxy;
+}
+
+egl::Image *Texture3D::getRenderTarget(GLenum target, unsigned int level)
+{
+	ASSERT(target == getTarget());
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(image[level])
+	{
+		image[level]->addRef();
+	}
+
+	return image[level];
+}
+
+bool Texture3D::isShared(GLenum target, unsigned int level) const
+{
+	ASSERT(target == getTarget());
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(mSurface)   // Bound to an EGLSurface
+	{
+		return true;
+	}
+
+	if(!image[level])
+	{
+		return false;
+	}
+
+	return image[level]->isShared();
+}
+
+Texture2DArray::Texture2DArray(GLuint name) : Texture3D(name)
+{
+}
+
+Texture2DArray::~Texture2DArray()
+{
+}
+
+GLenum Texture2DArray::getTarget() const
+{
+	return GL_TEXTURE_2D_ARRAY;
+}
+
+void Texture2DArray::generateMipmaps()
+{
+	int depth = image[0] ? image[0]->getDepth() : 0;
+	if(!depth)
+	{
+		return;   // FIXME: error?
+	}
+
+	unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+
+	for(unsigned int i = 1; i <= q; i++)
+	{
+		if(image[i])
+		{
+			image[i]->release();
+		}
+
+		GLsizei w = std::max(image[0]->getWidth() >> i, 1);
+		GLsizei h = std::max(image[0]->getHeight() >> i, 1);
+		image[i] = new egl::Image(this, w, h, depth, image[0]->getFormat(), image[0]->getType());
+
+		if(!image[i])
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+
+		GLsizei srcw = image[i - 1]->getWidth();
+		GLsizei srch = image[i - 1]->getHeight();
+		for(int z = 0; z < depth; ++z)
+		{
+			sw::SliceRect srcRect(0, 0, srcw, srch, z);
+			sw::SliceRect dstRect(0, 0, w, h, z);
+			getDevice()->stretchRect(image[i - 1], &srcRect, image[i], &dstRect, true);
+		}
+	}
+}
+
+TextureExternal::TextureExternal(GLuint name) : Texture2D(name)
+{
+	mMinFilter = GL_LINEAR;
+	mMagFilter = GL_LINEAR;
+	mWrapS = GL_CLAMP_TO_EDGE;
+	mWrapT = GL_CLAMP_TO_EDGE;
+	mWrapR = GL_CLAMP_TO_EDGE;
+}
+
+TextureExternal::~TextureExternal()
+{
+}
+
+GLenum TextureExternal::getTarget() const
+{
+	return GL_TEXTURE_EXTERNAL_OES;
+}
+
+}
+
+egl::Image *createBackBuffer(int width, int height, const egl::Config *config)
+{
+	if(config)
+	{
+		return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);
+	}
+
+	return nullptr;
+}
+
+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+{
+	if(width == 0 || height == 0 || height > sw::OUTLINE_RESOLUTION)
+	{
+		ERR("Invalid parameters: %dx%d", width, height);
+		return nullptr;
+	}
+
+	bool lockable = true;
+
+	switch(format)
+	{
+//	case sw::FORMAT_D15S1:
+	case sw::FORMAT_D24S8:
+	case sw::FORMAT_D24X8:
+//	case sw::FORMAT_D24X4S4:
+	case sw::FORMAT_D24FS8:
+	case sw::FORMAT_D32:
+	case sw::FORMAT_D16:
+		lockable = false;
+		break;
+//	case sw::FORMAT_S8_LOCKABLE:
+//	case sw::FORMAT_D16_LOCKABLE:
+	case sw::FORMAT_D32F_LOCKABLE:
+//	case sw::FORMAT_D32_LOCKABLE:
+	case sw::FORMAT_DF24S8:
+	case sw::FORMAT_DF16S8:
+		lockable = true;
+		break;
+	default:
+		UNREACHABLE(format);
+	}
+
+	egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+	if(!surface)
+	{
+		ERR("Out of memory");
+		return nullptr;
+	}
+
+	return surface;
+}
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index 8c7c5c8..74452b0 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -1,353 +1,356 @@
-// 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.

-//

-

-// Texture.h: Defines the abstract Texture class and its concrete derived

-// classes Texture2D and TextureCubeMap. Implements GL texture objects and

-// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

-

-#ifndef LIBGLESV2_TEXTURE_H_

-#define LIBGLESV2_TEXTURE_H_

-

-#include "Renderbuffer.h"

-#include "common/Object.hpp"

-#include "utilities.h"

-#include "libEGL/Texture.hpp"

-#include "common/debug.h"

-

-#include <GLES2/gl2.h>

-

-#include <vector>

-

-namespace egl

-{

-class Surface;

-class Config;

-}

-

-namespace es2

-{

-class Framebuffer;

-

-enum

-{

-	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,

-    IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,

-};

-

-class Texture : public egl::Texture

-{

-public:

-    explicit Texture(GLuint name);

-

-	virtual sw::Resource *getResource() const;

-

-	virtual void addProxyRef(const Renderbuffer *proxy) = 0;

-    virtual void releaseProxy(const Renderbuffer *proxy) = 0;

-

-    virtual GLenum getTarget() const = 0;

-

-    bool setMinFilter(GLenum filter);

-    bool setMagFilter(GLenum filter);

-    bool setWrapS(GLenum wrap);

-	bool setWrapT(GLenum wrap);

-	bool setWrapR(GLenum wrap);

-	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);

-	bool setBaseLevel(GLint baseLevel);

-	bool setCompareFunc(GLenum compareFunc);

-	bool setCompareMode(GLenum compareMode);

-	void makeImmutable(GLsizei levels);

-	bool setMaxLevel(GLint maxLevel);

-	bool setMaxLOD(GLfloat maxLOD);

-	bool setMinLOD(GLfloat minLOD);

-	bool setSwizzleR(GLenum swizzleR);

-	bool setSwizzleG(GLenum swizzleG);

-	bool setSwizzleB(GLenum swizzleB);

-	bool setSwizzleA(GLenum swizzleA);

-

-    GLenum getMinFilter() const;

-    GLenum getMagFilter() const;

-    GLenum getWrapS() const;

-	GLenum getWrapT() const;

-	GLenum getWrapR() const;

-	GLfloat getMaxAnisotropy() const;

-	GLint getBaseLevel() const;

-	GLenum getCompareFunc() const;

-	GLenum getCompareMode() const;

-	GLboolean getImmutableFormat() const;

-	GLsizei getImmutableLevels() const;

-	GLint getMaxLevel() const;

-	GLfloat getMaxLOD() const;

-	GLfloat getMinLOD() const;

-	GLenum getSwizzleR() const;

-	GLenum getSwizzleG() const;

-	GLenum getSwizzleB() const;

-	GLenum getSwizzleA() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const = 0;

-	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;

-	virtual GLsizei getDepth(GLenum target, GLint level) const;

-    virtual GLenum getFormat(GLenum target, GLint level) const = 0;

-    virtual GLenum getType(GLenum target, GLint level) const = 0;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;

-	virtual int getLevelCount() const = 0;

-

-    virtual bool isSamplerComplete() const = 0;

-    virtual bool isCompressed(GLenum target, GLint level) const = 0;

-	virtual bool isDepth(GLenum target, GLint level) const = 0;

-

-    virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) = 0;

-    virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;

-    virtual egl::Image *createSharedImage(GLenum target, unsigned int level);

-    virtual bool isShared(GLenum target, unsigned int level) const = 0;

-

-    virtual void generateMipmaps() = 0;

-	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

-

-protected:

-	virtual ~Texture();

-

-    void setImage(GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);

-    void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);

-    void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);

-    void subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);

-

-	bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest);

-

-	bool isMipmapFiltered() const;

-

-    GLenum mMinFilter;

-    GLenum mMagFilter;

-    GLenum mWrapS;

-    GLenum mWrapT;

-    GLenum mWrapR;

-	GLfloat mMaxAnisotropy;

-	GLint mBaseLevel;

-	GLenum mCompareFunc;

-	GLenum mCompareMode;

-	GLboolean mImmutableFormat;

-	GLsizei mImmutableLevels;

-	GLint mMaxLevel;

-	GLfloat mMaxLOD;

-	GLfloat mMinLOD;

-	GLenum mSwizzleR;

-	GLenum mSwizzleG;

-	GLenum mSwizzleB;

-	GLenum mSwizzleA;

-

-	sw::Resource *resource;

-};

-

-class Texture2D : public Texture

-{

-public:

-    explicit Texture2D(GLuint name);

-

-	void addProxyRef(const Renderbuffer *proxy) override;

-    void releaseProxy(const Renderbuffer *proxy) override;

-	void sweep() override;

-

-    virtual GLenum getTarget() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const;

-    virtual GLsizei getHeight(GLenum target, GLint level) const;

-    virtual GLenum getFormat(GLenum target, GLint level) const;

-    virtual GLenum getType(GLenum target, GLint level) const;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

-	virtual int getLevelCount() const;

-

-    void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);

-    void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);

-    void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);

-    void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

-    void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-

-	void setImage(egl::Image *image);

-

-    virtual bool isSamplerComplete() const;

-    virtual bool isCompressed(GLenum target, GLint level) const;

-	virtual bool isDepth(GLenum target, GLint level) const;

-    virtual void bindTexImage(egl::Surface *surface);

-    virtual void releaseTexImage();

-

-    virtual void generateMipmaps();

-

-	virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);

-    virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);

-	virtual bool isShared(GLenum target, unsigned int level) const;

-

-    egl::Image *getImage(unsigned int level);

-

-protected:

-	virtual ~Texture2D();

-

-	bool isMipmapComplete() const;

-

-	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-

-    egl::Surface *mSurface;

-

-	// A specific internal reference count is kept for colorbuffer proxy references,

-    // because, as the renderbuffer acting as proxy will maintain a binding pointer

-    // back to this texture, there would be a circular reference if we used a binding

-    // pointer here. This reference count will cause the pointer to be set to NULL if

-    // the count drops to zero, but will not cause deletion of the Renderbuffer.

-    Renderbuffer *mColorbufferProxy;

-    unsigned int mProxyRefs;

-};

-

-class TextureCubeMap : public Texture

-{

-public:

-    explicit TextureCubeMap(GLuint name);

-

-	void addProxyRef(const Renderbuffer *proxy) override;

-    void releaseProxy(const Renderbuffer *proxy) override;

-	void sweep() override;

-

-    virtual GLenum getTarget() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const;

-    virtual GLsizei getHeight(GLenum target, GLint level) const;

-    virtual GLenum getFormat(GLenum target, GLint level) const;

-    virtual GLenum getType(GLenum target, GLint level) const;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

-	virtual int getLevelCount() const;

-

-	void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);

-    void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);

-

-    void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);

-    void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

-    void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-

-    virtual bool isSamplerComplete() const;

-    virtual bool isCompressed(GLenum target, GLint level) const;

-	virtual bool isDepth(GLenum target, GLint level) const;

-	virtual void releaseTexImage();

-

-    virtual void generateMipmaps();

-

-    virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);

-	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);

-	virtual bool isShared(GLenum target, unsigned int level) const;

-

-	egl::Image *getImage(int face, unsigned int level);

-

-protected:

-	virtual ~TextureCubeMap();

-

-private:

-	bool isCubeComplete() const;

-	bool isMipmapCubeComplete() const;

-

-    // face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns NULL on failure.

-	egl::Image *getImage(GLenum face, unsigned int level);

-

-	egl::Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-

-	// A specific internal reference count is kept for colorbuffer proxy references,

-    // because, as the renderbuffer acting as proxy will maintain a binding pointer

-    // back to this texture, there would be a circular reference if we used a binding

-    // pointer here. This reference count will cause the pointer to be set to NULL if

-    // the count drops to zero, but will not cause deletion of the Renderbuffer.

-    Renderbuffer *mFaceProxies[6];

-	unsigned int mFaceProxyRefs[6];

-};

-

-class Texture3D : public Texture

-{

-public:

-	explicit Texture3D(GLuint name);

-

-	void addProxyRef(const Renderbuffer *proxy) override;

-    void releaseProxy(const Renderbuffer *proxy) override;

-	void sweep() override;

-

-	virtual GLenum getTarget() const;

-

-	virtual GLsizei getWidth(GLenum target, GLint level) const;

-	virtual GLsizei getHeight(GLenum target, GLint level) const;

-	virtual GLsizei getDepth(GLenum target, GLint level) const;

-	virtual GLenum getFormat(GLenum target, GLint level) const;

-	virtual GLenum getType(GLenum target, GLint level) const;

-	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

-	virtual int getLevelCount() const;

-

-	void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);

-	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);

-	void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);

-	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);

-	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source);

-	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-

-	void setImage(egl::Image *image);

-

-	virtual bool isSamplerComplete() const;

-	virtual bool isCompressed(GLenum target, GLint level) const;

-	virtual bool isDepth(GLenum target, GLint level) const;

-	virtual void bindTexImage(egl::Surface *surface);

-	virtual void releaseTexImage();

-

-	virtual void generateMipmaps();

-

-	virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);

-	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);

-	virtual bool isShared(GLenum target, unsigned int level) const;

-

-	egl::Image *getImage(unsigned int level);

-

-protected:

-	virtual ~Texture3D();

-

-	bool isMipmapComplete() const;

-

-	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-

-	egl::Surface *mSurface;

-

-	// A specific internal reference count is kept for colorbuffer proxy references,

-	// because, as the renderbuffer acting as proxy will maintain a binding pointer

-	// back to this texture, there would be a circular reference if we used a binding

-	// pointer here. This reference count will cause the pointer to be set to NULL if

-	// the count drops to zero, but will not cause deletion of the Renderbuffer.

-	Renderbuffer *mColorbufferProxy;

-	unsigned int mProxyRefs;

-};

-

-class Texture2DArray : public Texture3D

-{

-public:

-	explicit Texture2DArray(GLuint name);

-

-	virtual GLenum getTarget() const;

-	virtual void generateMipmaps();

-

-protected:

-	virtual ~Texture2DArray();

-};

-

-class TextureExternal : public Texture2D

-{

-public:

-    explicit TextureExternal(GLuint name);

-

-    virtual GLenum getTarget() const;

-

-protected:

-	virtual ~TextureExternal();

-};

-}

-

-#endif   // LIBGLESV2_TEXTURE_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Texture.h: Defines the abstract Texture class and its concrete derived
+// classes Texture2D and TextureCubeMap. Implements GL texture objects and
+// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#ifndef LIBGLESV2_TEXTURE_H_
+#define LIBGLESV2_TEXTURE_H_
+
+#include "Renderbuffer.h"
+#include "common/Object.hpp"
+#include "utilities.h"
+#include "libEGL/Texture.hpp"
+#include "common/debug.h"
+
+#include <GLES2/gl2.h>
+
+#include <vector>
+
+namespace egl
+{
+class Surface;
+class Config;
+}
+
+namespace es2
+{
+class Framebuffer;
+
+enum
+{
+	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
+	IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,
+};
+
+class Texture : public egl::Texture
+{
+public:
+	explicit Texture(GLuint name);
+
+	virtual sw::Resource *getResource() const;
+
+	virtual void addProxyRef(const Renderbuffer *proxy) = 0;
+	virtual void releaseProxy(const Renderbuffer *proxy) = 0;
+
+	virtual GLenum getTarget() const = 0;
+
+	bool setMinFilter(GLenum filter);
+	bool setMagFilter(GLenum filter);
+	bool setWrapS(GLenum wrap);
+	bool setWrapT(GLenum wrap);
+	bool setWrapR(GLenum wrap);
+	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);
+	bool setBaseLevel(GLint baseLevel);
+	bool setCompareFunc(GLenum compareFunc);
+	bool setCompareMode(GLenum compareMode);
+	void makeImmutable(GLsizei levels);
+	bool setMaxLevel(GLint maxLevel);
+	bool setMaxLOD(GLfloat maxLOD);
+	bool setMinLOD(GLfloat minLOD);
+	bool setSwizzleR(GLenum swizzleR);
+	bool setSwizzleG(GLenum swizzleG);
+	bool setSwizzleB(GLenum swizzleB);
+	bool setSwizzleA(GLenum swizzleA);
+
+	GLenum getMinFilter() const;
+	GLenum getMagFilter() const;
+	GLenum getWrapS() const;
+	GLenum getWrapT() const;
+	GLenum getWrapR() const;
+	GLfloat getMaxAnisotropy() const;
+	GLint getBaseLevel() const;
+	GLenum getCompareFunc() const;
+	GLenum getCompareMode() const;
+	GLboolean getImmutableFormat() const;
+	GLsizei getImmutableLevels() const;
+	GLint getMaxLevel() const;
+	GLfloat getMaxLOD() const;
+	GLfloat getMinLOD() const;
+	GLenum getSwizzleR() const;
+	GLenum getSwizzleG() const;
+	GLenum getSwizzleB() const;
+	GLenum getSwizzleA() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
+	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
+	virtual GLsizei getDepth(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
+	virtual GLenum getType(GLenum target, GLint level) const = 0;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
+	virtual int getLevelCount() const = 0;
+
+	virtual bool isSamplerComplete() const = 0;
+	virtual bool isCompressed(GLenum target, GLint level) const = 0;
+	virtual bool isDepth(GLenum target, GLint level) const = 0;
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) = 0;
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;
+	virtual egl::Image *createSharedImage(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const = 0;
+
+	virtual void generateMipmaps() = 0;
+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
+
+protected:
+	virtual ~Texture();
+
+	void setImage(GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);
+	void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);
+	void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);
+	void subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);
+
+	bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest);
+
+	bool isMipmapFiltered() const;
+
+	GLenum mMinFilter;
+	GLenum mMagFilter;
+	GLenum mWrapS;
+	GLenum mWrapT;
+	GLenum mWrapR;
+	GLfloat mMaxAnisotropy;
+	GLint mBaseLevel;
+	GLenum mCompareFunc;
+	GLenum mCompareMode;
+	GLboolean mImmutableFormat;
+	GLsizei mImmutableLevels;
+	GLint mMaxLevel;
+	GLfloat mMaxLOD;
+	GLfloat mMinLOD;
+	GLenum mSwizzleR;
+	GLenum mSwizzleG;
+	GLenum mSwizzleB;
+	GLenum mSwizzleA;
+
+	sw::Resource *resource;
+};
+
+class Texture2D : public Texture
+{
+public:
+	explicit Texture2D(GLuint name);
+
+	void addProxyRef(const Renderbuffer *proxy) override;
+	void releaseProxy(const Renderbuffer *proxy) override;
+	void sweep() override;
+
+	virtual GLenum getTarget() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const;
+	virtual GLsizei getHeight(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const;
+	virtual GLenum getType(GLenum target, GLint level) const;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
+	virtual int getLevelCount() const;
+
+	void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+	void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+
+	void setImage(egl::Image *image);
+
+	virtual bool isSamplerComplete() const;
+	virtual bool isCompressed(GLenum target, GLint level) const;
+	virtual bool isDepth(GLenum target, GLint level) const;
+	virtual void bindTexImage(egl::Surface *surface);
+	virtual void releaseTexImage();
+
+	virtual void generateMipmaps();
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const;
+
+	egl::Image *getImage(unsigned int level);
+
+protected:
+	virtual ~Texture2D();
+
+	bool isMipmapComplete() const;
+
+	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+	egl::Surface *mSurface;
+
+	// A specific internal reference count is kept for colorbuffer proxy references,
+	// because, as the renderbuffer acting as proxy will maintain a binding pointer
+	// back to this texture, there would be a circular reference if we used a binding
+	// pointer here. This reference count will cause the pointer to be set to null if
+	// the count drops to zero, but will not cause deletion of the Renderbuffer.
+	Renderbuffer *mColorbufferProxy;
+	unsigned int mProxyRefs;
+};
+
+class TextureCubeMap : public Texture
+{
+public:
+	explicit TextureCubeMap(GLuint name);
+
+	void addProxyRef(const Renderbuffer *proxy) override;
+	void releaseProxy(const Renderbuffer *proxy) override;
+	void sweep() override;
+
+	virtual GLenum getTarget() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const;
+	virtual GLsizei getHeight(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const;
+	virtual GLenum getType(GLenum target, GLint level) const;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
+	virtual int getLevelCount() const;
+
+	void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+	void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+
+	void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+	void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+	void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+
+	virtual bool isSamplerComplete() const;
+	virtual bool isCompressed(GLenum target, GLint level) const;
+	virtual bool isDepth(GLenum target, GLint level) const;
+	virtual void releaseTexImage();
+
+	virtual void generateMipmaps();
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const;
+
+	egl::Image *getImage(int face, unsigned int level);
+
+protected:
+	virtual ~TextureCubeMap();
+
+private:
+	bool isCubeComplete() const;
+	bool isMipmapCubeComplete() const;
+
+	// face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure.
+	egl::Image *getImage(GLenum face, unsigned int level);
+
+	egl::Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+	// A specific internal reference count is kept for colorbuffer proxy references,
+	// because, as the renderbuffer acting as proxy will maintain a binding pointer
+	// back to this texture, there would be a circular reference if we used a binding
+	// pointer here. This reference count will cause the pointer to be set to null if
+	// the count drops to zero, but will not cause deletion of the Renderbuffer.
+	Renderbuffer *mFaceProxies[6];
+	unsigned int mFaceProxyRefs[6];
+};
+
+class Texture3D : public Texture
+{
+public:
+	explicit Texture3D(GLuint name);
+
+	void addProxyRef(const Renderbuffer *proxy) override;
+	void releaseProxy(const Renderbuffer *proxy) override;
+	void sweep() override;
+
+	virtual GLenum getTarget() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const;
+	virtual GLsizei getHeight(GLenum target, GLint level) const;
+	virtual GLsizei getDepth(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const;
+	virtual GLenum getType(GLenum target, GLint level) const;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
+	virtual int getLevelCount() const;
+
+	void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
+	void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
+	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source);
+	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+
+	void setImage(egl::Image *image);
+
+	virtual bool isSamplerComplete() const;
+	virtual bool isCompressed(GLenum target, GLint level) const;
+	virtual bool isDepth(GLenum target, GLint level) const;
+	virtual void bindTexImage(egl::Surface *surface);
+	virtual void releaseTexImage();
+
+	virtual void generateMipmaps();
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const;
+
+	egl::Image *getImage(unsigned int level);
+
+protected:
+	virtual ~Texture3D();
+
+	bool isMipmapComplete() const;
+
+	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+	egl::Surface *mSurface;
+
+	// A specific internal reference count is kept for colorbuffer proxy references,
+	// because, as the renderbuffer acting as proxy will maintain a binding pointer
+	// back to this texture, there would be a circular reference if we used a binding
+	// pointer here. This reference count will cause the pointer to be set to null if
+	// the count drops to zero, but will not cause deletion of the Renderbuffer.
+	Renderbuffer *mColorbufferProxy;
+	unsigned int mProxyRefs;
+};
+
+class Texture2DArray : public Texture3D
+{
+public:
+	explicit Texture2DArray(GLuint name);
+
+	virtual GLenum getTarget() const;
+	virtual void generateMipmaps();
+
+protected:
+	virtual ~Texture2DArray();
+};
+
+class TextureExternal : public Texture2D
+{
+public:
+	explicit TextureExternal(GLuint name);
+
+	virtual GLenum getTarget() const;
+
+protected:
+	virtual ~TextureExternal();
+};
+}
+
+#endif   // LIBGLESV2_TEXTURE_H_
diff --git a/src/OpenGL/libGLESv2/TransformFeedback.cpp b/src/OpenGL/libGLESv2/TransformFeedback.cpp
index 44df63e..fd88646 100644
--- a/src/OpenGL/libGLESv2/TransformFeedback.cpp
+++ b/src/OpenGL/libGLESv2/TransformFeedback.cpp
@@ -1,139 +1,142 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// TransformFeedback.cpp: Implements the es2::TransformFeedback class

-

-#include "TransformFeedback.h"

-

-namespace es2

-{

-

-TransformFeedback::TransformFeedback(GLuint name) : NamedObject(name), mActive(false), mPaused(false), mVertexOffset(0)

-{

-	mGenericBuffer = NULL;

-}

-

-TransformFeedback::~TransformFeedback()

-{

-	mGenericBuffer = NULL;

-	for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; ++i)

-	{

-		mBuffer[i].set(nullptr);

-	}

-}

-

-Buffer* TransformFeedback::getGenericBuffer() const

-{

-	return mGenericBuffer;

-}

-

-Buffer* TransformFeedback::getBuffer(GLuint index) const

-{

-	return mBuffer[index].get();

-}

-

-GLuint TransformFeedback::getGenericBufferName() const

-{

-	return mGenericBuffer.name();

-}

-

-GLuint TransformFeedback::getBufferName(GLuint index) const

-{

-	return mBuffer[index].get().name();

-}

-

-int TransformFeedback::getOffset(GLuint index) const

-{

-	return mBuffer[index].getOffset();

-}

-

-int TransformFeedback::getSize(GLuint index) const

-{

-	return mBuffer[index].getSize();

-}

-

-void TransformFeedback::addVertexOffset(int count)

-{

-	if(isActive() && !isPaused())

-	{

-		mVertexOffset += count;

-	}

-}

-

-int TransformFeedback::vertexOffset() const

-{

-	return mVertexOffset;

-}

-

-bool TransformFeedback::isActive() const

-{

-	return mActive;

-}

-

-bool TransformFeedback::isPaused() const

-{

-	return mPaused;

-}

-

-GLenum TransformFeedback::primitiveMode() const

-{

-	return mPrimitiveMode;

-}

-

-void TransformFeedback::begin(GLenum primitiveMode)

-{

-	mActive = true; mPrimitiveMode = primitiveMode;

-}

-

-void TransformFeedback::end()

-{

-	mActive = false;

-	mPaused = false;

-	mVertexOffset = 0;

-}

-

-void TransformFeedback::setPaused(bool paused)

-{

-	mPaused = paused;

-}

-

-void TransformFeedback::setGenericBuffer(Buffer* buffer)

-{

-	mGenericBuffer = buffer;

-}

-

-void TransformFeedback::setBuffer(GLuint index, Buffer* buffer)

-{

-	mBuffer[index].set(buffer);

-}

-

-void TransformFeedback::setBuffer(GLuint index, Buffer* buffer, GLintptr offset, GLsizeiptr size)

-{

-	mBuffer[index].set(buffer, offset, size);

-}

-

-void TransformFeedback::detachBuffer(GLuint buffer)

-{

-	if(mGenericBuffer.name() == buffer)

-	{

-		mGenericBuffer = NULL;

-	}

-

-	for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; ++i)

-	{

-		if(mBuffer[i].get().name() == buffer)

-		{

-			mBuffer[i].set(nullptr);

-		}

-	}

-}

-

-}

+// 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.
+
+// TransformFeedback.cpp: Implements the es2::TransformFeedback class
+
+#include "TransformFeedback.h"
+
+namespace es2
+{
+
+TransformFeedback::TransformFeedback(GLuint name) : NamedObject(name), mActive(false), mPaused(false), mVertexOffset(0)
+{
+	mGenericBuffer = nullptr;
+}
+
+TransformFeedback::~TransformFeedback()
+{
+	mGenericBuffer = nullptr;
+	for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; ++i)
+	{
+		mBuffer[i].set(nullptr);
+	}
+}
+
+Buffer* TransformFeedback::getGenericBuffer() const
+{
+	return mGenericBuffer;
+}
+
+Buffer* TransformFeedback::getBuffer(GLuint index) const
+{
+	return mBuffer[index].get();
+}
+
+GLuint TransformFeedback::getGenericBufferName() const
+{
+	return mGenericBuffer.name();
+}
+
+GLuint TransformFeedback::getBufferName(GLuint index) const
+{
+	return mBuffer[index].get().name();
+}
+
+int TransformFeedback::getOffset(GLuint index) const
+{
+	return mBuffer[index].getOffset();
+}
+
+int TransformFeedback::getSize(GLuint index) const
+{
+	return mBuffer[index].getSize();
+}
+
+void TransformFeedback::addVertexOffset(int count)
+{
+	if(isActive() && !isPaused())
+	{
+		mVertexOffset += count;
+	}
+}
+
+int TransformFeedback::vertexOffset() const
+{
+	return mVertexOffset;
+}
+
+bool TransformFeedback::isActive() const
+{
+	return mActive;
+}
+
+bool TransformFeedback::isPaused() const
+{
+	return mPaused;
+}
+
+GLenum TransformFeedback::primitiveMode() const
+{
+	return mPrimitiveMode;
+}
+
+void TransformFeedback::begin(GLenum primitiveMode)
+{
+	mActive = true; mPrimitiveMode = primitiveMode;
+}
+
+void TransformFeedback::end()
+{
+	mActive = false;
+	mPaused = false;
+	mVertexOffset = 0;
+}
+
+void TransformFeedback::setPaused(bool paused)
+{
+	mPaused = paused;
+}
+
+void TransformFeedback::setGenericBuffer(Buffer* buffer)
+{
+	mGenericBuffer = buffer;
+}
+
+void TransformFeedback::setBuffer(GLuint index, Buffer* buffer)
+{
+	mBuffer[index].set(buffer);
+}
+
+void TransformFeedback::setBuffer(GLuint index, Buffer* buffer, GLintptr offset, GLsizeiptr size)
+{
+	mBuffer[index].set(buffer, offset, size);
+}
+
+void TransformFeedback::detachBuffer(GLuint buffer)
+{
+	if(mGenericBuffer.name() == buffer)
+	{
+		mGenericBuffer = nullptr;
+	}
+
+	for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; ++i)
+	{
+		if(mBuffer[i].get().name() == buffer)
+		{
+			mBuffer[i].set(nullptr);
+		}
+	}
+}
+
+}
diff --git a/src/OpenGL/libGLESv2/TransformFeedback.h b/src/OpenGL/libGLESv2/TransformFeedback.h
index 0bc11b6..c045a75 100644
--- a/src/OpenGL/libGLESv2/TransformFeedback.h
+++ b/src/OpenGL/libGLESv2/TransformFeedback.h
@@ -1,67 +1,70 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// TransformFeedback.h: Defines the es2::TransformFeedback class

-

-#ifndef LIBGLESV2_TRANSFORM_FEEDBACK_H_

-#define LIBGLESV2_TRANSFORM_FEEDBACK_H_

-

-#include "Buffer.h"

-#include "Context.h"

-#include "common/Object.hpp"

-#include "Renderer/Renderer.hpp"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-

-class TransformFeedback : public gl::NamedObject

-{

-public:

-	TransformFeedback(GLuint name);

-	~TransformFeedback();

-

-	BufferBinding* getBuffers() { return mBuffer; }

-

-	Buffer* getGenericBuffer() const;

-	Buffer* getBuffer(GLuint index) const;

-	GLuint getGenericBufferName() const;

-	GLuint getBufferName(GLuint index) const;

-	int getOffset(GLuint index) const;

-	int getSize(GLuint index) const;

-	bool isActive() const;

-	bool isPaused() const;

-	GLenum primitiveMode() const;

-	int vertexOffset() const;

-

-	void setGenericBuffer(Buffer* buffer);

-	void setBuffer(GLuint index, Buffer* buffer);

-	void setBuffer(GLuint index, Buffer* buffer, GLintptr offset, GLsizeiptr size);

-	void detachBuffer(GLuint buffer);

-	void begin(GLenum primitiveMode);

-	void end();

-	void setPaused(bool paused);

-	void addVertexOffset(int count);

-

-private:

-	gl::BindingPointer<Buffer> mGenericBuffer;

-	BufferBinding mBuffer[MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS];

-

-	bool mActive;

-	bool mPaused;

-	GLenum mPrimitiveMode;

-	int mVertexOffset;

-};

-

-}

-

-#endif // LIBGLESV2_TRANSFORM_FEEDBACK_H_

+// 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.
+
+// TransformFeedback.h: Defines the es2::TransformFeedback class
+
+#ifndef LIBGLESV2_TRANSFORM_FEEDBACK_H_
+#define LIBGLESV2_TRANSFORM_FEEDBACK_H_
+
+#include "Buffer.h"
+#include "Context.h"
+#include "common/Object.hpp"
+#include "Renderer/Renderer.hpp"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+
+class TransformFeedback : public gl::NamedObject
+{
+public:
+	TransformFeedback(GLuint name);
+	~TransformFeedback();
+
+	BufferBinding* getBuffers() { return mBuffer; }
+
+	Buffer* getGenericBuffer() const;
+	Buffer* getBuffer(GLuint index) const;
+	GLuint getGenericBufferName() const;
+	GLuint getBufferName(GLuint index) const;
+	int getOffset(GLuint index) const;
+	int getSize(GLuint index) const;
+	bool isActive() const;
+	bool isPaused() const;
+	GLenum primitiveMode() const;
+	int vertexOffset() const;
+
+	void setGenericBuffer(Buffer* buffer);
+	void setBuffer(GLuint index, Buffer* buffer);
+	void setBuffer(GLuint index, Buffer* buffer, GLintptr offset, GLsizeiptr size);
+	void detachBuffer(GLuint buffer);
+	void begin(GLenum primitiveMode);
+	void end();
+	void setPaused(bool paused);
+	void addVertexOffset(int count);
+
+private:
+	gl::BindingPointer<Buffer> mGenericBuffer;
+	BufferBinding mBuffer[MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS];
+
+	bool mActive;
+	bool mPaused;
+	GLenum mPrimitiveMode;
+	int mVertexOffset;
+};
+
+}
+
+#endif // LIBGLESV2_TRANSFORM_FEEDBACK_H_
diff --git a/src/OpenGL/libGLESv2/VertexArray.cpp b/src/OpenGL/libGLESv2/VertexArray.cpp
index 81ce677..d52e7ca 100644
--- a/src/OpenGL/libGLESv2/VertexArray.cpp
+++ b/src/OpenGL/libGLESv2/VertexArray.cpp
@@ -1,81 +1,84 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google 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 "VertexArray.h"

-

-namespace es2

-{

-

-VertexArray::VertexArray(GLuint name) : gl::NamedObject(name)

-{

-}

-

-VertexArray::~VertexArray()

-{

-	for(size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-		mVertexAttributes[i].mBoundBuffer = NULL;

-    }

-    mElementArrayBuffer = NULL;

-}

-

-void VertexArray::detachBuffer(GLuint bufferName)

-{

-	for(size_t attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)

-    {

-		if(mVertexAttributes[attribute].mBoundBuffer.name() == bufferName)

-        {

-			mVertexAttributes[attribute].mBoundBuffer = NULL;

-        }

-    }

-

-    if (mElementArrayBuffer.name() == bufferName)

-    {

-        mElementArrayBuffer = NULL;

-    }

-}

-

-const VertexAttribute& VertexArray::getVertexAttribute(size_t attributeIndex) const

-{

-	ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);

-    return mVertexAttributes[attributeIndex];

-}

-

-void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor)

-{

-	ASSERT(index < MAX_VERTEX_ATTRIBS);

-	mVertexAttributes[index].mDivisor = divisor;

-}

-

-void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState)

-{

-	ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);

-	mVertexAttributes[attributeIndex].mArrayEnabled = enabledState;

-}

-

-void VertexArray::setAttributeState(unsigned int attributeIndex, Buffer *boundBuffer, GLint size, GLenum type,

-                                    bool normalized, GLsizei stride, const void *pointer)

-{

-	ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);

-    mVertexAttributes[attributeIndex].mBoundBuffer = boundBuffer;

-    mVertexAttributes[attributeIndex].mSize = size;

-    mVertexAttributes[attributeIndex].mType = type;

-    mVertexAttributes[attributeIndex].mNormalized = normalized;

-	mVertexAttributes[attributeIndex].mStride = stride;

-	mVertexAttributes[attributeIndex].mPointer = pointer;

-}

-

-void VertexArray::setElementArrayBuffer(Buffer *buffer)

-{

-    mElementArrayBuffer = buffer;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "VertexArray.h"
+
+namespace es2
+{
+
+VertexArray::VertexArray(GLuint name) : gl::NamedObject(name)
+{
+}
+
+VertexArray::~VertexArray()
+{
+	for(size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mVertexAttributes[i].mBoundBuffer = nullptr;
+	}
+	mElementArrayBuffer = nullptr;
+}
+
+void VertexArray::detachBuffer(GLuint bufferName)
+{
+	for(size_t attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+	{
+		if(mVertexAttributes[attribute].mBoundBuffer.name() == bufferName)
+		{
+			mVertexAttributes[attribute].mBoundBuffer = nullptr;
+		}
+	}
+
+	if(mElementArrayBuffer.name() == bufferName)
+	{
+		mElementArrayBuffer = nullptr;
+	}
+}
+
+const VertexAttribute& VertexArray::getVertexAttribute(size_t attributeIndex) const
+{
+	ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);
+	return mVertexAttributes[attributeIndex];
+}
+
+void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor)
+{
+	ASSERT(index < MAX_VERTEX_ATTRIBS);
+	mVertexAttributes[index].mDivisor = divisor;
+}
+
+void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState)
+{
+	ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);
+	mVertexAttributes[attributeIndex].mArrayEnabled = enabledState;
+}
+
+void VertexArray::setAttributeState(unsigned int attributeIndex, Buffer *boundBuffer, GLint size, GLenum type,
+                                    bool normalized, GLsizei stride, const void *pointer)
+{
+	ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);
+	mVertexAttributes[attributeIndex].mBoundBuffer = boundBuffer;
+	mVertexAttributes[attributeIndex].mSize = size;
+	mVertexAttributes[attributeIndex].mType = type;
+	mVertexAttributes[attributeIndex].mNormalized = normalized;
+	mVertexAttributes[attributeIndex].mStride = stride;
+	mVertexAttributes[attributeIndex].mPointer = pointer;
+}
+
+void VertexArray::setElementArrayBuffer(Buffer *buffer)
+{
+	mElementArrayBuffer = buffer;
+}
+
+}
diff --git a/src/OpenGL/libGLESv2/VertexArray.h b/src/OpenGL/libGLESv2/VertexArray.h
index 8fb8be5..363cf53 100644
--- a/src/OpenGL/libGLESv2/VertexArray.h
+++ b/src/OpenGL/libGLESv2/VertexArray.h
@@ -1,50 +1,53 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// VertexArray.h: Defines the es2::VertexArray class

-

-#ifndef LIBGLESV2_VERTEX_ARRAY_H_

-#define LIBGLESV2_VERTEX_ARRAY_H_

-

-#include "Buffer.h"

-#include "Context.h"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-

-class VertexArray : public gl::NamedObject

-{

-public:

-	VertexArray(GLuint name);

-	~VertexArray();

-

-	const VertexAttribute& getVertexAttribute(size_t attributeIndex) const;

-	VertexAttributeArray& getVertexAttributes() { return mVertexAttributes; }

-

-	void detachBuffer(GLuint bufferName);

-	void setVertexAttribDivisor(GLuint index, GLuint divisor);

-	void enableAttribute(unsigned int attributeIndex, bool enabledState);

-	void setAttributeState(unsigned int attributeIndex, Buffer *boundBuffer, GLint size, GLenum type,

-	                       bool normalized, GLsizei stride, const void *pointer);

-

-	Buffer *getElementArrayBuffer() const { return mElementArrayBuffer; }

-	void setElementArrayBuffer(Buffer *buffer);

-

-private:

-	VertexAttributeArray mVertexAttributes;

-	gl::BindingPointer<Buffer> mElementArrayBuffer;

-};

-

-}

-

-#endif // LIBGLESV2_VERTEX_ARRAY_H_

+// 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.
+
+// VertexArray.h: Defines the es2::VertexArray class
+
+#ifndef LIBGLESV2_VERTEX_ARRAY_H_
+#define LIBGLESV2_VERTEX_ARRAY_H_
+
+#include "Buffer.h"
+#include "Context.h"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+
+class VertexArray : public gl::NamedObject
+{
+public:
+	VertexArray(GLuint name);
+	~VertexArray();
+
+	const VertexAttribute& getVertexAttribute(size_t attributeIndex) const;
+	VertexAttributeArray& getVertexAttributes() { return mVertexAttributes; }
+
+	void detachBuffer(GLuint bufferName);
+	void setVertexAttribDivisor(GLuint index, GLuint divisor);
+	void enableAttribute(unsigned int attributeIndex, bool enabledState);
+	void setAttributeState(unsigned int attributeIndex, Buffer *boundBuffer, GLint size, GLenum type,
+	                       bool normalized, GLsizei stride, const void *pointer);
+
+	Buffer *getElementArrayBuffer() const { return mElementArrayBuffer; }
+	void setElementArrayBuffer(Buffer *buffer);
+
+private:
+	VertexAttributeArray mVertexAttributes;
+	gl::BindingPointer<Buffer> mElementArrayBuffer;
+};
+
+}
+
+#endif // LIBGLESV2_VERTEX_ARRAY_H_
diff --git a/src/OpenGL/libGLESv2/VertexDataManager.cpp b/src/OpenGL/libGLESv2/VertexDataManager.cpp
index 70d89c8..ddc9d8d 100644
--- a/src/OpenGL/libGLESv2/VertexDataManager.cpp
+++ b/src/OpenGL/libGLESv2/VertexDataManager.cpp
@@ -1,340 +1,343 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#include "VertexDataManager.h"

-

-#include "Buffer.h"

-#include "Program.h"

-#include "IndexDataManager.h"

-#include "common/debug.h"

-

-namespace

-{

-    enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};

-}

-

-namespace es2

-{

-

-VertexDataManager::VertexDataManager(Context *context) : mContext(context)

-{

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        mDirtyCurrentValue[i] = true;

-        mCurrentValueBuffer[i] = NULL;

-    }

-

-    mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming vertex buffer.");

-    }

-}

-

-VertexDataManager::~VertexDataManager()

-{

-    delete mStreamingBuffer;

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        delete mCurrentValueBuffer[i];

-    }

-}

-

-unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)

-{

-    Buffer *buffer = attribute.mBoundBuffer;

-

-    int inputStride = attribute.stride();

-    int elementSize = attribute.typeSize();

-    unsigned int streamOffset = 0;

-

-    char *output = nullptr;

-

-    if(vertexBuffer)

-    {

-        output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);

-    }

-

-    if(!output)

-    {

-        ERR("Failed to map vertex buffer.");

-        return ~0u;

-    }

-

-    const char *input = nullptr;

-

-    if(buffer)

-    {

-        input = static_cast<const char*>(buffer->data()) + attribute.mOffset;

-    }

-    else

-    {

-        input = static_cast<const char*>(attribute.mPointer);

-    }

-

-    input += inputStride * start;

-

-    if(inputStride == elementSize)

-    {

-        memcpy(output, input, count * inputStride);

-    }

-    else

-    {

-		for(int i = 0; i < count; i++)

-		{

-			memcpy(output, input, elementSize);

-			output += elementSize;

-			input += inputStride;

-		}

-    }

-

-    vertexBuffer->unmap();

-

-    return streamOffset;

-}

-

-GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instanceId)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-	const VertexAttributeArray &attribs = mContext->getVertexArrayAttributes();

-	const VertexAttributeArray &currentAttribs = mContext->getCurrentVertexAttributes();

-    Program *program = mContext->getCurrentProgram();

-

-    // Determine the required storage size per used buffer

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        const VertexAttribute &attrib = attribs[i].mArrayEnabled ? attribs[i] : currentAttribs[i];

-

-        if(program->getAttributeStream(i) != -1 && attrib.mArrayEnabled)

-        {

-            if(!attrib.mBoundBuffer)

-            {

-                const bool isInstanced = attrib.mDivisor > 0;

-                mStreamingBuffer->addRequiredSpace(attrib.typeSize() * (isInstanced ? 1 : count));

-            }

-        }

-    }

-

-    mStreamingBuffer->reserveRequiredSpace();

-

-    // Perform the vertex data translations

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        if(program->getAttributeStream(i) != -1)

-        {

-			const VertexAttribute &attrib = attribs[i].mArrayEnabled ? attribs[i] : currentAttribs[i];

-

-            if(attrib.mArrayEnabled)

-            {

-				const bool isInstanced = attrib.mDivisor > 0;

-

-				// Instanced vertices do not apply the 'start' offset

-				GLint firstVertexIndex = isInstanced ? instanceId / attrib.mDivisor : start;

-

-                Buffer *buffer = attrib.mBoundBuffer;

-

-                if(!buffer && attrib.mPointer == NULL)

-                {

-                    // This is an application error that would normally result in a crash, but we catch it and return an error

-                    ERR("An enabled vertex array has no buffer and no pointer.");

-                    return GL_INVALID_OPERATION;

-                }

-

-                sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-                if(staticBuffer)

-                {

-					translated[i].vertexBuffer = staticBuffer;

-					translated[i].offset = firstVertexIndex * attrib.stride() + attrib.mOffset;

-					translated[i].stride = isInstanced ? 0 : attrib.stride();

-                }

-                else

-                {

-                    unsigned int streamOffset = writeAttributeData(mStreamingBuffer, firstVertexIndex, isInstanced ? 1 : count, attrib);

-

-					if(streamOffset == ~0u)

-					{

-						return GL_OUT_OF_MEMORY;

-					}

-

-					translated[i].vertexBuffer = mStreamingBuffer->getResource();

-					translated[i].offset = streamOffset;

-					translated[i].stride = isInstanced ? 0 : attrib.typeSize();

-                }

-

-				switch(attrib.mType)

-				{

-				case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;

-				case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;

-				case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;

-				case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;

-				case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;

-				case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;

-				case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;

-				case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-				default: UNREACHABLE(attrib.mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-				}

-

-				translated[i].count = attrib.mSize;

-				translated[i].normalized = attrib.mNormalized;

-            }

-            else

-            {

-                if(mDirtyCurrentValue[i])

-                {

-                    delete mCurrentValueBuffer[i];

-                    mCurrentValueBuffer[i] = new ConstantVertexBuffer(attrib.getCurrentValueBitsAsFloat(0), attrib.getCurrentValueBitsAsFloat(1), attrib.getCurrentValueBitsAsFloat(2), attrib.getCurrentValueBitsAsFloat(3));

-                    mDirtyCurrentValue[i] = false;

-                }

-

-                translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();

-

-                translated[i].type = sw::STREAMTYPE_FLOAT;

-				translated[i].count = 4;

-                translated[i].stride = 0;

-                translated[i].offset = 0;

-            }

-        }

-    }

-

-    return GL_NO_ERROR;

-}

-

-VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(NULL)

-{

-    if(size > 0)

-    {

-        mVertexBuffer = new sw::Resource(size + 1024);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", size);

-        }

-    }

-}

-

-VertexBuffer::~VertexBuffer()

-{

-    if(mVertexBuffer)

-    {

-        mVertexBuffer->destruct();

-    }

-}

-

-void VertexBuffer::unmap()

-{

-    if(mVertexBuffer)

-    {

-		mVertexBuffer->unlock();

-    }

-}

-

-sw::Resource *VertexBuffer::getResource() const

-{

-    return mVertexBuffer;

-}

-

-ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))

-{

-    if(mVertexBuffer)

-    {

-		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);

-

-        vector[0] = x;

-        vector[1] = y;

-        vector[2] = z;

-        vector[3] = w;

-

-        mVertexBuffer->unlock();

-    }

-}

-

-ConstantVertexBuffer::~ConstantVertexBuffer()

-{

-}

-

-StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)

-{

-    mBufferSize = size;

-    mWritePosition = 0;

-    mRequiredSpace = 0;

-}

-

-StreamingVertexBuffer::~StreamingVertexBuffer()

-{

-}

-

-void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)

-{

-    mRequiredSpace += requiredSpace;

-}

-

-void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mVertexBuffer)

-    {

-		// We can use a private lock because we never overwrite the content

-		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingVertexBuffer::reserveRequiredSpace()

-{

-    if(mRequiredSpace > mBufferSize)

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-            mVertexBuffer = 0;

-        }

-

-        mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.

-

-		mVertexBuffer = new sw::Resource(mBufferSize);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-			mVertexBuffer = new sw::Resource(mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-

-    mRequiredSpace = 0;

-}

-

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#include "VertexDataManager.h"
+
+#include "Buffer.h"
+#include "Program.h"
+#include "IndexDataManager.h"
+#include "common/debug.h"
+
+namespace
+{
+	enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};
+}
+
+namespace es2
+{
+
+VertexDataManager::VertexDataManager(Context *context) : mContext(context)
+{
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mDirtyCurrentValue[i] = true;
+		mCurrentValueBuffer[i] = nullptr;
+	}
+
+	mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming vertex buffer.");
+	}
+}
+
+VertexDataManager::~VertexDataManager()
+{
+	delete mStreamingBuffer;
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		delete mCurrentValueBuffer[i];
+	}
+}
+
+unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
+{
+	Buffer *buffer = attribute.mBoundBuffer;
+
+	int inputStride = attribute.stride();
+	int elementSize = attribute.typeSize();
+	unsigned int streamOffset = 0;
+
+	char *output = nullptr;
+
+	if(vertexBuffer)
+	{
+		output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);
+	}
+
+	if(!output)
+	{
+		ERR("Failed to map vertex buffer.");
+		return ~0u;
+	}
+
+	const char *input = nullptr;
+
+	if(buffer)
+	{
+		input = static_cast<const char*>(buffer->data()) + attribute.mOffset;
+	}
+	else
+	{
+		input = static_cast<const char*>(attribute.mPointer);
+	}
+
+	input += inputStride * start;
+
+	if(inputStride == elementSize)
+	{
+		memcpy(output, input, count * inputStride);
+	}
+	else
+	{
+		for(int i = 0; i < count; i++)
+		{
+			memcpy(output, input, elementSize);
+			output += elementSize;
+			input += inputStride;
+		}
+	}
+
+	vertexBuffer->unmap();
+
+	return streamOffset;
+}
+
+GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instanceId)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	const VertexAttributeArray &attribs = mContext->getVertexArrayAttributes();
+	const VertexAttributeArray &currentAttribs = mContext->getCurrentVertexAttributes();
+	Program *program = mContext->getCurrentProgram();
+
+	// Determine the required storage size per used buffer
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		const VertexAttribute &attrib = attribs[i].mArrayEnabled ? attribs[i] : currentAttribs[i];
+
+		if(program->getAttributeStream(i) != -1 && attrib.mArrayEnabled)
+		{
+			if(!attrib.mBoundBuffer)
+			{
+				const bool isInstanced = attrib.mDivisor > 0;
+				mStreamingBuffer->addRequiredSpace(attrib.typeSize() * (isInstanced ? 1 : count));
+			}
+		}
+	}
+
+	mStreamingBuffer->reserveRequiredSpace();
+
+	// Perform the vertex data translations
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(program->getAttributeStream(i) != -1)
+		{
+			const VertexAttribute &attrib = attribs[i].mArrayEnabled ? attribs[i] : currentAttribs[i];
+
+			if(attrib.mArrayEnabled)
+			{
+				const bool isInstanced = attrib.mDivisor > 0;
+
+				// Instanced vertices do not apply the 'start' offset
+				GLint firstVertexIndex = isInstanced ? instanceId / attrib.mDivisor : start;
+
+				Buffer *buffer = attrib.mBoundBuffer;
+
+				if(!buffer && attrib.mPointer == nullptr)
+				{
+					// This is an application error that would normally result in a crash, but we catch it and return an error
+					ERR("An enabled vertex array has no buffer and no pointer.");
+					return GL_INVALID_OPERATION;
+				}
+
+				sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr;
+
+				if(staticBuffer)
+				{
+					translated[i].vertexBuffer = staticBuffer;
+					translated[i].offset = firstVertexIndex * attrib.stride() + attrib.mOffset;
+					translated[i].stride = isInstanced ? 0 : attrib.stride();
+				}
+				else
+				{
+					unsigned int streamOffset = writeAttributeData(mStreamingBuffer, firstVertexIndex, isInstanced ? 1 : count, attrib);
+
+					if(streamOffset == ~0u)
+					{
+						return GL_OUT_OF_MEMORY;
+					}
+
+					translated[i].vertexBuffer = mStreamingBuffer->getResource();
+					translated[i].offset = streamOffset;
+					translated[i].stride = isInstanced ? 0 : attrib.typeSize();
+				}
+
+				switch(attrib.mType)
+				{
+				case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;
+				case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;
+				case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;
+				case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;
+				case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;
+				case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;
+				case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;
+				case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+				default: UNREACHABLE(attrib.mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+				}
+
+				translated[i].count = attrib.mSize;
+				translated[i].normalized = attrib.mNormalized;
+			}
+			else
+			{
+				if(mDirtyCurrentValue[i])
+				{
+					delete mCurrentValueBuffer[i];
+					mCurrentValueBuffer[i] = new ConstantVertexBuffer(attrib.getCurrentValueBitsAsFloat(0), attrib.getCurrentValueBitsAsFloat(1), attrib.getCurrentValueBitsAsFloat(2), attrib.getCurrentValueBitsAsFloat(3));
+					mDirtyCurrentValue[i] = false;
+				}
+
+				translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();
+
+				translated[i].type = sw::STREAMTYPE_FLOAT;
+				translated[i].count = 4;
+				translated[i].stride = 0;
+				translated[i].offset = 0;
+			}
+		}
+	}
+
+	return GL_NO_ERROR;
+}
+
+VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(nullptr)
+{
+	if(size > 0)
+	{
+		mVertexBuffer = new sw::Resource(size + 1024);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", size);
+		}
+	}
+}
+
+VertexBuffer::~VertexBuffer()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->destruct();
+	}
+}
+
+void VertexBuffer::unmap()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->unlock();
+	}
+}
+
+sw::Resource *VertexBuffer::getResource() const
+{
+	return mVertexBuffer;
+}
+
+ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))
+{
+	if(mVertexBuffer)
+	{
+		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);
+
+		vector[0] = x;
+		vector[1] = y;
+		vector[2] = z;
+		vector[3] = w;
+
+		mVertexBuffer->unlock();
+	}
+}
+
+ConstantVertexBuffer::~ConstantVertexBuffer()
+{
+}
+
+StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)
+{
+	mBufferSize = size;
+	mWritePosition = 0;
+	mRequiredSpace = 0;
+}
+
+StreamingVertexBuffer::~StreamingVertexBuffer()
+{
+}
+
+void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)
+{
+	mRequiredSpace += requiredSpace;
+}
+
+void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = nullptr;
+
+	if(mVertexBuffer)
+	{
+		// We can use a private lock because we never overwrite the content
+		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingVertexBuffer::reserveRequiredSpace()
+{
+	if(mRequiredSpace > mBufferSize)
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = 0;
+		}
+
+		mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
+
+		mVertexBuffer = new sw::Resource(mBufferSize);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = new sw::Resource(mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+
+	mRequiredSpace = 0;
+}
+
+}
diff --git a/src/OpenGL/libGLESv2/VertexDataManager.h b/src/OpenGL/libGLESv2/VertexDataManager.h
index ddf2c99..caf1ffa 100644
--- a/src/OpenGL/libGLESv2/VertexDataManager.h
+++ b/src/OpenGL/libGLESv2/VertexDataManager.h
@@ -1,98 +1,101 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#ifndef LIBGLESV2_VERTEXDATAMANAGER_H_

-#define LIBGLESV2_VERTEXDATAMANAGER_H_

-

-#include "Context.h"

-#include "Device.hpp"

-

-#include <GLES2/gl2.h>

-

-namespace es2

-{

-

-struct TranslatedAttribute

-{

-    sw::StreamType type;

-	int count;

-	bool normalized;

-

-    unsigned int offset;

-    unsigned int stride;   // 0 means not to advance the read pointer at all

-

-    sw::Resource *vertexBuffer;

-};

-

-class VertexBuffer

-{

-  public:

-    VertexBuffer(unsigned int size);

-    virtual ~VertexBuffer();

-

-    void unmap();

-

-    sw::Resource *getResource() const;

-

-  protected:

-    sw::Resource *mVertexBuffer;

-};

-

-class ConstantVertexBuffer : public VertexBuffer

-{

-  public:

-    ConstantVertexBuffer(float x, float y, float z, float w);

-    ~ConstantVertexBuffer();

-};

-

-class StreamingVertexBuffer : public VertexBuffer

-{

-  public:

-    StreamingVertexBuffer(unsigned int size);

-    ~StreamingVertexBuffer();

-

-    void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);

-    void reserveRequiredSpace();

-    void addRequiredSpace(unsigned int requiredSpace);

-

-  protected:

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-    unsigned int mRequiredSpace;

-};

-

-class VertexDataManager

-{

-  public:

-    VertexDataManager(Context *context);

-    virtual ~VertexDataManager();

-

-    void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }

-

-    GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instanceId);

-

-  private:

-    unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);

-

-    Context *const mContext;

-

-    StreamingVertexBuffer *mStreamingBuffer;

-

-    bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];

-    ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];

-};

-

-}

-

-#endif   // LIBGLESV2_VERTEXDATAMANAGER_H_

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#ifndef LIBGLESV2_VERTEXDATAMANAGER_H_
+#define LIBGLESV2_VERTEXDATAMANAGER_H_
+
+#include "Context.h"
+#include "Device.hpp"
+
+#include <GLES2/gl2.h>
+
+namespace es2
+{
+
+struct TranslatedAttribute
+{
+	sw::StreamType type;
+	int count;
+	bool normalized;
+
+	unsigned int offset;
+	unsigned int stride;   // 0 means not to advance the read pointer at all
+
+	sw::Resource *vertexBuffer;
+};
+
+class VertexBuffer
+{
+public:
+	VertexBuffer(unsigned int size);
+	virtual ~VertexBuffer();
+
+	void unmap();
+
+	sw::Resource *getResource() const;
+
+protected:
+	sw::Resource *mVertexBuffer;
+};
+
+class ConstantVertexBuffer : public VertexBuffer
+{
+public:
+	ConstantVertexBuffer(float x, float y, float z, float w);
+	~ConstantVertexBuffer();
+};
+
+class StreamingVertexBuffer : public VertexBuffer
+{
+public:
+	StreamingVertexBuffer(unsigned int size);
+	~StreamingVertexBuffer();
+
+	void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);
+	void reserveRequiredSpace();
+	void addRequiredSpace(unsigned int requiredSpace);
+
+protected:
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+	unsigned int mRequiredSpace;
+};
+
+class VertexDataManager
+{
+public:
+	VertexDataManager(Context *context);
+	virtual ~VertexDataManager();
+
+	void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
+
+	GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instanceId);
+
+private:
+	unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
+
+	Context *const mContext;
+
+	StreamingVertexBuffer *mStreamingBuffer;
+
+	bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
+	ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
+};
+
+}
+
+#endif   // LIBGLESV2_VERTEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index cd721f3..4732c52 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -1,6942 +1,6945 @@
-// 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.

-//

-// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "Buffer.h"

-#include "Context.h"

-#include "Fence.h"

-#include "Framebuffer.h"

-#include "Program.h"

-#include "Renderbuffer.h"

-#include "Shader.h"

-#include "Texture.h"

-#include "Query.h"

-#include "TransformFeedback.h"

-#include "common/debug.h"

-#include "Common/Version.h"

-

-#include <GLES2/gl2.h>

-#include <GLES2/gl2ext.h>

-#include <GLES3/gl3.h>

-

-#include <limits>

-

-#ifdef ANDROID

-#include <cutils/log.h>

-#endif

-

-namespace es2

-{

-

-static bool validImageSize(GLint level, GLsizei width, GLsizei height)

-{

-	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)

-	{

-		return false;

-	}

-

-	return true;

-}

-

-static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)

-{

-	GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);

-	if(validationError != GL_NONE)

-	{

-		return error(validationError, false);

-	}

-

-	// [OpenGL ES 2.0.24] table 3.9

-	switch(textureFormat)

-	{

-	case GL_ALPHA:

-		if(colorbufferFormat != GL_ALPHA &&

-		   colorbufferFormat != GL_RGBA &&

-		   colorbufferFormat != GL_RGBA4 &&

-		   colorbufferFormat != GL_RGB5_A1 &&

-		   colorbufferFormat != GL_RGBA8_OES &&

-		   colorbufferFormat != GL_BGRA8_EXT &&

-		   colorbufferFormat != GL_RGBA16F_EXT &&

-		   colorbufferFormat != GL_RGBA32F_EXT)

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-		break;

-	case GL_LUMINANCE:

-	case GL_RGB:

-		if(colorbufferFormat != GL_RGB &&

-		   colorbufferFormat != GL_RGB565 &&

-		   colorbufferFormat != GL_RGB8_OES &&

-		   colorbufferFormat != GL_RGBA &&

-		   colorbufferFormat != GL_RGBA4 &&

-		   colorbufferFormat != GL_RGB5_A1 &&

-		   colorbufferFormat != GL_RGBA8_OES &&

-		   colorbufferFormat != GL_RGB16F_EXT &&

-		   colorbufferFormat != GL_RGB32F_EXT &&

-		   colorbufferFormat != GL_BGRA8_EXT &&

-		   colorbufferFormat != GL_RGBA16F_EXT &&

-		   colorbufferFormat != GL_RGBA32F_EXT)

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-		break;

-	case GL_LUMINANCE_ALPHA:

-	case GL_RGBA:

-		if(colorbufferFormat != GL_RGBA &&

-		   colorbufferFormat != GL_RGBA4 &&

-		   colorbufferFormat != GL_RGB5_A1 &&

-		   colorbufferFormat != GL_RGBA8_OES &&

-		   colorbufferFormat != GL_BGRA8_EXT &&

-		   colorbufferFormat != GL_RGBA16F_EXT &&

-		   colorbufferFormat != GL_RGBA32F_EXT)

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-		break;

-	case GL_DEPTH_COMPONENT:

-	case GL_DEPTH_STENCIL_OES:

-		return error(GL_INVALID_OPERATION, false);

-	default:

-		return error(GL_INVALID_ENUM, false);

-	}

-	return true;

-}

-

-void ActiveTexture(GLenum texture)

-{

-	TRACE("(GLenum texture = 0x%X)", texture);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		context->setActiveSampler(texture - GL_TEXTURE0);

-	}

-}

-

-void AttachShader(GLuint program, GLuint shader)

-{

-	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(!programObject->attachShader(shaderObject))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void BeginQueryEXT(GLenum target, GLuint name)

-{

-	TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);

-

-	switch(target)

-	{

-	case GL_ANY_SAMPLES_PASSED_EXT:

-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(name == 0)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->beginQuery(target, name);

-	}

-}

-

-void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(strncmp(name, "gl_", 3) == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		programObject->bindAttributeLocation(index, name);

-	}

-}

-

-void BindBuffer(GLenum target, GLuint buffer)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLint clientVersion = egl::getClientVersion();

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			context->bindArrayBuffer(buffer);

-			return;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			context->bindElementArrayBuffer(buffer);

-			return;

-		case GL_COPY_READ_BUFFER:

-			if(clientVersion >= 3)

-			{

-				context->bindCopyReadBuffer(buffer);

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_COPY_WRITE_BUFFER:

-			if(clientVersion >= 3)

-			{

-				context->bindCopyWriteBuffer(buffer);

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_PIXEL_PACK_BUFFER:

-			if(clientVersion >= 3)

-			{

-				context->bindPixelPackBuffer(buffer);

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_PIXEL_UNPACK_BUFFER:

-			if(clientVersion >= 3)

-			{

-				context->bindPixelUnpackBuffer(buffer);

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TRANSFORM_FEEDBACK_BUFFER:

-			if(clientVersion >= 3)

-			{

-				context->bindTransformFeedbackBuffer(buffer);

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_UNIFORM_BUFFER:

-			if(clientVersion >= 3)

-			{

-				context->bindGenericUniformBuffer(buffer);

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void BindFramebuffer(GLenum target, GLuint framebuffer)

-{

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

-

-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)

-		{

-			context->bindReadFramebuffer(framebuffer);

-		}

-

-		if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)

-		{

-			context->bindDrawFramebuffer(framebuffer);

-		}

-	}

-}

-

-void BindRenderbuffer(GLenum target, GLuint renderbuffer)

-{

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

-

-	if(target != GL_RENDERBUFFER)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		// [OpenGL ES 2.0.25] Section 4.4.3 page 110

-		// [OpenGL ES 3.0.4] Section 4.4.2 page 204

-		// If renderbuffer is not zero, then the resulting renderbuffer object

-		// is a new state vector, initialized with a zero-sized memory buffer.

-		context->bindRenderbuffer(renderbuffer);

-	}

-}

-

-void BindTexture(GLenum target, GLuint texture)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture *textureObject = context->getTexture(texture);

-

-		if(textureObject && textureObject->getTarget() != target && texture != 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			context->bindTexture2D(texture);

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			context->bindTextureCubeMap(texture);

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			context->bindTextureExternal(texture);

-			break;

-		case GL_TEXTURE_2D_ARRAY:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			context->bindTexture2DArray(texture);

-			break;

-		case GL_TEXTURE_3D_OES:

-			context->bindTexture3D(texture);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",

-		red, green, blue, alpha);

-

-	es2::Context* context = es2::getContext();

-

-	if(context)

-	{

-		context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));

-	}

-}

-

-void BlendEquation(GLenum mode)

-{

-	glBlendEquationSeparate(mode, mode);

-}

-

-void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)

-{

-	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);

-

-	switch(modeRGB)

-	{

-	case GL_FUNC_ADD:

-	case GL_FUNC_SUBTRACT:

-	case GL_FUNC_REVERSE_SUBTRACT:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(modeAlpha)

-	{

-	case GL_FUNC_ADD:

-	case GL_FUNC_SUBTRACT:

-	case GL_FUNC_REVERSE_SUBTRACT:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setBlendEquation(modeRGB, modeAlpha);

-	}

-}

-

-void BlendFunc(GLenum sfactor, GLenum dfactor)

-{

-	glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);

-}

-

-void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)

-{

-	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",

-	      srcRGB, dstRGB, srcAlpha, dstAlpha);

-

-	GLint clientVersion = egl::getClientVersion();

-

-	switch(srcRGB)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-	case GL_SRC_ALPHA_SATURATE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(dstRGB)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-		break;

-	case GL_SRC_ALPHA_SATURATE:

-		if(clientVersion < 3)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(srcAlpha)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-	case GL_SRC_ALPHA_SATURATE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(dstAlpha)

-	{

-	case GL_ZERO:

-	case GL_ONE:

-	case GL_SRC_COLOR:

-	case GL_ONE_MINUS_SRC_COLOR:

-	case GL_DST_COLOR:

-	case GL_ONE_MINUS_DST_COLOR:

-	case GL_SRC_ALPHA:

-	case GL_ONE_MINUS_SRC_ALPHA:

-	case GL_DST_ALPHA:

-	case GL_ONE_MINUS_DST_ALPHA:

-	case GL_CONSTANT_COLOR:

-	case GL_ONE_MINUS_CONSTANT_COLOR:

-	case GL_CONSTANT_ALPHA:

-	case GL_ONE_MINUS_CONSTANT_ALPHA:

-		break;

-	case GL_SRC_ALPHA_SATURATE:

-		if(clientVersion < 3)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

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

-	}

-}

-

-void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)

-{

-	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications

-

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

-	      target, size, data, usage);

-

-	if(size < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	GLint clientVersion = egl::getClientVersion();

-

-	switch(usage)

-	{

-	case GL_STREAM_DRAW:

-	case GL_STATIC_DRAW:

-	case GL_DYNAMIC_DRAW:

-		break;

-	case GL_STREAM_READ:

-	case GL_STREAM_COPY:

-	case GL_STATIC_READ:

-	case GL_STATIC_COPY:

-	case GL_DYNAMIC_READ:

-	case GL_DYNAMIC_COPY:

-		if(clientVersion < 3)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer = nullptr;

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-	}

-}

-

-void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)

-{

-	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications

-	offset = static_cast<GLint>(offset);

-

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

-	      target, offset, size, data);

-

-	if(size < 0 || offset < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer = nullptr;

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if((size_t)size + offset > buffer->size())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

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

-	}

-}

-

-GLenum CheckFramebufferStatus(GLenum target)

-{

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

-

-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)

-	{

-		return error(GL_INVALID_ENUM, 0);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Framebuffer *framebuffer = NULL;

-		if(target == GL_READ_FRAMEBUFFER_ANGLE)

-		{

-			framebuffer = context->getReadFramebuffer();

-		}

-		else

-		{

-			framebuffer = context->getDrawFramebuffer();

-		}

-

-		return framebuffer->completeness();

-	}

-

-	return 0;

-}

-

-void Clear(GLbitfield mask)

-{

-	TRACE("(GLbitfield mask = %X)", mask);

-

-	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->clear(mask);

-	}

-}

-

-void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",

-	      red, green, blue, alpha);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

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

-	}

-}

-

-void ClearDepthf(GLclampf depth)

-{

-	TRACE("(GLclampf depth = %f)", depth);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setClearDepth(depth);

-	}

-}

-

-void ClearStencil(GLint s)

-{

-	TRACE("(GLint s = %d)", s);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setClearStencil(s);

-	}

-}

-

-void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)

-{

-	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",

-	      red, green, blue, alpha);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);

-	}

-}

-

-void CompileShader(GLuint shader)

-{

-	TRACE("(GLuint shader = %d)", shader);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		shaderObject->compile();

-	}

-}

-

-void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                          GLint border, GLsizei imageSize, const GLvoid* data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "

-	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",

-	      target, level, internalformat, width, height, border, imageSize, data);

-

-	if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(internalformat)

-	{

-	case GL_DEPTH_COMPONENT:

-	case GL_DEPTH_COMPONENT16:

-	case GL_DEPTH_COMPONENT32_OES:

-	case GL_DEPTH_STENCIL_OES:

-	case GL_DEPTH24_STENCIL8_OES:

-		return error(GL_INVALID_OPERATION);

-	default:

-		{

-			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

-			if(validationError != GL_NONE)

-			{

-				return error(validationError);

-			}

-		}

-		break;

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-			if(width != height)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||

-			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es2::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);

-		}

-		else

-		{

-			es2::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			switch(target)

-			{

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

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

-				break;

-			default: UNREACHABLE(target);

-			}

-		}

-	}

-}

-

-void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                             GLenum format, GLsizei imageSize, const GLvoid* data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "

-	      "GLsizei imageSize = %d, const GLvoid* data = %p)",

-	      target, level, xoffset, yoffset, width, height, format, imageSize, data);

-

-	if(!es2::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

-	if(validationError != GL_NONE)

-	{

-		return error(validationError);

-	}

-

-	if(width == 0 || height == 0 || !data)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(imageSize != egl::ComputeCompressedSize(width, height, format))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(xoffset % 4 != 0 || yoffset % 4 != 0)

-		{

-			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es2::Texture2D *texture = context->getTexture2D();

-

-			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

-

-			if(validationError == GL_NONE)

-			{

-				texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);

-			}

-			else

-			{

-				return error(validationError);

-			}

-		}

-		else if(es2::IsCubemapTextureTarget(target))

-		{

-			es2::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

-

-			if(validationError == GL_NONE)

-			{

-				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);

-			}

-			else

-			{

-				return error(validationError);

-			}

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "

-	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",

-	      target, level, internalformat, x, y, width, height, border);

-

-	if(!validImageSize(level, width, height))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-			if(width != height)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||

-			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-		}

-

-		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();

-

-		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLenum colorbufferFormat = source->getFormat();

-

-		if(!validateColorBufferFormat(internalformat, colorbufferFormat))

-		{

-			return;

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es2::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);

-		}

-		else if(es2::IsCubemapTextureTarget(target))

-		{

-			es2::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

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

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",

-	      target, level, xoffset, yoffset, x, y, width, height);

-

-	if(!es2::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(width == 0 || height == 0)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-		}

-

-		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();

-

-		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		es2::Texture *texture = nullptr;

-

-		if(target == GL_TEXTURE_2D)

-		{

-			texture = context->getTexture2D();

-		}

-		else if(es2::IsCubemapTextureTarget(target))

-		{

-			texture = context->getTextureCubeMap();

-		}

-		else UNREACHABLE(target);

-

-		GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);

-		if(validationError != GL_NONE)

-		{

-			return error(validationError);

-		}

-

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

-	}

-}

-

-GLuint CreateProgram(void)

-{

-	TRACE("()");

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		return context->createProgram();

-	}

-

-	return 0;

-}

-

-GLuint CreateShader(GLenum type)

-{

-	TRACE("(GLenum type = 0x%X)", type);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(type)

-		{

-		case GL_FRAGMENT_SHADER:

-		case GL_VERTEX_SHADER:

-			return context->createShader(type);

-		default:

-			return error(GL_INVALID_ENUM, 0);

-		}

-	}

-

-	return 0;

-}

-

-void CullFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		{

-			es2::Context *context = es2::getContext();

-

-			if(context)

-			{

-				context->setCullMode(mode);

-			}

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void DeleteBuffers(GLsizei n, const GLuint* buffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteBuffer(buffers[i]);

-		}

-	}

-}

-

-void DeleteFencesNV(GLsizei n, const GLuint* fences)

-{

-	TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteFence(fences[i]);

-		}

-	}

-}

-

-void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			if(framebuffers[i] != 0)

-			{

-				context->deleteFramebuffer(framebuffers[i]);

-			}

-		}

-	}

-}

-

-void DeleteProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	if(program == 0)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->getProgram(program))

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		context->deleteProgram(program);

-	}

-}

-

-void DeleteQueriesEXT(GLsizei n, const GLuint *ids)

-{

-	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteQuery(ids[i]);

-		}

-	}

-}

-

-void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteRenderbuffer(renderbuffers[i]);

-		}

-	}

-}

-

-void DeleteShader(GLuint shader)

-{

-	TRACE("(GLuint shader = %d)", shader);

-

-	if(shader == 0)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->getShader(shader))

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		context->deleteShader(shader);

-	}

-}

-

-void DeleteTextures(GLsizei n, const GLuint* textures)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			if(textures[i] != 0)

-			{

-				context->deleteTexture(textures[i]);

-			}

-		}

-	}

-}

-

-void DepthFunc(GLenum func)

-{

-	TRACE("(GLenum func = 0x%X)", func);

-

-	switch(func)

-	{

-	case GL_NEVER:

-	case GL_ALWAYS:

-	case GL_LESS:

-	case GL_LEQUAL:

-	case GL_EQUAL:

-	case GL_GREATER:

-	case GL_GEQUAL:

-	case GL_NOTEQUAL:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setDepthFunc(func);

-	}

-}

-

-void DepthMask(GLboolean flag)

-{

-	TRACE("(GLboolean flag = %d)", flag);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setDepthMask(flag != GL_FALSE);

-	}

-}

-

-void DepthRangef(GLclampf zNear, GLclampf zFar)

-{

-	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setDepthRange(zNear, zFar);

-	}

-}

-

-void DetachShader(GLuint program, GLuint shader)

-{

-	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-

-		es2::Program *programObject = context->getProgram(program);

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(!programObject)

-		{

-			es2::Shader *shaderByProgramHandle;

-			shaderByProgramHandle = context->getShader(program);

-			if(!shaderByProgramHandle)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		}

-

-		if(!shaderObject)

-		{

-			es2::Program *programByShaderHandle = context->getProgram(shader);

-			if(!programByShaderHandle)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		}

-

-		if(!programObject->detachShader(shaderObject))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Disable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(cap)

-		{

-		case GL_CULL_FACE:                     context->setCullFaceEnabled(false);                   break;

-		case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(false);          break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(false);      break;

-		case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(false);             break;

-		case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(false);                break;

-		case GL_STENCIL_TEST:                  context->setStencilTestEnabled(false);                break;

-		case GL_DEPTH_TEST:                    context->setDepthTestEnabled(false);                  break;

-		case GL_BLEND:                         context->setBlendEnabled(false);                      break;

-		case GL_DITHER:                        context->setDitherEnabled(false);                     break;

-		case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;

-		case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(false);          break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void DisableVertexAttribArray(GLuint index)

-{

-	TRACE("(GLuint index = %d)", index);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribArrayEnabled(index, false);

-	}

-}

-

-void DrawArrays(GLenum mode, GLint first, GLsizei count)

-{

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

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0 || first < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->drawArrays(mode, first, count);

-	}

-}

-

-void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)

-{

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

-	      mode, count, type, indices);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT:

-		case GL_UNSIGNED_INT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

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

-	}

-}

-

-void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)

-{

-	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",

-		mode, first, count, instanceCount);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0 || instanceCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->drawArrays(mode, first, count, instanceCount);

-	}

-}

-

-void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)

-{

-	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",

-		mode, count, type, indices, instanceCount);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(type)

-	{

-	case GL_UNSIGNED_BYTE:

-	case GL_UNSIGNED_SHORT:

-	case GL_UNSIGNED_INT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0 || instanceCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);

-	}

-}

-

-void VertexAttribDivisorEXT(GLuint index, GLuint divisor)

-{

-	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= es2::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		context->setVertexAttribDivisor(index, divisor);

-	}

-}

-

-void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)

-{

-	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",

-		mode, first, count, instanceCount);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0 || instanceCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->hasZeroDivisor())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->drawArrays(mode, first, count, instanceCount);

-	}

-}

-

-void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)

-{

-	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",

-		mode, count, type, indices, instanceCount);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(type)

-	{

-	case GL_UNSIGNED_BYTE:

-	case GL_UNSIGNED_SHORT:

-	case GL_UNSIGNED_INT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0 || instanceCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->hasZeroDivisor())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);

-	}

-}

-

-void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)

-{

-	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		context->setVertexAttribDivisor(index, divisor);

-	}

-}

-

-void Enable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(cap)

-		{

-		case GL_CULL_FACE:                     context->setCullFaceEnabled(true);                   break;

-		case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(true);          break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(true);      break;

-		case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(true);             break;

-		case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(true);                break;

-		case GL_STENCIL_TEST:                  context->setStencilTestEnabled(true);                break;

-		case GL_DEPTH_TEST:                    context->setDepthTestEnabled(true);                  break;

-		case GL_BLEND:                         context->setBlendEnabled(true);                      break;

-		case GL_DITHER:                        context->setDitherEnabled(true);                     break;

-		case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;

-		case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(true);          break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void EnableVertexAttribArray(GLuint index)

-{

-	TRACE("(GLuint index = %d)", index);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribArrayEnabled(index, true);

-	}

-}

-

-void EndQueryEXT(GLenum target)

-{

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

-

-	switch(target)

-	{

-	case GL_ANY_SAMPLES_PASSED_EXT:

-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->endQuery(target);

-	}

-}

-

-void FinishFenceNV(GLuint fence)

-{

-	TRACE("(GLuint fence = %d)", fence);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Fence* fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		fenceObject->finishFence();

-	}

-}

-

-void Finish(void)

-{

-	TRACE("()");

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->finish();

-	}

-}

-

-void Flush(void)

-{

-	TRACE("()");

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->flush();

-	}

-}

-

-void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "

-	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);

-

-	if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||

-	   (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Framebuffer *framebuffer = NULL;

-		GLuint framebufferName = 0;

-		if(target == GL_READ_FRAMEBUFFER_ANGLE)

-		{

-			framebuffer = context->getReadFramebuffer();

-			framebufferName = context->getReadFramebufferName();

-		}

-		else

-		{

-			framebuffer = context->getDrawFramebuffer();

-			framebufferName = context->getDrawFramebufferName();

-		}

-

-		if(!framebuffer || framebufferName == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		// [OpenGL ES 2.0.25] Section 4.4.3 page 112

-		// [OpenGL ES 3.0.2] Section 4.4.2 page 201

-		// 'renderbuffer' must be either zero or the name of an existing renderbuffer object of

-		// type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.

-		if(renderbuffer != 0)

-		{

-			if(!context->getRenderbuffer(renderbuffer))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		}

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0:

-		case GL_COLOR_ATTACHMENT1:

-		case GL_COLOR_ATTACHMENT2:

-		case GL_COLOR_ATTACHMENT3:

-		case GL_COLOR_ATTACHMENT4:

-		case GL_COLOR_ATTACHMENT5:

-		case GL_COLOR_ATTACHMENT6:

-		case GL_COLOR_ATTACHMENT7:

-		case GL_COLOR_ATTACHMENT8:

-		case GL_COLOR_ATTACHMENT9:

-		case GL_COLOR_ATTACHMENT10:

-		case GL_COLOR_ATTACHMENT11:

-		case GL_COLOR_ATTACHMENT12:

-		case GL_COLOR_ATTACHMENT13:

-		case GL_COLOR_ATTACHMENT14:

-		case GL_COLOR_ATTACHMENT15:

-		case GL_COLOR_ATTACHMENT16:

-		case GL_COLOR_ATTACHMENT17:

-		case GL_COLOR_ATTACHMENT18:

-		case GL_COLOR_ATTACHMENT19:

-		case GL_COLOR_ATTACHMENT20:

-		case GL_COLOR_ATTACHMENT21:

-		case GL_COLOR_ATTACHMENT22:

-		case GL_COLOR_ATTACHMENT23:

-		case GL_COLOR_ATTACHMENT24:

-		case GL_COLOR_ATTACHMENT25:

-		case GL_COLOR_ATTACHMENT26:

-		case GL_COLOR_ATTACHMENT27:

-		case GL_COLOR_ATTACHMENT28:

-		case GL_COLOR_ATTACHMENT29:

-		case GL_COLOR_ATTACHMENT30:

-		case GL_COLOR_ATTACHMENT31:

-			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);

-			break;

-		case GL_DEPTH_ATTACHMENT:

-			framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);

-			break;

-		case GL_STENCIL_ATTACHMENT:

-			framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);

-			break;

-		case GL_DEPTH_STENCIL_ATTACHMENT:

-			if(clientVersion >= 3)

-			{

-				framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);

-				framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "

-	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);

-

-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(texture == 0)

-		{

-			textarget = GL_NONE;

-		}

-		else

-		{

-			es2::Texture *tex = context->getTexture(texture);

-

-			if(tex == NULL)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			switch(textarget)

-			{

-			case GL_TEXTURE_2D:

-				if(tex->getTarget() != GL_TEXTURE_2D)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(tex->isCompressed(textarget, level))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			if((level != 0) && (context->getClientVersion() < 3))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		es2::Framebuffer *framebuffer = NULL;

-		GLuint framebufferName = 0;

-		if(target == GL_READ_FRAMEBUFFER_ANGLE)

-		{

-			framebuffer = context->getReadFramebuffer();

-			framebufferName = context->getReadFramebufferName();

-		}

-		else

-		{

-			framebuffer = context->getDrawFramebuffer();

-			framebufferName = context->getDrawFramebufferName();

-		}

-

-		if(framebufferName == 0 || !framebuffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0:

-		case GL_COLOR_ATTACHMENT1:

-		case GL_COLOR_ATTACHMENT2:

-		case GL_COLOR_ATTACHMENT3:

-		case GL_COLOR_ATTACHMENT4:

-		case GL_COLOR_ATTACHMENT5:

-		case GL_COLOR_ATTACHMENT6:

-		case GL_COLOR_ATTACHMENT7:

-		case GL_COLOR_ATTACHMENT8:

-		case GL_COLOR_ATTACHMENT9:

-		case GL_COLOR_ATTACHMENT10:

-		case GL_COLOR_ATTACHMENT11:

-		case GL_COLOR_ATTACHMENT12:

-		case GL_COLOR_ATTACHMENT13:

-		case GL_COLOR_ATTACHMENT14:

-		case GL_COLOR_ATTACHMENT15:

-		case GL_COLOR_ATTACHMENT16:

-		case GL_COLOR_ATTACHMENT17:

-		case GL_COLOR_ATTACHMENT18:

-		case GL_COLOR_ATTACHMENT19:

-		case GL_COLOR_ATTACHMENT20:

-		case GL_COLOR_ATTACHMENT21:

-		case GL_COLOR_ATTACHMENT22:

-		case GL_COLOR_ATTACHMENT23:

-		case GL_COLOR_ATTACHMENT24:

-		case GL_COLOR_ATTACHMENT25:

-		case GL_COLOR_ATTACHMENT26:

-		case GL_COLOR_ATTACHMENT27:

-		case GL_COLOR_ATTACHMENT28:

-		case GL_COLOR_ATTACHMENT29:

-		case GL_COLOR_ATTACHMENT30:

-		case GL_COLOR_ATTACHMENT31:

-			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);

-			break;

-		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture, level);   break;

-		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void FrontFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_CW:

-	case GL_CCW:

-		{

-			es2::Context *context = es2::getContext();

-

-			if(context)

-			{

-				context->setFrontFace(mode);

-			}

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void GenBuffers(GLsizei n, GLuint* buffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			buffers[i] = context->createBuffer();

-		}

-	}

-}

-

-void GenerateMipmap(GLenum target)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture *texture = nullptr;

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		case GL_TEXTURE_2D_ARRAY:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			else

-			{

-				texture = context->getTexture2DArray();

-			}

-			break;

-		case GL_TEXTURE_3D_OES:

-			texture = context->getTexture3D();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->generateMipmaps();

-	}

-}

-

-void GenFencesNV(GLsizei n, GLuint* fences)

-{

-	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			fences[i] = context->createFence();

-		}

-	}

-}

-

-void GenFramebuffers(GLsizei n, GLuint* framebuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			framebuffers[i] = context->createFramebuffer();

-		}

-	}

-}

-

-void GenQueriesEXT(GLsizei n, GLuint* ids)

-{

-	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			ids[i] = context->createQuery();

-		}

-	}

-}

-

-void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			renderbuffers[i] = context->createRenderbuffer();

-		}

-	}

-}

-

-void GenTextures(GLsizei n, GLuint* textures)

-{

-	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			textures[i] = context->createTexture();

-		}

-	}

-}

-

-void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "

-	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",

-	      program, index, bufsize, length, size, type, name);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(index >= programObject->getActiveAttributeCount())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->getActiveAttribute(index, bufsize, length, size, type, name);

-	}

-}

-

-void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "

-	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",

-	      program, index, bufsize, length, size, type, name);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(index >= programObject->getActiveUniformCount())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->getActiveUniform(index, bufsize, length, size, type, name);

-	}

-}

-

-void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)

-{

-	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",

-	      program, maxcount, count, shaders);

-

-	if(maxcount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		return programObject->getAttachedShaders(maxcount, count, shaders);

-	}

-}

-

-int GetAttribLocation(GLuint program, const GLchar* name)

-{

-	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION, -1);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE, -1);

-			}

-		}

-

-		if(!programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION, -1);

-		}

-

-		return programObject->getAttributeLocation(name);

-	}

-

-	return -1;

-}

-

-void GetBooleanv(GLenum pname, GLboolean* params)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!(context->getBooleanv(pname, params)))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that the pname is valid, but there are no parameters to return

-

-			if(nativeType == GL_FLOAT)

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(floatParams[i] == 0.0f)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] floatParams;

-			}

-			else if(nativeType == GL_INT)

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(intParams[i] == 0)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] intParams;

-			}

-		}

-	}

-}

-

-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer;

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(pname)

-		{

-		case GL_BUFFER_USAGE:

-			*params = buffer->usage();

-			break;

-		case GL_BUFFER_SIZE:

-			*params = (GLint)buffer->size();

-			break;

-		case GL_BUFFER_ACCESS_FLAGS:

-			if(clientVersion >= 3)

-			{

-				*params = buffer->access();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_BUFFER_MAPPED:

-			if(clientVersion >= 3)

-			{

-				*params = buffer->isMapped();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_BUFFER_MAP_LENGTH:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)buffer->length();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_BUFFER_MAP_OFFSET:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)buffer->offset();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GLenum GetError(void)

-{

-	TRACE("()");

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		return context->getError();

-	}

-

-	return GL_NO_ERROR;

-}

-

-void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)

-{

-	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		fenceObject->getFenceiv(pname, params);

-	}

-}

-

-void GetFloatv(GLenum pname, GLfloat* params)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!(context->getFloatv(pname, params)))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that the pname is valid, but that there are no parameters to return.

-

-			if(nativeType == GL_BOOL)

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(boolParams[i] == GL_FALSE)

-						params[i] = 0.0f;

-					else

-						params[i] = 1.0f;

-				}

-

-				delete [] boolParams;

-			}

-			else if(nativeType == GL_INT)

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					params[i] = (GLfloat)intParams[i];

-				}

-

-				delete [] intParams;

-			}

-		}

-	}

-}

-

-void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",

-	      target, attachment, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		GLint clientVersion = context->getClientVersion();

-

-		es2::Framebuffer *framebuffer = nullptr;

-		if(target == GL_READ_FRAMEBUFFER)

-		{

-			if(context->getReadFramebufferName() == 0)

-			{

-				if(clientVersion < 3)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				else

-				{

-					switch(attachment)

-					{

-					case GL_BACK:

-					case GL_DEPTH:

-					case GL_STENCIL:

-						break;

-					default:

-						return error(GL_INVALID_ENUM);

-					}

-				}

-			}

-

-			framebuffer = context->getReadFramebuffer();

-		}

-		else

-		{

-			if(context->getDrawFramebufferName() == 0)

-			{

-				if(clientVersion < 3)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				else

-				{

-					switch(attachment)

-					{

-					case GL_BACK:

-					case GL_DEPTH:

-					case GL_STENCIL:

-						break;

-					default:

-						return error(GL_INVALID_ENUM);

-					}

-				}

-			}

-

-			framebuffer = context->getDrawFramebuffer();

-		}

-

-		GLenum attachmentType;

-		GLuint attachmentHandle;

-		GLint attachmentLayer;

-		Renderbuffer* renderbuffer = nullptr;

-		switch(attachment)

-		{

-		case GL_BACK:

-			if(clientVersion >= 3)

-			{

-				attachmentType = framebuffer->getColorbufferType(0);

-				attachmentHandle = framebuffer->getColorbufferName(0);

-				attachmentLayer = framebuffer->getColorbufferLayer(0);

-				renderbuffer = framebuffer->getColorbuffer(0);

-			}

-			else return error(GL_INVALID_ENUM);

-			break;

-		case GL_COLOR_ATTACHMENT0:

-		case GL_COLOR_ATTACHMENT1:

-		case GL_COLOR_ATTACHMENT2:

-		case GL_COLOR_ATTACHMENT3:

-		case GL_COLOR_ATTACHMENT4:

-		case GL_COLOR_ATTACHMENT5:

-		case GL_COLOR_ATTACHMENT6:

-		case GL_COLOR_ATTACHMENT7:

-		case GL_COLOR_ATTACHMENT8:

-		case GL_COLOR_ATTACHMENT9:

-		case GL_COLOR_ATTACHMENT10:

-		case GL_COLOR_ATTACHMENT11:

-		case GL_COLOR_ATTACHMENT12:

-		case GL_COLOR_ATTACHMENT13:

-		case GL_COLOR_ATTACHMENT14:

-		case GL_COLOR_ATTACHMENT15:

-		case GL_COLOR_ATTACHMENT16:

-		case GL_COLOR_ATTACHMENT17:

-		case GL_COLOR_ATTACHMENT18:

-		case GL_COLOR_ATTACHMENT19:

-		case GL_COLOR_ATTACHMENT20:

-		case GL_COLOR_ATTACHMENT21:

-		case GL_COLOR_ATTACHMENT22:

-		case GL_COLOR_ATTACHMENT23:

-		case GL_COLOR_ATTACHMENT24:

-		case GL_COLOR_ATTACHMENT25:

-		case GL_COLOR_ATTACHMENT26:

-		case GL_COLOR_ATTACHMENT27:

-		case GL_COLOR_ATTACHMENT28:

-		case GL_COLOR_ATTACHMENT29:

-		case GL_COLOR_ATTACHMENT30:

-		case GL_COLOR_ATTACHMENT31:

-			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);

-			attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);

-			attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);

-			renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);

-			break;

-		case GL_DEPTH:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			// fall through

-		case GL_DEPTH_ATTACHMENT:

-			attachmentType = framebuffer->getDepthbufferType();

-			attachmentHandle = framebuffer->getDepthbufferName();

-			attachmentLayer = framebuffer->getDepthbufferLayer();

-			renderbuffer = framebuffer->getDepthbuffer();

-			break;

-		case GL_STENCIL:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			// fall through

-		case GL_STENCIL_ATTACHMENT:

-			attachmentType = framebuffer->getStencilbufferType();

-			attachmentHandle = framebuffer->getStencilbufferName();

-			attachmentLayer = framebuffer->getStencilbufferLayer();

-			renderbuffer = framebuffer->getStencilbuffer();

-			break;

-		case GL_DEPTH_STENCIL_ATTACHMENT:

-			if(clientVersion >= 3)

-			{

-				attachmentType = framebuffer->getDepthbufferType();

-				attachmentHandle = framebuffer->getDepthbufferName();

-				attachmentLayer = framebuffer->getDepthbufferLayer();

-				if(attachmentHandle != framebuffer->getStencilbufferName())

-				{

-					// Different attachments to DEPTH and STENCIL, query fails

-					return error(GL_INVALID_OPERATION);

-				}

-				renderbuffer = framebuffer->getDepthbuffer();

-			}

-			else return error(GL_INVALID_ENUM);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		GLenum attachmentObjectType = GL_NONE;   // Type category

-		if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))

-		{

-			attachmentObjectType = attachmentType;

-		}

-		else if(es2::IsTextureTarget(attachmentType))

-		{

-			attachmentObjectType = GL_TEXTURE;

-		}

-		else UNREACHABLE(attachmentType);

-

-		if(attachmentObjectType != GL_NONE)

-		{

-			switch(pname)

-			{

-			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:

-				*params = attachmentObjectType;

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:

-				if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE)

-				{

-					*params = attachmentHandle;

-				}

-				else

-				{

-					return error(GL_INVALID_ENUM);

-				}

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:

-				if(attachmentObjectType == GL_TEXTURE)

-				{

-					*params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0

-				}

-				else

-				{

-					return error(GL_INVALID_ENUM);

-				}

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:

-				if(attachmentObjectType == GL_TEXTURE)

-				{

-					if(es2::IsCubemapTextureTarget(attachmentType))

-					{

-						*params = attachmentType;

-					}

-					else

-					{

-						*params = 0;

-					}

-				}

-				else

-				{

-					return error(GL_INVALID_ENUM);

-				}

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:

-				if(clientVersion >= 3)

-				{

-					*params = attachmentLayer;

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:

-				if(clientVersion >= 3)

-				{

-					*params = renderbuffer->getRedSize();

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:

-				if(clientVersion >= 3)

-				{

-					*params = renderbuffer->getGreenSize();

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:

-				if(clientVersion >= 3)

-				{

-					*params = renderbuffer->getBlueSize();

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:

-				if(clientVersion >= 3)

-				{

-					*params = renderbuffer->getAlphaSize();

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:

-				if(clientVersion >= 3)

-				{

-					*params = renderbuffer->getDepthSize();

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:

-				if(clientVersion >= 3)

-				{

-					*params = renderbuffer->getStencilSize();

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:

-				if(clientVersion >= 3)

-				{

-					if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)

-					{

-						return error(GL_INVALID_OPERATION);

-					}

-

-					*params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:

-				if(clientVersion >= 3)

-				{

-					*params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added

-				}

-				else return error(GL_INVALID_ENUM);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-		}

-		else

-		{

-			// ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE

-			// is NONE, then querying any other pname will generate INVALID_ENUM.

-

-			// ES 3.0.2 spec pg 235 states that if the attachment type is none,

-			// GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an

-			// INVALID_OPERATION for all other pnames

-

-			switch(pname)

-			{

-			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:

-				*params = GL_NONE;

-				break;

-

-			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:

-				if(clientVersion < 3)

-				{

-					return error(GL_INVALID_ENUM);

-				}

-				*params = 0;

-				break;

-

-			default:

-				if(clientVersion < 3)

-				{

-					return error(GL_INVALID_ENUM);

-				}

-				else

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-			}

-		}

-	}

-}

-

-GLenum GetGraphicsResetStatusEXT(void)

-{

-	TRACE("()");

-

-	return GL_NO_ERROR;

-}

-

-void GetIntegerv(GLenum pname, GLint* params)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(!context)

-	{

-		// Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior

-		#ifdef __ANDROID__

-			ALOGI("expected_badness glGetIntegerv() called without current context.");

-		#else

-			ERR("glGetIntegerv() called without current context.");

-		#endif

-

-		// This is not spec compliant! When there is no current GL context, functions should

-		// have no side effects. Google Maps queries these values before creating a context,

-		// so we need this as a bug-compatible workaround.

-		switch(pname)

-		{

-		case GL_MAX_TEXTURE_SIZE:                 *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE;  return;

-		case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return;

-		case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;

-		case GL_STENCIL_BITS:                     *params = 8;                                     return;

-		case GL_ALIASED_LINE_WIDTH_RANGE:

-			params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;

-			params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;

-			return;

-		}

-	}

-

-	if(context)

-	{

-		if(!(context->getIntegerv(pname, params)))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that pname is valid, but there are no parameters to return

-

-			if(nativeType == GL_BOOL)

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;

-				}

-

-				delete [] boolParams;

-			}

-			else if(nativeType == GL_FLOAT)

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)

-					{

-						params[i] = es2::floatToInt(floatParams[i]);

-					}

-					else

-					{

-						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

-					}

-				}

-

-				delete [] floatParams;

-			}

-		}

-	}

-}

-

-void GetProgramiv(GLuint program, GLenum pname, GLint* params)

-{

-	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		GLint clientVersion = egl::getClientVersion();

-

-		switch(pname)

-		{

-		case GL_DELETE_STATUS:

-			*params = programObject->isFlaggedForDeletion();

-			return;

-		case GL_LINK_STATUS:

-			*params = programObject->isLinked();

-			return;

-		case GL_VALIDATE_STATUS:

-			*params = programObject->isValidated();

-			return;

-		case GL_INFO_LOG_LENGTH:

-			*params = (GLint)programObject->getInfoLogLength();

-			return;

-		case GL_ATTACHED_SHADERS:

-			*params = programObject->getAttachedShadersCount();

-			return;

-		case GL_ACTIVE_ATTRIBUTES:

-			*params = (GLint)programObject->getActiveAttributeCount();

-			return;

-		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:

-			*params = programObject->getActiveAttributeMaxLength();

-			return;

-		case GL_ACTIVE_UNIFORMS:

-			*params = (GLint)programObject->getActiveUniformCount();

-			return;

-		case GL_ACTIVE_UNIFORM_MAX_LENGTH:

-			*params = programObject->getActiveUniformMaxLength();

-			return;

-		case GL_ACTIVE_UNIFORM_BLOCKS:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)programObject->getActiveUniformBlockCount();

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:

-			if(clientVersion >= 3)

-			{

-				*params = programObject->getActiveUniformBlockMaxLength();

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:

-			if(clientVersion >= 3)

-			{

-				*params = programObject->getTransformFeedbackBufferMode();

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TRANSFORM_FEEDBACK_VARYINGS:

-			if(clientVersion >= 3)

-			{

-				*params = programObject->getTransformFeedbackVaryingCount();

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:

-			if(clientVersion >= 3)

-			{

-				*params = programObject->getTransformFeedbackVaryingMaxLength();

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:

-			if(clientVersion >= 3)

-			{

-				*params = programObject->getBinaryRetrievableHint();

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_PROGRAM_BINARY_LENGTH:

-			if(clientVersion >= 3)

-			{

-				*params = programObject->getBinaryLength();

-				return;

-			}

-			else return error(GL_INVALID_ENUM);

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)

-{

-	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",

-	      program, bufsize, length, infolog);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		programObject->getInfoLog(bufsize, length, infolog);

-	}

-}

-

-void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)

-{

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

-

-	switch(pname)

-	{

-	case GL_CURRENT_QUERY_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		params[0] = context->getActiveQuery(target);

-	}

-}

-

-void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)

-{

-	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);

-

-	switch(pname)

-	{

-	case GL_QUERY_RESULT_EXT:

-	case GL_QUERY_RESULT_AVAILABLE_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Query *queryObject = context->getQuery(name);

-

-		if(!queryObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(context->getActiveQuery(queryObject->getType()) == name)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_QUERY_RESULT_EXT:

-			params[0] = queryObject->getResult();

-			break;

-		case GL_QUERY_RESULT_AVAILABLE_EXT:

-			params[0] = queryObject->isResultAvailable();

-			break;

-		default:

-			ASSERT(false);

-		}

-	}

-}

-

-void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(target != GL_RENDERBUFFER)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(context->getRenderbufferName() == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-

-		switch(pname)

-		{

-		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;

-		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;

-		case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;

-		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;

-		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;

-		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;

-		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;

-		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;

-		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;

-		case GL_RENDERBUFFER_SAMPLES_ANGLE:   *params = renderbuffer->getSamples();     break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetShaderiv(GLuint shader, GLenum pname, GLint* params)

-{

-	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		switch(pname)

-		{

-		case GL_SHADER_TYPE:

-			*params = shaderObject->getType();

-			return;

-		case GL_DELETE_STATUS:

-			*params = shaderObject->isFlaggedForDeletion();

-			return;

-		case GL_COMPILE_STATUS:

-			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;

-			return;

-		case GL_INFO_LOG_LENGTH:

-			*params = (GLint)shaderObject->getInfoLogLength();

-			return;

-		case GL_SHADER_SOURCE_LENGTH:

-			*params = (GLint)shaderObject->getSourceLength();

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)

-{

-	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",

-	      shader, bufsize, length, infolog);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		shaderObject->getInfoLog(bufsize, length, infolog);

-	}

-}

-

-void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)

-{

-	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",

-	      shadertype, precisiontype, range, precision);

-

-	switch(shadertype)

-	{

-	case GL_VERTEX_SHADER:

-	case GL_FRAGMENT_SHADER:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(precisiontype)

-	{

-	case GL_LOW_FLOAT:

-	case GL_MEDIUM_FLOAT:

-	case GL_HIGH_FLOAT:

-		// IEEE 754 single-precision

-		range[0] = 127;

-		range[1] = 127;

-		*precision = 23;

-		break;

-	case GL_LOW_INT:

-	case GL_MEDIUM_INT:

-	case GL_HIGH_INT:

-		// Full integer precision is supported

-		range[0] = 31;

-		range[1] = 30;

-		*precision = 0;

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)

-{

-	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",

-	      shader, bufsize, length, source);

-

-	if(bufsize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		shaderObject->getSource(bufsize, length, source);

-	}

-}

-

-const GLubyte* GetString(GLenum name)

-{

-	TRACE("(GLenum name = 0x%X)", name);

-

-	switch(name)

-	{

-	case GL_VENDOR:

-		return (GLubyte*)"Google Inc.";

-	case GL_RENDERER:

-		return (GLubyte*)"Google SwiftShader";

-	case GL_VERSION:

-	{

-		es2::Context *context = es2::getContext();

-		return (context && (context->getClientVersion() >= 3)) ?

-		       (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :

-		       (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;

-	}

-	case GL_SHADING_LANGUAGE_VERSION:

-	{

-		es2::Context *context = es2::getContext();

-		return (context && (context->getClientVersion() >= 3)) ?

-		       (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :

-		       (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;

-	}

-	case GL_EXTENSIONS:

-	{

-		es2::Context *context = es2::getContext();

-		return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)NULL;

-	}

-	default:

-		return error(GL_INVALID_ENUM, (GLubyte*)NULL);

-	}

-}

-

-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture *texture;

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		case GL_TEXTURE_2D_ARRAY:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			else

-			{

-				texture = context->getTexture2DArray();

-			}

-			break;

-		case GL_TEXTURE_3D_OES:

-			texture = context->getTexture3D();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_MAG_FILTER:

-			*params = (GLfloat)texture->getMagFilter();

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			*params = (GLfloat)texture->getMinFilter();

-			break;

-		case GL_TEXTURE_WRAP_S:

-			*params = (GLfloat)texture->getWrapS();

-			break;

-		case GL_TEXTURE_WRAP_T:

-			*params = (GLfloat)texture->getWrapT();

-			break;

-		case GL_TEXTURE_WRAP_R_OES:

-			*params = (GLfloat)texture->getWrapR();

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			*params = texture->getMaxAnisotropy();

-			break;

-		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:

-			*params = (GLfloat)1;

-			break;

-		case GL_TEXTURE_BASE_LEVEL:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getBaseLevel();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_COMPARE_FUNC:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getCompareFunc();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_COMPARE_MODE:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getCompareMode();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_IMMUTABLE_FORMAT:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getImmutableFormat();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_IMMUTABLE_LEVELS:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getImmutableLevels();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_MAX_LEVEL:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getMaxLevel();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_MAX_LOD:

-			if(clientVersion >= 3)

-			{

-				*params = texture->getMaxLOD();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_MIN_LOD:

-			if(clientVersion >= 3)

-			{

-				*params = texture->getMinLOD();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_R:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getSwizzleR();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_G:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getSwizzleG();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_B:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getSwizzleB();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_A:

-			if(clientVersion >= 3)

-			{

-				*params = (GLfloat)texture->getSwizzleA();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture *texture;

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		case GL_TEXTURE_2D_ARRAY:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			else

-			{

-				texture = context->getTexture2DArray();

-			}

-			break;

-		case GL_TEXTURE_3D_OES:

-			texture = context->getTexture3D();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_MAG_FILTER:

-			*params = texture->getMagFilter();

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			*params = texture->getMinFilter();

-			break;

-		case GL_TEXTURE_WRAP_S:

-			*params = texture->getWrapS();

-			break;

-		case GL_TEXTURE_WRAP_T:

-			*params = texture->getWrapT();

-			break;

-		case GL_TEXTURE_WRAP_R_OES:

-			*params = texture->getWrapR();

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			*params = (GLint)texture->getMaxAnisotropy();

-			break;

-		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:

-			*params = 1;

-			break;

-		case GL_TEXTURE_BASE_LEVEL:

-			if(clientVersion >= 3)

-			{

-				*params = texture->getBaseLevel();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_COMPARE_FUNC:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getCompareFunc();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_COMPARE_MODE:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getCompareMode();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_IMMUTABLE_FORMAT:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getImmutableFormat();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_IMMUTABLE_LEVELS:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getImmutableLevels();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_MAX_LEVEL:

-			if(clientVersion >= 3)

-			{

-				*params = texture->getMaxLevel();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_MAX_LOD:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)roundf(texture->getMaxLOD());

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_MIN_LOD:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)roundf(texture->getMinLOD());

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_R:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getSwizzleR();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_G:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getSwizzleG();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_B:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getSwizzleB();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_TEXTURE_SWIZZLE_A:

-			if(clientVersion >= 3)

-			{

-				*params = (GLint)texture->getSwizzleA();

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",

-	      program, location, bufSize, params);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformfv(location, &bufSize, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void GetUniformfv(GLuint program, GLint location, GLfloat* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformfv(location, NULL, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",

-	      program, location, bufSize, params);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformiv(location, &bufSize, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void GetUniformiv(GLuint program, GLint location, GLint* params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformiv(location, NULL, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-int GetUniformLocation(GLuint program, const GLchar* name)

-{

-	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

-

-	es2::Context *context = es2::getContext();

-

-	if(strstr(name, "gl_") == name)

-	{

-		return -1;

-	}

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION, -1);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE, -1);

-			}

-		}

-

-		if(!programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION, -1);

-		}

-

-		return programObject->getUniformLocation(name);

-	}

-

-	return -1;

-}

-

-void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= es2::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(pname)

-		{

-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:

-			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:

-			*params = (GLfloat)attribState.mSize;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:

-			*params = (GLfloat)attribState.mStride;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:

-			*params = (GLfloat)attribState.mType;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:

-			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:

-			*params = (GLfloat)attribState.mBoundBuffer.name();

-			break;

-		case GL_CURRENT_VERTEX_ATTRIB:

-			{

-				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];

-				for(int i = 0; i < 4; ++i)

-				{

-					params[i] = attrib.getCurrentValueF(i);

-				}

-			}

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:

-			if(clientVersion >= 3)

-			{

-				switch(attribState.mType)

-				{

-				case GL_BYTE:

-				case GL_UNSIGNED_BYTE:

-				case GL_SHORT:

-				case GL_UNSIGNED_SHORT:

-				case GL_INT:

-				case GL_INT_2_10_10_10_REV:

-				case GL_UNSIGNED_INT:

-				case GL_FIXED:

-					*params = (GLfloat)GL_TRUE;

-					break;

-				default:

-					*params = (GLfloat)GL_FALSE;

-					break;

-				}

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		default: return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= es2::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(pname)

-		{

-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:

-			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:

-			*params = attribState.mSize;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:

-			*params = attribState.mStride;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:

-			*params = attribState.mType;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:

-			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:

-			*params = attribState.mBoundBuffer.name();

-			break;

-		case GL_CURRENT_VERTEX_ATTRIB:

-			{

-				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];

-				for(int i = 0; i < 4; ++i)

-				{

-					float currentValue = attrib.getCurrentValueF(i);

-					params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));

-				}

-			}

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:

-			if(clientVersion >= 3)

-			{

-				switch(attribState.mType)

-				{

-				case GL_BYTE:

-				case GL_UNSIGNED_BYTE:

-				case GL_SHORT:

-				case GL_UNSIGNED_SHORT:

-				case GL_INT:

-				case GL_INT_2_10_10_10_REV:

-				case GL_UNSIGNED_INT:

-				case GL_FIXED:

-					*params = GL_TRUE;

-					break;

-				default:

-					*params = GL_FALSE;

-					break;

-				}

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		default: return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= es2::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));

-	}

-}

-

-void Hint(GLenum target, GLenum mode)

-{

-	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);

-

-	switch(mode)

-	{

-	case GL_FASTEST:

-	case GL_NICEST:

-	case GL_DONT_CARE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-	switch(target)

-	{

-	case GL_GENERATE_MIPMAP_HINT:

-		if(context) context->setGenerateMipmapHint(mode);

-		break;

-	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:

-		if(context) context->setFragmentShaderDerivativeHint(mode);

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-GLboolean IsBuffer(GLuint buffer)

-{

-	TRACE("(GLuint buffer = %d)", buffer);

-

-	es2::Context *context = es2::getContext();

-

-	if(context && buffer)

-	{

-		es2::Buffer *bufferObject = context->getBuffer(buffer);

-

-		if(bufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsEnabled(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLint clientVersion = context->getClientVersion();

-

-		switch(cap)

-		{

-		case GL_CULL_FACE:                return context->isCullFaceEnabled();

-		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();

-		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();

-		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();

-		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();

-		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();

-		case GL_BLEND:                    return context->isBlendEnabled();

-		case GL_DITHER:                   return context->isDitherEnabled();

-		case GL_PRIMITIVE_RESTART_FIXED_INDEX:

-			if(clientVersion >= 3)

-			{

-				return context->isPrimitiveRestartFixedIndexEnabled();

-			}

-			else return error(GL_INVALID_ENUM, false);

-		case GL_RASTERIZER_DISCARD:

-			if(clientVersion >= 3)

-			{

-				return context->isRasterizerDiscardEnabled();

-			}

-			else return error(GL_INVALID_ENUM, false);

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-	}

-

-	return false;

-}

-

-GLboolean IsFenceNV(GLuint fence)

-{

-	TRACE("(GLuint fence = %d)", fence);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return GL_FALSE;

-		}

-

-		return fenceObject->isFence();

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsFramebuffer(GLuint framebuffer)

-{

-	TRACE("(GLuint framebuffer = %d)", framebuffer);

-

-	es2::Context *context = es2::getContext();

-

-	if(context && framebuffer)

-	{

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

-

-		if(framebufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	es2::Context *context = es2::getContext();

-

-	if(context && program)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(programObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsQueryEXT(GLuint name)

-{

-	TRACE("(GLuint name = %d)", name);

-

-	if(name == 0)

-	{

-		return GL_FALSE;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Query *queryObject = context->getQuery(name);

-

-		if(queryObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsRenderbuffer(GLuint renderbuffer)

-{

-	TRACE("(GLuint renderbuffer = %d)", renderbuffer);

-

-	es2::Context *context = es2::getContext();

-

-	if(context && renderbuffer)

-	{

-		es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);

-

-		if(renderbufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsShader(GLuint shader)

-{

-	TRACE("(GLuint shader = %d)", shader);

-

-	es2::Context *context = es2::getContext();

-

-	if(context && shader)

-	{

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(shaderObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsTexture(GLuint texture)

-{

-	TRACE("(GLuint texture = %d)", texture);

-

-	es2::Context *context = es2::getContext();

-

-	if(context && texture)

-	{

-		es2::Texture *textureObject = context->getTexture(texture);

-

-		if(textureObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-void LineWidth(GLfloat width)

-{

-	TRACE("(GLfloat width = %f)", width);

-

-	if(width <= 0.0f)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setLineWidth(width);

-	}

-}

-

-void LinkProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		programObject->link();

-	}

-}

-

-void PixelStorei(GLenum pname, GLint param)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLint clientVersion = context->getClientVersion();

-

-		switch(pname)

-		{

-		case GL_UNPACK_ALIGNMENT:

-			if(param != 1 && param != 2 && param != 4 && param != 8)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setUnpackAlignment(param);

-			break;

-		case GL_PACK_ALIGNMENT:

-			if(param != 1 && param != 2 && param != 4 && param != 8)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPackAlignment(param);

-			break;

-		case GL_PACK_ROW_LENGTH:

-			if(clientVersion >= 3)

-			{

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setPackRowLength(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_PACK_SKIP_PIXELS:

-			if(clientVersion >= 3)

-			{

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setPackSkipPixels(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_PACK_SKIP_ROWS:

-			if(clientVersion >= 3)

-			{

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setPackSkipRows(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_UNPACK_ROW_LENGTH:

-			if(clientVersion >= 3)

-			{

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setUnpackRowLength(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_UNPACK_IMAGE_HEIGHT:

-			if(clientVersion >= 3)

-			{

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setUnpackImageHeight(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_UNPACK_SKIP_PIXELS:

-			if(clientVersion >= 3)

-			{

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setUnpackSkipPixels(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_UNPACK_SKIP_ROWS:

-			if(clientVersion >= 3)

-			{

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setUnpackSkipRows(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		case GL_UNPACK_SKIP_IMAGES:

-			if(clientVersion >= 3) {

-				if(param < 0)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				context->setUnpackSkipImages(param);

-				break;

-			}

-			else return error(GL_INVALID_ENUM);

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PolygonOffset(GLfloat factor, GLfloat units)

-{

-	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setPolygonOffsetParams(factor, units);

-	}

-}

-

-void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,

-                    GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",

-	      x, y, width, height, format, type, bufSize, data);

-

-	if(width < 0 || height < 0 || bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->readPixels(x, y, width, height, format, type, &bufSize, data);

-	}

-}

-

-void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",

-	      x, y, width, height, format, type,  pixels);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->readPixels(x, y, width, height, format, type, NULL, pixels);

-	}

-}

-

-void ReleaseShaderCompiler(void)

-{

-	TRACE("()");

-

-	es2::Shader::releaseCompiler();

-}

-

-void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",

-	      target, samples, internalformat, width, height);

-

-	switch(target)

-	{

-	case GL_RENDERBUFFER:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width < 0 || height < 0 || samples < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   samples > es2::IMPLEMENTATION_MAX_SAMPLES)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		GLuint handle = context->getRenderbufferName();

-		if(handle == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLint clientVersion = context->getClientVersion();

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT32F:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			// fall through

-		case GL_DEPTH_COMPONENT16:

-		case GL_DEPTH_COMPONENT24:

-		case GL_DEPTH_COMPONENT32_OES:

-			context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));

-			break;

-		case GL_R8:

-		case GL_R8UI:

-		case GL_R8I:

-		case GL_R16UI:

-		case GL_R16I:

-		case GL_R32UI:

-		case GL_R32I:

-		case GL_RG8:

-		case GL_RG8UI:

-		case GL_RG8I:

-		case GL_RG16UI:

-		case GL_RG16I:

-		case GL_RG32UI:

-		case GL_RG32I:

-		case GL_SRGB8_ALPHA8:

-		case GL_RGB10_A2:

-		case GL_RGBA8UI:

-		case GL_RGBA8I:

-		case GL_RGB10_A2UI:

-		case GL_RGBA16UI:

-		case GL_RGBA16I:

-		case GL_RGBA32I:

-		case GL_RGBA32UI:

-		case GL_R11F_G11F_B10F:

-		case GL_R32F:

-		case GL_RG32F:

-		case GL_RGB32F:

-		case GL_RGBA32F:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			// fall through

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-		case GL_R16F:

-		case GL_RG16F:

-		case GL_RGB16F:

-		case GL_RGBA16F:

-			context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));

-			break;

-		case GL_STENCIL_INDEX8:

-			context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));

-			break;

-		case GL_DEPTH32F_STENCIL8:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			// fall through

-		case GL_DEPTH24_STENCIL8_OES:

-			context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);

-}

-

-void SampleCoverage(GLclampf value, GLboolean invert)

-{

-	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

-

-	es2::Context* context = es2::getContext();

-

-	if(context)

-	{

-		context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);

-	}

-}

-

-void SetFenceNV(GLuint fence, GLenum condition)

-{

-	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);

-

-	if(condition != GL_ALL_COMPLETED_NV)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		fenceObject->setFence(condition);

-	}

-}

-

-void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context* context = es2::getContext();

-

-	if(context)

-	{

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

-	}

-}

-

-void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)

-{

-	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "

-	      "const GLvoid* binary = %p, GLsizei length = %d)",

-	      n, shaders, binaryformat, binary, length);

-

-	// No binary shader formats are supported.

-	return error(GL_INVALID_ENUM);

-}

-

-void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)

-{

-	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",

-	      shader, count, string, length);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Shader *shaderObject = context->getShader(shader);

-

-		if(!shaderObject)

-		{

-			if(context->getProgram(shader))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		shaderObject->setSource(count, string, length);

-	}

-}

-

-void StencilFunc(GLenum func, GLint ref, GLuint mask)

-{

-	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);

-}

-

-void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)

-{

-	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);

-

-	switch(face)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(func)

-	{

-	case GL_NEVER:

-	case GL_ALWAYS:

-	case GL_LESS:

-	case GL_LEQUAL:

-	case GL_EQUAL:

-	case GL_GEQUAL:

-	case GL_GREATER:

-	case GL_NOTEQUAL:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilParams(func, ref, mask);

-		}

-

-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilBackParams(func, ref, mask);

-		}

-	}

-}

-

-void StencilMask(GLuint mask)

-{

-	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);

-}

-

-void StencilMaskSeparate(GLenum face, GLuint mask)

-{

-	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);

-

-	switch(face)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilWritemask(mask);

-		}

-

-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilBackWritemask(mask);

-		}

-	}

-}

-

-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)

-{

-	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);

-}

-

-void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)

-{

-	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",

-	      face, fail, zfail, zpass);

-

-	switch(face)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(fail)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP:

-	case GL_DECR_WRAP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(zfail)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP:

-	case GL_DECR_WRAP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(zpass)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP:

-	case GL_DECR_WRAP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilOperations(fail, zfail, zpass);

-		}

-

-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)

-		{

-			context->setStencilBackOperations(fail, zfail, zpass);

-		}

-	}

-}

-

-GLboolean TestFenceNV(GLuint fence)

-{

-	TRACE("(GLuint fence = %d)", fence);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Fence *fenceObject = context->getFence(fence);

-

-		if(fenceObject == NULL)

-		{

-			return error(GL_INVALID_OPERATION, GL_TRUE);

-		}

-

-		return fenceObject->testFence();

-	}

-

-	return GL_TRUE;

-}

-

-void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "

-	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",

-	      target, level, internalformat, width, height, border, format, type, pixels);

-

-	if(!validImageSize(level, width, height))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLint clientVersion = context->getClientVersion();

-		if(clientVersion < 3)

-		{

-			if(internalformat != (GLint)format)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		}

-

-		GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);

-		if(validationError != GL_NONE)

-		{

-			return error(validationError);

-		}

-

-		if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))

-		{

-			return;

-		}

-

-		if(border != 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:

-			if(width != height)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||

-			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es2::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

-		}

-		else

-		{

-			es2::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

-		}

-	}

-}

-

-void TexParameterf(GLenum target, GLenum pname, GLfloat param)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture *texture;

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_2D_ARRAY:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			else

-			{

-				texture = context->getTexture2DArray();

-			}

-			break;

-		case GL_TEXTURE_3D_OES:

-			texture = context->getTexture3D();

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_WRAP_S:

-			if(!texture->setWrapS((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_T:

-			if(!texture->setWrapT((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_R_OES:

-			if(!texture->setWrapR((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			if(!texture->setMinFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAG_FILTER:

-			if(!texture->setMagFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			if(!texture->setMaxAnisotropy(param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_BASE_LEVEL:

-			if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_COMPARE_FUNC:

-			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_COMPARE_MODE:

-			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MAX_LEVEL:

-			if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MAX_LOD:

-			if(clientVersion < 3 || !texture->setMaxLOD(param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MIN_LOD:

-			if(clientVersion < 3 || !texture->setMinLOD(param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_R:

-			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_G:

-			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_B:

-			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_A:

-			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)

-{

-	glTexParameterf(target, pname, *params);

-}

-

-void TexParameteri(GLenum target, GLenum pname, GLint param)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture *texture;

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_2D_ARRAY:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			else

-			{

-				texture = context->getTexture2DArray();

-			}

-			break;

-		case GL_TEXTURE_3D_OES:

-			texture = context->getTexture3D();

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-			texture = context->getTextureCubeMap();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_WRAP_S:

-			if(!texture->setWrapS((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_T:

-			if(!texture->setWrapT((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_WRAP_R_OES:

-			if(!texture->setWrapR((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MIN_FILTER:

-			if(!texture->setMinFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAG_FILTER:

-			if(!texture->setMagFilter((GLenum)param))

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-			if(!texture->setMaxAnisotropy((GLfloat)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_BASE_LEVEL:

-			if(clientVersion < 3 || !texture->setBaseLevel(param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_COMPARE_FUNC:

-			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_COMPARE_MODE:

-			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MAX_LEVEL:

-			if(clientVersion < 3 || !texture->setMaxLevel(param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MAX_LOD:

-			if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_MIN_LOD:

-			if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_R:

-			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_G:

-			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_B:

-			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		case GL_TEXTURE_SWIZZLE_A:

-			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameteriv(GLenum target, GLenum pname, const GLint* params)

-{

-	glTexParameteri(target, pname, *params);

-}

-

-void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                   GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "

-	      "const GLvoid* pixels = %p)",

-	      target, level, xoffset, yoffset, width, height, format, type, pixels);

-

-	if(!es2::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))

-	{

-		return;

-	}

-

-	if(width == 0 || height == 0 || !pixels)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es2::Texture2D *texture = context->getTexture2D();

-

-			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

-

-			if(validationError == GL_NONE)

-			{

-				texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

-			}

-			else

-			{

-				return error(validationError);

-			}

-		}

-		else if(es2::IsCubemapTextureTarget(target))

-		{

-			es2::TextureCubeMap *texture = context->getTextureCubeMap();

-

-			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);

-

-			if(validationError == GL_NONE)

-			{

-				texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

-			}

-			else

-			{

-				return error(validationError);

-			}

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void Uniform1f(GLint location, GLfloat x)

-{

-	glUniform1fv(location, 1, &x);

-}

-

-void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform1fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Uniform1i(GLint location, GLint x)

-{

-	glUniform1iv(location, 1, &x);

-}

-

-void Uniform1iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform1iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Uniform2f(GLint location, GLfloat x, GLfloat y)

-{

-	GLfloat xy[2] = {x, y};

-

-	glUniform2fv(location, 1, (GLfloat*)&xy);

-}

-

-void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform2fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Uniform2i(GLint location, GLint x, GLint y)

-{

-	GLint xy[4] = {x, y};

-

-	glUniform2iv(location, 1, (GLint*)&xy);

-}

-

-void Uniform2iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform2iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)

-{

-	GLfloat xyz[3] = {x, y, z};

-

-	glUniform3fv(location, 1, (GLfloat*)&xyz);

-}

-

-void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform3fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Uniform3i(GLint location, GLint x, GLint y, GLint z)

-{

-	GLint xyz[3] = {x, y, z};

-

-	glUniform3iv(location, 1, (GLint*)&xyz);

-}

-

-void Uniform3iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform3iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	GLfloat xyzw[4] = {x, y, z, w};

-

-	glUniform4fv(location, 1, (GLfloat*)&xyzw);

-}

-

-void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform4fv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)

-{

-	GLint xyzw[4] = {x, y, z, w};

-

-	glUniform4iv(location, 1, (GLint*)&xyzw);

-}

-

-void Uniform4iv(GLint location, GLsizei count, const GLint* v)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform4iv(location, count, v))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",

-	      location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(context->getClientVersion() < 3 && transpose != GL_FALSE)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix2fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",

-	      location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(context->getClientVersion() < 3 && transpose != GL_FALSE)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix3fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",

-	      location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(context->getClientVersion() < 3 && transpose != GL_FALSE)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix4fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-void UseProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject && program != 0)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if(program != 0 && !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->useProgram(program);

-	}

-}

-

-void ValidateProgram(GLuint program)

-{

-	TRACE("(GLuint program = %d)", program);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		programObject->validate();

-	}

-}

-

-void VertexAttrib1f(GLuint index, GLfloat x)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLfloat vals[4] = { x, 0, 0, 1 };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-void VertexAttrib1fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLfloat vals[4] = { values[0], 0, 0, 1 };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLfloat vals[4] = { x, y, 0, 1 };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-void VertexAttrib2fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLfloat vals[4] = { values[0], values[1], 0, 1 };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLfloat vals[4] = { x, y, z, 1 };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-void VertexAttrib3fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLfloat vals[4] = { values[0], values[1], values[2], 1 };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLfloat vals[4] = { x, y, z, w };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-void VertexAttrib4fv(GLuint index, const GLfloat* values)

-{

-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setVertexAttrib(index, values);

-	}

-}

-

-void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)

-{

-	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "

-	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",

-	      index, size, type, normalized, stride, ptr);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(size < 1 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	GLint clientVersion = egl::getClientVersion();

-

-	switch(type)

-	{

-	case GL_BYTE:

-	case GL_UNSIGNED_BYTE:

-	case GL_SHORT:

-	case GL_UNSIGNED_SHORT:

-	case GL_FIXED:

-	case GL_FLOAT:

-		break;

-	case GL_INT_2_10_10_10_REV:

-	case GL_UNSIGNED_INT_2_10_10_10_REV:

-		if(clientVersion >= 3)

-		{

-			if(size != 4)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		}

-		else return error(GL_INVALID_ENUM);

-	case GL_INT:

-	case GL_UNSIGNED_INT:

-	case GL_HALF_FLOAT:

-		if(clientVersion >= 3)

-		{

-			break;

-		}

-		else return error(GL_INVALID_ENUM);

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(stride < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);

-	}

-}

-

-void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

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

-	}

-}

-

-void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)

-{

-	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "

-	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "

-	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",

-	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);

-

-	switch(filter)

-	{

-	case GL_NEAREST:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(context->getReadFramebufferName() == context->getDrawFramebufferName())

-		{

-			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);

-	}

-}

-

-void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                          GLbitfield mask, GLenum filter)

-{

-	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)

-	{

-		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");

-		return error(GL_INVALID_OPERATION);

-	}

-

-	glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);

-}

-

-void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,

-                   GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "

-	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",

-	      target, level, internalformat, width, height, depth, border, format, type, pixels);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D_OES:

-		switch(format)

-		{

-		case GL_DEPTH_COMPONENT:

-		case GL_DEPTH_STENCIL_OES:

-			return error(GL_INVALID_OPERATION);

-		default:

-			break;

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))

-	{

-		return;

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;

-	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = context->getTexture3D();

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);

-	}

-}

-

-void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",

-	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))

-	{

-		return;

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if((width < 0) || (height < 0) || (depth < 0))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = context->getTexture3D();

-

-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

-

-		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);

-		if(validationError == GL_NONE)

-		{

-			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

-		}

-		else

-		{

-			return error(validationError);

-		}

-	}

-}

-

-void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",

-	      target, level, xoffset, yoffset, zoffset, x, y, width, height);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-		}

-

-		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();

-

-		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		es2::Texture3D *texture = context->getTexture3D();

-

-		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);

-

-		if(validationError != GL_NONE)

-		{

-			return error(validationError);

-		}

-

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

-	}

-}

-

-void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "

-	      "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",

-	      target, level, internalformat, width, height, depth, border, imageSize, data);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;

-	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(internalformat)

-	{

-	case GL_DEPTH_COMPONENT:

-	case GL_DEPTH_COMPONENT16:

-	case GL_DEPTH_COMPONENT32_OES:

-	case GL_DEPTH_STENCIL_OES:

-	case GL_DEPTH24_STENCIL8_OES:

-		return error(GL_INVALID_OPERATION);

-	default:

-		{

-			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

-			if(validationError != GL_NONE)

-			{

-				return error(validationError);

-			}

-		}

-	}

-

-	if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = context->getTexture3D();

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);

-	}

-}

-

-void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "

-	      "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",

-	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

-	if(validationError != GL_NONE)

-	{

-		return error(validationError);

-	}

-

-	if(width == 0 || height == 0 || depth == 0 || !data)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = context->getTexture3D();

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);

-	}

-}

-

-void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "

-	      "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);

-

-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(texture == 0)

-		{

-			textarget = GL_NONE;

-		}

-		else

-		{

-			es2::Texture *tex = context->getTexture(texture);

-

-			if(tex == NULL)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			if(tex->isCompressed(textarget, level))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			switch(textarget)

-			{

-			case GL_TEXTURE_3D_OES:

-				if(tex->getTarget() != GL_TEXTURE_3D_OES)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(level != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		es2::Framebuffer *framebuffer = NULL;

-		GLuint framebufferName = 0;

-		if(target == GL_READ_FRAMEBUFFER_ANGLE)

-		{

-			framebuffer = context->getReadFramebuffer();

-			framebufferName = context->getReadFramebufferName();

-		}

-		else

-		{

-			framebuffer = context->getDrawFramebuffer();

-			framebufferName = context->getDrawFramebufferName();

-		}

-

-		if(framebufferName == 0 || !framebuffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLint clientVersion = context->getClientVersion();

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT1:

-		case GL_COLOR_ATTACHMENT2:

-		case GL_COLOR_ATTACHMENT3:

-		case GL_COLOR_ATTACHMENT4:

-		case GL_COLOR_ATTACHMENT5:

-		case GL_COLOR_ATTACHMENT6:

-		case GL_COLOR_ATTACHMENT7:

-		case GL_COLOR_ATTACHMENT8:

-		case GL_COLOR_ATTACHMENT9:

-		case GL_COLOR_ATTACHMENT10:

-		case GL_COLOR_ATTACHMENT11:

-		case GL_COLOR_ATTACHMENT12:

-		case GL_COLOR_ATTACHMENT13:

-		case GL_COLOR_ATTACHMENT14:

-		case GL_COLOR_ATTACHMENT15:

-		case GL_COLOR_ATTACHMENT16:

-		case GL_COLOR_ATTACHMENT17:

-		case GL_COLOR_ATTACHMENT18:

-		case GL_COLOR_ATTACHMENT19:

-		case GL_COLOR_ATTACHMENT20:

-		case GL_COLOR_ATTACHMENT21:

-		case GL_COLOR_ATTACHMENT22:

-		case GL_COLOR_ATTACHMENT23:

-		case GL_COLOR_ATTACHMENT24:

-		case GL_COLOR_ATTACHMENT25:

-		case GL_COLOR_ATTACHMENT26:

-		case GL_COLOR_ATTACHMENT27:

-		case GL_COLOR_ATTACHMENT28:

-		case GL_COLOR_ATTACHMENT29:

-		case GL_COLOR_ATTACHMENT30:

-		case GL_COLOR_ATTACHMENT31:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			// fall through

-		case GL_COLOR_ATTACHMENT0:

-			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);

-			break;

-		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;

-		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)

-{

-	if(egl::getClientVersion() == 1)

-	{

-		return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);

-	}

-

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

-

-	switch(target)

-	{

-	case GL_TEXTURE_2D:

-	case GL_TEXTURE_EXTERNAL_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture2D *texture = 0;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;

-		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;

-		default:                      UNREACHABLE(target);

-		}

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		egl::Image *glImage = static_cast<egl::Image*>(image);

-

-		texture->setImage(glImage);

-	}

-}

-

-void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)

-{

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

-

-	UNIMPLEMENTED();

-}

-

-GLboolean IsRenderbufferOES(GLuint renderbuffer)

-{

-	return IsRenderbuffer(renderbuffer);

-}

-

-void BindRenderbufferOES(GLenum target, GLuint renderbuffer)

-{

-	BindRenderbuffer(target, renderbuffer);

-}

-

-void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)

-{

-	DeleteRenderbuffers(n, renderbuffers);

-}

-

-void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)

-{

-	GenRenderbuffers(n, renderbuffers);

-}

-

-void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	RenderbufferStorage(target, internalformat, width, height);

-}

-

-void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)

-{

-	GetRenderbufferParameteriv(target, pname, params);

-}

-

-GLboolean IsFramebufferOES(GLuint framebuffer)

-{

-	return IsFramebuffer(framebuffer);

-}

-

-void BindFramebufferOES(GLenum target, GLuint framebuffer)

-{

-	BindFramebuffer(target, framebuffer);

-}

-

-void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)

-{

-	DeleteFramebuffers(n, framebuffers);

-}

-

-void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)

-{

-	GenFramebuffers(n, framebuffers);

-}

-

-GLenum CheckFramebufferStatusOES(GLenum target)

-{

-	return CheckFramebufferStatus(target);

-}

-

-void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);

-}

-

-void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	FramebufferTexture2D(target, attachment, textarget, texture, level);

-}

-

-void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	GetFramebufferAttachmentParameteriv(target, attachment, pname, params);

-}

-

-void GenerateMipmapOES(GLenum target)

-{

-	GenerateMipmap(target);

-}

-

-void DrawBuffersEXT(GLsizei n, const GLenum *bufs)

-{

-	TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);

-

-	if(n < 0 || n > MAX_DRAW_BUFFERS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLuint drawFramebufferName = context->getDrawFramebufferName();

-

-		if((drawFramebufferName == 0) && (n != 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		for(unsigned int i = 0; i < (unsigned)n; i++)

-		{

-			switch(bufs[i])

-			{

-			case GL_BACK:

-				if(drawFramebufferName != 0)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			case GL_NONE:

-				break;

-			case GL_COLOR_ATTACHMENT0_EXT:

-			case GL_COLOR_ATTACHMENT1_EXT:

-			case GL_COLOR_ATTACHMENT2_EXT:

-			case GL_COLOR_ATTACHMENT3_EXT:

-			case GL_COLOR_ATTACHMENT4_EXT:

-			case GL_COLOR_ATTACHMENT5_EXT:

-			case GL_COLOR_ATTACHMENT6_EXT:

-			case GL_COLOR_ATTACHMENT7_EXT:

-			case GL_COLOR_ATTACHMENT8_EXT:

-			case GL_COLOR_ATTACHMENT9_EXT:

-			case GL_COLOR_ATTACHMENT10_EXT:

-			case GL_COLOR_ATTACHMENT11_EXT:

-			case GL_COLOR_ATTACHMENT12_EXT:

-			case GL_COLOR_ATTACHMENT13_EXT:

-			case GL_COLOR_ATTACHMENT14_EXT:

-			case GL_COLOR_ATTACHMENT15_EXT:

-				{

-					GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);

-

-					if(index >= MAX_COLOR_ATTACHMENTS)

-					{

-						return error(GL_INVALID_OPERATION);

-					}

-

-					if(index != i)

-					{

-						return error(GL_INVALID_OPERATION);

-					}

-

-					if(drawFramebufferName == 0)

-					{

-						return error(GL_INVALID_OPERATION);

-					}

-				}

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-		}

-

-		context->setFramebufferDrawBuffers(n, bufs);

-	}

-}

-

-}

-

-extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)

-{

-	struct Extension

-	{

-		const char *name;

-		__eglMustCastToProperFunctionPointerType address;

-	};

-

-	static const Extension glExtensions[] =

-	{

-		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}

-

-		EXTENSION(glTexImage3DOES),

-		EXTENSION(glBlitFramebufferANGLE),

-		EXTENSION(glBlitFramebufferNV),

-		EXTENSION(glRenderbufferStorageMultisampleANGLE),

-		EXTENSION(glDeleteFencesNV),

-		EXTENSION(glGenFencesNV),

-		EXTENSION(glIsFenceNV),

-		EXTENSION(glTestFenceNV),

-		EXTENSION(glGetFenceivNV),

-		EXTENSION(glFinishFenceNV),

-		EXTENSION(glSetFenceNV),

-		EXTENSION(glGetGraphicsResetStatusEXT),

-		EXTENSION(glReadnPixelsEXT),

-		EXTENSION(glGetnUniformfvEXT),

-		EXTENSION(glGetnUniformivEXT),

-		EXTENSION(glGenQueriesEXT),

-		EXTENSION(glDeleteQueriesEXT),

-		EXTENSION(glIsQueryEXT),

-		EXTENSION(glBeginQueryEXT),

-		EXTENSION(glEndQueryEXT),

-		EXTENSION(glGetQueryivEXT),

-		EXTENSION(glGetQueryObjectuivEXT),

-		EXTENSION(glEGLImageTargetTexture2DOES),

-		EXTENSION(glEGLImageTargetRenderbufferStorageOES),

-		EXTENSION(glDrawElementsInstancedEXT),

-		EXTENSION(glDrawArraysInstancedEXT),

-		EXTENSION(glVertexAttribDivisorEXT),

-		EXTENSION(glDrawArraysInstancedANGLE),

-		EXTENSION(glDrawElementsInstancedANGLE),

-		EXTENSION(glVertexAttribDivisorANGLE),

-		EXTENSION(glIsRenderbufferOES),

-		EXTENSION(glBindRenderbufferOES),

-		EXTENSION(glDeleteRenderbuffersOES),

-		EXTENSION(glGenRenderbuffersOES),

-		EXTENSION(glRenderbufferStorageOES),

-		EXTENSION(glGetRenderbufferParameterivOES),

-		EXTENSION(glIsFramebufferOES),

-		EXTENSION(glBindFramebufferOES),

-		EXTENSION(glDeleteFramebuffersOES),

-		EXTENSION(glGenFramebuffersOES),

-		EXTENSION(glCheckFramebufferStatusOES),

-		EXTENSION(glFramebufferRenderbufferOES),

-		EXTENSION(glFramebufferTexture2DOES),

-		EXTENSION(glGetFramebufferAttachmentParameterivOES),

-		EXTENSION(glGenerateMipmapOES),

-		EXTENSION(glDrawBuffersEXT),

-

-		#undef EXTENSION

-	};

-

-	for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)

-	{

-		if(strcmp(procname, glExtensions[ext].name) == 0)

-		{

-			return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;

-		}

-	}

-

-	return NULL;

-}

+// 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.
+// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "Buffer.h"
+#include "Context.h"
+#include "Fence.h"
+#include "Framebuffer.h"
+#include "Program.h"
+#include "Renderbuffer.h"
+#include "Shader.h"
+#include "Texture.h"
+#include "Query.h"
+#include "TransformFeedback.h"
+#include "common/debug.h"
+#include "Common/Version.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+
+#include <limits>
+
+#ifdef ANDROID
+#include <cutils/log.h>
+#endif
+
+namespace es2
+{
+
+static bool validImageSize(GLint level, GLsizei width, GLsizei height)
+{
+	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
+{
+	GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
+	if(validationError != GL_NONE)
+	{
+		return error(validationError, false);
+	}
+
+	// [OpenGL ES 2.0.24] table 3.9
+	switch(textureFormat)
+	{
+	case GL_ALPHA:
+		if(colorbufferFormat != GL_ALPHA &&
+		   colorbufferFormat != GL_RGBA &&
+		   colorbufferFormat != GL_RGBA4 &&
+		   colorbufferFormat != GL_RGB5_A1 &&
+		   colorbufferFormat != GL_RGBA8_OES &&
+		   colorbufferFormat != GL_BGRA8_EXT &&
+		   colorbufferFormat != GL_RGBA16F_EXT &&
+		   colorbufferFormat != GL_RGBA32F_EXT)
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+		break;
+	case GL_LUMINANCE:
+	case GL_RGB:
+		if(colorbufferFormat != GL_RGB &&
+		   colorbufferFormat != GL_RGB565 &&
+		   colorbufferFormat != GL_RGB8_OES &&
+		   colorbufferFormat != GL_RGBA &&
+		   colorbufferFormat != GL_RGBA4 &&
+		   colorbufferFormat != GL_RGB5_A1 &&
+		   colorbufferFormat != GL_RGBA8_OES &&
+		   colorbufferFormat != GL_RGB16F_EXT &&
+		   colorbufferFormat != GL_RGB32F_EXT &&
+		   colorbufferFormat != GL_BGRA8_EXT &&
+		   colorbufferFormat != GL_RGBA16F_EXT &&
+		   colorbufferFormat != GL_RGBA32F_EXT)
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+		break;
+	case GL_LUMINANCE_ALPHA:
+	case GL_RGBA:
+		if(colorbufferFormat != GL_RGBA &&
+		   colorbufferFormat != GL_RGBA4 &&
+		   colorbufferFormat != GL_RGB5_A1 &&
+		   colorbufferFormat != GL_RGBA8_OES &&
+		   colorbufferFormat != GL_BGRA8_EXT &&
+		   colorbufferFormat != GL_RGBA16F_EXT &&
+		   colorbufferFormat != GL_RGBA32F_EXT)
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+		break;
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_STENCIL_OES:
+		return error(GL_INVALID_OPERATION, false);
+	default:
+		return error(GL_INVALID_ENUM, false);
+	}
+	return true;
+}
+
+void ActiveTexture(GLenum texture)
+{
+	TRACE("(GLenum texture = 0x%X)", texture);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->setActiveSampler(texture - GL_TEXTURE0);
+	}
+}
+
+void AttachShader(GLuint program, GLuint shader)
+{
+	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(!programObject->attachShader(shaderObject))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void BeginQueryEXT(GLenum target, GLuint name)
+{
+	TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED_EXT:
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(name == 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->beginQuery(target, name);
+	}
+}
+
+void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(strncmp(name, "gl_", 3) == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		programObject->bindAttributeLocation(index, name);
+	}
+}
+
+void BindBuffer(GLenum target, GLuint buffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLint clientVersion = egl::getClientVersion();
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			context->bindArrayBuffer(buffer);
+			return;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			context->bindElementArrayBuffer(buffer);
+			return;
+		case GL_COPY_READ_BUFFER:
+			if(clientVersion >= 3)
+			{
+				context->bindCopyReadBuffer(buffer);
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_COPY_WRITE_BUFFER:
+			if(clientVersion >= 3)
+			{
+				context->bindCopyWriteBuffer(buffer);
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_PIXEL_PACK_BUFFER:
+			if(clientVersion >= 3)
+			{
+				context->bindPixelPackBuffer(buffer);
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_PIXEL_UNPACK_BUFFER:
+			if(clientVersion >= 3)
+			{
+				context->bindPixelUnpackBuffer(buffer);
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TRANSFORM_FEEDBACK_BUFFER:
+			if(clientVersion >= 3)
+			{
+				context->bindTransformFeedbackBuffer(buffer);
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_UNIFORM_BUFFER:
+			if(clientVersion >= 3)
+			{
+				context->bindGenericUniformBuffer(buffer);
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void BindFramebuffer(GLenum target, GLuint framebuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
+
+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+		{
+			context->bindReadFramebuffer(framebuffer);
+		}
+
+		if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+		{
+			context->bindDrawFramebuffer(framebuffer);
+		}
+	}
+}
+
+void BindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
+
+	if(target != GL_RENDERBUFFER)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		// [OpenGL ES 2.0.25] Section 4.4.3 page 110
+		// [OpenGL ES 3.0.4] Section 4.4.2 page 204
+		// If renderbuffer is not zero, then the resulting renderbuffer object
+		// is a new state vector, initialized with a zero-sized memory buffer.
+		context->bindRenderbuffer(renderbuffer);
+	}
+}
+
+void BindTexture(GLenum target, GLuint texture)
+{
+	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject && textureObject->getTarget() != target && texture != 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			context->bindTexture2D(texture);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			context->bindTextureCubeMap(texture);
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			context->bindTextureExternal(texture);
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			context->bindTexture2DArray(texture);
+			break;
+		case GL_TEXTURE_3D_OES:
+			context->bindTexture3D(texture);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
+		red, green, blue, alpha);
+
+	es2::Context* context = es2::getContext();
+
+	if(context)
+	{
+		context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
+	}
+}
+
+void BlendEquation(GLenum mode)
+{
+	glBlendEquationSeparate(mode, mode);
+}
+
+void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
+
+	switch(modeRGB)
+	{
+	case GL_FUNC_ADD:
+	case GL_FUNC_SUBTRACT:
+	case GL_FUNC_REVERSE_SUBTRACT:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(modeAlpha)
+	{
+	case GL_FUNC_ADD:
+	case GL_FUNC_SUBTRACT:
+	case GL_FUNC_REVERSE_SUBTRACT:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setBlendEquation(modeRGB, modeAlpha);
+	}
+}
+
+void BlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
+}
+
+void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
+	      srcRGB, dstRGB, srcAlpha, dstAlpha);
+
+	GLint clientVersion = egl::getClientVersion();
+
+	switch(srcRGB)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+	case GL_SRC_ALPHA_SATURATE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(dstRGB)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+		break;
+	case GL_SRC_ALPHA_SATURATE:
+		if(clientVersion < 3)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(srcAlpha)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+	case GL_SRC_ALPHA_SATURATE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(dstAlpha)
+	{
+	case GL_ZERO:
+	case GL_ONE:
+	case GL_SRC_COLOR:
+	case GL_ONE_MINUS_SRC_COLOR:
+	case GL_DST_COLOR:
+	case GL_ONE_MINUS_DST_COLOR:
+	case GL_SRC_ALPHA:
+	case GL_ONE_MINUS_SRC_ALPHA:
+	case GL_DST_ALPHA:
+	case GL_ONE_MINUS_DST_ALPHA:
+	case GL_CONSTANT_COLOR:
+	case GL_ONE_MINUS_CONSTANT_COLOR:
+	case GL_CONSTANT_ALPHA:
+	case GL_ONE_MINUS_CONSTANT_ALPHA:
+		break;
+	case GL_SRC_ALPHA_SATURATE:
+		if(clientVersion < 3)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
+	}
+}
+
+void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
+
+	TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
+	      target, size, data, usage);
+
+	if(size < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	GLint clientVersion = egl::getClientVersion();
+
+	switch(usage)
+	{
+	case GL_STREAM_DRAW:
+	case GL_STATIC_DRAW:
+	case GL_DYNAMIC_DRAW:
+		break;
+	case GL_STREAM_READ:
+	case GL_STREAM_COPY:
+	case GL_STATIC_READ:
+	case GL_STATIC_COPY:
+	case GL_DYNAMIC_READ:
+	case GL_DYNAMIC_COPY:
+		if(clientVersion < 3)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer = nullptr;
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		buffer->bufferData(data, size, usage);
+	}
+}
+
+void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
+	offset = static_cast<GLint>(offset);
+
+	TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
+	      target, offset, size, data);
+
+	if(size < 0 || offset < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer = nullptr;
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if((size_t)size + offset > buffer->size())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		buffer->bufferSubData(data, size, offset);
+	}
+}
+
+GLenum CheckFramebufferStatus(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+	{
+		return error(GL_INVALID_ENUM, 0);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Framebuffer *framebuffer = nullptr;
+		if(target == GL_READ_FRAMEBUFFER_ANGLE)
+		{
+			framebuffer = context->getReadFramebuffer();
+		}
+		else
+		{
+			framebuffer = context->getDrawFramebuffer();
+		}
+
+		return framebuffer->completeness();
+	}
+
+	return 0;
+}
+
+void Clear(GLbitfield mask)
+{
+	TRACE("(GLbitfield mask = %X)", mask);
+
+	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->clear(mask);
+	}
+}
+
+void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
+	      red, green, blue, alpha);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setClearColor(red, green, blue, alpha);
+	}
+}
+
+void ClearDepthf(GLclampf depth)
+{
+	TRACE("(GLclampf depth = %f)", depth);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setClearDepth(depth);
+	}
+}
+
+void ClearStencil(GLint s)
+{
+	TRACE("(GLint s = %d)", s);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setClearStencil(s);
+	}
+}
+
+void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
+	      red, green, blue, alpha);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
+	}
+}
+
+void CompileShader(GLuint shader)
+{
+	TRACE("(GLuint shader = %d)", shader);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		shaderObject->compile();
+	}
+}
+
+void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                          GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
+	      target, level, internalformat, width, height, border, imageSize, data);
+
+	if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(internalformat)
+	{
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_COMPONENT16:
+	case GL_DEPTH_COMPONENT32_OES:
+	case GL_DEPTH_STENCIL_OES:
+	case GL_DEPTH24_STENCIL8_OES:
+		return error(GL_INVALID_OPERATION);
+	default:
+		{
+			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
+			if(validationError != GL_NONE)
+			{
+				return error(validationError);
+			}
+		}
+		break;
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+			if(width != height)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
+			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es2::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+		}
+		else
+		{
+			es2::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			switch(target)
+			{
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+				texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+				break;
+			default: UNREACHABLE(target);
+			}
+		}
+	}
+}
+
+void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                             GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
+	      "GLsizei imageSize = %d, const GLvoid* data = %p)",
+	      target, level, xoffset, yoffset, width, height, format, imageSize, data);
+
+	if(!es2::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
+	if(validationError != GL_NONE)
+	{
+		return error(validationError);
+	}
+
+	if(width == 0 || height == 0 || !data)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(imageSize != egl::ComputeCompressedSize(width, height, format))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(xoffset % 4 != 0 || yoffset % 4 != 0)
+		{
+			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es2::Texture2D *texture = context->getTexture2D();
+
+			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
+
+			if(validationError == GL_NONE)
+			{
+				texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
+			}
+			else
+			{
+				return error(validationError);
+			}
+		}
+		else if(es2::IsCubemapTextureTarget(target))
+		{
+			es2::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
+
+			if(validationError == GL_NONE)
+			{
+				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
+			}
+			else
+			{
+				return error(validationError);
+			}
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
+	      target, level, internalformat, x, y, width, height, border);
+
+	if(!validImageSize(level, width, height))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+			if(width != height)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
+			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
+
+		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
+
+		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLenum colorbufferFormat = source->getFormat();
+
+		if(!validateColorBufferFormat(internalformat, colorbufferFormat))
+		{
+			return;
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es2::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+		}
+		else if(es2::IsCubemapTextureTarget(target))
+		{
+			es2::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+	      target, level, xoffset, yoffset, x, y, width, height);
+
+	if(!es2::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(width == 0 || height == 0)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
+
+		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
+
+		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es2::Texture *texture = nullptr;
+
+		if(target == GL_TEXTURE_2D)
+		{
+			texture = context->getTexture2D();
+		}
+		else if(es2::IsCubemapTextureTarget(target))
+		{
+			texture = context->getTextureCubeMap();
+		}
+		else UNREACHABLE(target);
+
+		GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);
+		if(validationError != GL_NONE)
+		{
+			return error(validationError);
+		}
+
+		texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+	}
+}
+
+GLuint CreateProgram(void)
+{
+	TRACE("()");
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		return context->createProgram();
+	}
+
+	return 0;
+}
+
+GLuint CreateShader(GLenum type)
+{
+	TRACE("(GLenum type = 0x%X)", type);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(type)
+		{
+		case GL_FRAGMENT_SHADER:
+		case GL_VERTEX_SHADER:
+			return context->createShader(type);
+		default:
+			return error(GL_INVALID_ENUM, 0);
+		}
+	}
+
+	return 0;
+}
+
+void CullFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		{
+			es2::Context *context = es2::getContext();
+
+			if(context)
+			{
+				context->setCullMode(mode);
+			}
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void DeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteBuffer(buffers[i]);
+		}
+	}
+}
+
+void DeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+	TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteFence(fences[i]);
+		}
+	}
+}
+
+void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			if(framebuffers[i] != 0)
+			{
+				context->deleteFramebuffer(framebuffers[i]);
+			}
+		}
+	}
+}
+
+void DeleteProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	if(program == 0)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->getProgram(program))
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		context->deleteProgram(program);
+	}
+}
+
+void DeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteQuery(ids[i]);
+		}
+	}
+}
+
+void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteRenderbuffer(renderbuffers[i]);
+		}
+	}
+}
+
+void DeleteShader(GLuint shader)
+{
+	TRACE("(GLuint shader = %d)", shader);
+
+	if(shader == 0)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->getShader(shader))
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		context->deleteShader(shader);
+	}
+}
+
+void DeleteTextures(GLsizei n, const GLuint* textures)
+{
+	TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			if(textures[i] != 0)
+			{
+				context->deleteTexture(textures[i]);
+			}
+		}
+	}
+}
+
+void DepthFunc(GLenum func)
+{
+	TRACE("(GLenum func = 0x%X)", func);
+
+	switch(func)
+	{
+	case GL_NEVER:
+	case GL_ALWAYS:
+	case GL_LESS:
+	case GL_LEQUAL:
+	case GL_EQUAL:
+	case GL_GREATER:
+	case GL_GEQUAL:
+	case GL_NOTEQUAL:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setDepthFunc(func);
+	}
+}
+
+void DepthMask(GLboolean flag)
+{
+	TRACE("(GLboolean flag = %d)", flag);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setDepthMask(flag != GL_FALSE);
+	}
+}
+
+void DepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setDepthRange(zNear, zFar);
+	}
+}
+
+void DetachShader(GLuint program, GLuint shader)
+{
+	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+
+		es2::Program *programObject = context->getProgram(program);
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(!programObject)
+		{
+			es2::Shader *shaderByProgramHandle;
+			shaderByProgramHandle = context->getShader(program);
+			if(!shaderByProgramHandle)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
+		if(!shaderObject)
+		{
+			es2::Program *programByShaderHandle = context->getProgram(shader);
+			if(!programByShaderHandle)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
+		if(!programObject->detachShader(shaderObject))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Disable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(cap)
+		{
+		case GL_CULL_FACE:                     context->setCullFaceEnabled(false);                   break;
+		case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(false);          break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(false);      break;
+		case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(false);             break;
+		case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(false);                break;
+		case GL_STENCIL_TEST:                  context->setStencilTestEnabled(false);                break;
+		case GL_DEPTH_TEST:                    context->setDepthTestEnabled(false);                  break;
+		case GL_BLEND:                         context->setBlendEnabled(false);                      break;
+		case GL_DITHER:                        context->setDitherEnabled(false);                     break;
+		case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;
+		case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(false);          break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void DisableVertexAttribArray(GLuint index)
+{
+	TRACE("(GLuint index = %d)", index);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribArrayEnabled(index, false);
+	}
+}
+
+void DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0 || first < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawArrays(mode, first, count);
+	}
+}
+
+void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
+	      mode, count, type, indices);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT:
+		case GL_UNSIGNED_INT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
+	}
+}
+
+void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
+		mode, first, count, instanceCount);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0 || instanceCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawArrays(mode, first, count, instanceCount);
+	}
+}
+
+void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
+		mode, count, type, indices, instanceCount);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(type)
+	{
+	case GL_UNSIGNED_BYTE:
+	case GL_UNSIGNED_SHORT:
+	case GL_UNSIGNED_INT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0 || instanceCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
+	}
+}
+
+void VertexAttribDivisorEXT(GLuint index, GLuint divisor)
+{
+	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= es2::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		context->setVertexAttribDivisor(index, divisor);
+	}
+}
+
+void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
+		mode, first, count, instanceCount);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0 || instanceCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->hasZeroDivisor())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawArrays(mode, first, count, instanceCount);
+	}
+}
+
+void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
+		mode, count, type, indices, instanceCount);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(type)
+	{
+	case GL_UNSIGNED_BYTE:
+	case GL_UNSIGNED_SHORT:
+	case GL_UNSIGNED_INT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0 || instanceCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->hasZeroDivisor())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
+	}
+}
+
+void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		context->setVertexAttribDivisor(index, divisor);
+	}
+}
+
+void Enable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(cap)
+		{
+		case GL_CULL_FACE:                     context->setCullFaceEnabled(true);                   break;
+		case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(true);          break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(true);      break;
+		case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(true);             break;
+		case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(true);                break;
+		case GL_STENCIL_TEST:                  context->setStencilTestEnabled(true);                break;
+		case GL_DEPTH_TEST:                    context->setDepthTestEnabled(true);                  break;
+		case GL_BLEND:                         context->setBlendEnabled(true);                      break;
+		case GL_DITHER:                        context->setDitherEnabled(true);                     break;
+		case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;
+		case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(true);          break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void EnableVertexAttribArray(GLuint index)
+{
+	TRACE("(GLuint index = %d)", index);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribArrayEnabled(index, true);
+	}
+}
+
+void EndQueryEXT(GLenum target)
+{
+	TRACE("GLenum target = 0x%X)", target);
+
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED_EXT:
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->endQuery(target);
+	}
+}
+
+void FinishFenceNV(GLuint fence)
+{
+	TRACE("(GLuint fence = %d)", fence);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		fenceObject->finishFence();
+	}
+}
+
+void Finish(void)
+{
+	TRACE("()");
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->finish();
+	}
+}
+
+void Flush(void)
+{
+	TRACE("()");
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->flush();
+	}
+}
+
+void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
+	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
+
+	if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
+	   (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Framebuffer *framebuffer = nullptr;
+		GLuint framebufferName = 0;
+		if(target == GL_READ_FRAMEBUFFER_ANGLE)
+		{
+			framebuffer = context->getReadFramebuffer();
+			framebufferName = context->getReadFramebufferName();
+		}
+		else
+		{
+			framebuffer = context->getDrawFramebuffer();
+			framebufferName = context->getDrawFramebufferName();
+		}
+
+		if(!framebuffer || framebufferName == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		// [OpenGL ES 2.0.25] Section 4.4.3 page 112
+		// [OpenGL ES 3.0.2] Section 4.4.2 page 201
+		// 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
+		// type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
+		if(renderbuffer != 0)
+		{
+			if(!context->getRenderbuffer(renderbuffer))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0:
+		case GL_COLOR_ATTACHMENT1:
+		case GL_COLOR_ATTACHMENT2:
+		case GL_COLOR_ATTACHMENT3:
+		case GL_COLOR_ATTACHMENT4:
+		case GL_COLOR_ATTACHMENT5:
+		case GL_COLOR_ATTACHMENT6:
+		case GL_COLOR_ATTACHMENT7:
+		case GL_COLOR_ATTACHMENT8:
+		case GL_COLOR_ATTACHMENT9:
+		case GL_COLOR_ATTACHMENT10:
+		case GL_COLOR_ATTACHMENT11:
+		case GL_COLOR_ATTACHMENT12:
+		case GL_COLOR_ATTACHMENT13:
+		case GL_COLOR_ATTACHMENT14:
+		case GL_COLOR_ATTACHMENT15:
+		case GL_COLOR_ATTACHMENT16:
+		case GL_COLOR_ATTACHMENT17:
+		case GL_COLOR_ATTACHMENT18:
+		case GL_COLOR_ATTACHMENT19:
+		case GL_COLOR_ATTACHMENT20:
+		case GL_COLOR_ATTACHMENT21:
+		case GL_COLOR_ATTACHMENT22:
+		case GL_COLOR_ATTACHMENT23:
+		case GL_COLOR_ATTACHMENT24:
+		case GL_COLOR_ATTACHMENT25:
+		case GL_COLOR_ATTACHMENT26:
+		case GL_COLOR_ATTACHMENT27:
+		case GL_COLOR_ATTACHMENT28:
+		case GL_COLOR_ATTACHMENT29:
+		case GL_COLOR_ATTACHMENT30:
+		case GL_COLOR_ATTACHMENT31:
+			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);
+			break;
+		case GL_DEPTH_ATTACHMENT:
+			framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
+			break;
+		case GL_STENCIL_ATTACHMENT:
+			framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
+			break;
+		case GL_DEPTH_STENCIL_ATTACHMENT:
+			if(clientVersion >= 3)
+			{
+				framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
+				framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
+	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
+
+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(texture == 0)
+		{
+			textarget = GL_NONE;
+		}
+		else
+		{
+			es2::Texture *tex = context->getTexture(texture);
+
+			if(!tex)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			switch(textarget)
+			{
+			case GL_TEXTURE_2D:
+				if(tex->getTarget() != GL_TEXTURE_2D)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(tex->isCompressed(textarget, level))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			if((level != 0) && (context->getClientVersion() < 3))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		es2::Framebuffer *framebuffer = nullptr;
+		GLuint framebufferName = 0;
+		if(target == GL_READ_FRAMEBUFFER_ANGLE)
+		{
+			framebuffer = context->getReadFramebuffer();
+			framebufferName = context->getReadFramebufferName();
+		}
+		else
+		{
+			framebuffer = context->getDrawFramebuffer();
+			framebufferName = context->getDrawFramebufferName();
+		}
+
+		if(framebufferName == 0 || !framebuffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0:
+		case GL_COLOR_ATTACHMENT1:
+		case GL_COLOR_ATTACHMENT2:
+		case GL_COLOR_ATTACHMENT3:
+		case GL_COLOR_ATTACHMENT4:
+		case GL_COLOR_ATTACHMENT5:
+		case GL_COLOR_ATTACHMENT6:
+		case GL_COLOR_ATTACHMENT7:
+		case GL_COLOR_ATTACHMENT8:
+		case GL_COLOR_ATTACHMENT9:
+		case GL_COLOR_ATTACHMENT10:
+		case GL_COLOR_ATTACHMENT11:
+		case GL_COLOR_ATTACHMENT12:
+		case GL_COLOR_ATTACHMENT13:
+		case GL_COLOR_ATTACHMENT14:
+		case GL_COLOR_ATTACHMENT15:
+		case GL_COLOR_ATTACHMENT16:
+		case GL_COLOR_ATTACHMENT17:
+		case GL_COLOR_ATTACHMENT18:
+		case GL_COLOR_ATTACHMENT19:
+		case GL_COLOR_ATTACHMENT20:
+		case GL_COLOR_ATTACHMENT21:
+		case GL_COLOR_ATTACHMENT22:
+		case GL_COLOR_ATTACHMENT23:
+		case GL_COLOR_ATTACHMENT24:
+		case GL_COLOR_ATTACHMENT25:
+		case GL_COLOR_ATTACHMENT26:
+		case GL_COLOR_ATTACHMENT27:
+		case GL_COLOR_ATTACHMENT28:
+		case GL_COLOR_ATTACHMENT29:
+		case GL_COLOR_ATTACHMENT30:
+		case GL_COLOR_ATTACHMENT31:
+			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);
+			break;
+		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture, level);   break;
+		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void FrontFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_CW:
+	case GL_CCW:
+		{
+			es2::Context *context = es2::getContext();
+
+			if(context)
+			{
+				context->setFrontFace(mode);
+			}
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void GenBuffers(GLsizei n, GLuint* buffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			buffers[i] = context->createBuffer();
+		}
+	}
+}
+
+void GenerateMipmap(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture *texture = nullptr;
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			else
+			{
+				texture = context->getTexture2DArray();
+			}
+			break;
+		case GL_TEXTURE_3D_OES:
+			texture = context->getTexture3D();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->generateMipmaps();
+	}
+}
+
+void GenFencesNV(GLsizei n, GLuint* fences)
+{
+	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			fences[i] = context->createFence();
+		}
+	}
+}
+
+void GenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			framebuffers[i] = context->createFramebuffer();
+		}
+	}
+}
+
+void GenQueriesEXT(GLsizei n, GLuint* ids)
+{
+	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			ids[i] = context->createQuery();
+		}
+	}
+}
+
+void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			renderbuffers[i] = context->createRenderbuffer();
+		}
+	}
+}
+
+void GenTextures(GLsizei n, GLuint* textures)
+{
+	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			textures[i] = context->createTexture();
+		}
+	}
+}
+
+void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
+	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
+	      program, index, bufsize, length, size, type, name);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(index >= programObject->getActiveAttributeCount())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->getActiveAttribute(index, bufsize, length, size, type, name);
+	}
+}
+
+void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
+	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
+	      program, index, bufsize, length, size, type, name);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(index >= programObject->getActiveUniformCount())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->getActiveUniform(index, bufsize, length, size, type, name);
+	}
+}
+
+void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
+	      program, maxcount, count, shaders);
+
+	if(maxcount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		return programObject->getAttachedShaders(maxcount, count, shaders);
+	}
+}
+
+int GetAttribLocation(GLuint program, const GLchar* name)
+{
+	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION, -1);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE, -1);
+			}
+		}
+
+		if(!programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION, -1);
+		}
+
+		return programObject->getAttributeLocation(name);
+	}
+
+	return -1;
+}
+
+void GetBooleanv(GLenum pname, GLboolean* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!(context->getBooleanv(pname, params)))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that the pname is valid, but there are no parameters to return
+
+			if(nativeType == GL_FLOAT)
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(floatParams[i] == 0.0f)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] floatParams;
+			}
+			else if(nativeType == GL_INT)
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(intParams[i] == 0)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] intParams;
+			}
+		}
+	}
+}
+
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer;
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(pname)
+		{
+		case GL_BUFFER_USAGE:
+			*params = buffer->usage();
+			break;
+		case GL_BUFFER_SIZE:
+			*params = (GLint)buffer->size();
+			break;
+		case GL_BUFFER_ACCESS_FLAGS:
+			if(clientVersion >= 3)
+			{
+				*params = buffer->access();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_BUFFER_MAPPED:
+			if(clientVersion >= 3)
+			{
+				*params = buffer->isMapped();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_BUFFER_MAP_LENGTH:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)buffer->length();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_BUFFER_MAP_OFFSET:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)buffer->offset();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GLenum GetError(void)
+{
+	TRACE("()");
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		return context->getError();
+	}
+
+	return GL_NO_ERROR;
+}
+
+void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		fenceObject->getFenceiv(pname, params);
+	}
+}
+
+void GetFloatv(GLenum pname, GLfloat* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!(context->getFloatv(pname, params)))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that the pname is valid, but that there are no parameters to return.
+
+			if(nativeType == GL_BOOL)
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(boolParams[i] == GL_FALSE)
+						params[i] = 0.0f;
+					else
+						params[i] = 1.0f;
+				}
+
+				delete [] boolParams;
+			}
+			else if(nativeType == GL_INT)
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					params[i] = (GLfloat)intParams[i];
+				}
+
+				delete [] intParams;
+			}
+		}
+	}
+}
+
+void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
+	      target, attachment, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		GLint clientVersion = context->getClientVersion();
+
+		es2::Framebuffer *framebuffer = nullptr;
+		if(target == GL_READ_FRAMEBUFFER)
+		{
+			if(context->getReadFramebufferName() == 0)
+			{
+				if(clientVersion < 3)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				else
+				{
+					switch(attachment)
+					{
+					case GL_BACK:
+					case GL_DEPTH:
+					case GL_STENCIL:
+						break;
+					default:
+						return error(GL_INVALID_ENUM);
+					}
+				}
+			}
+
+			framebuffer = context->getReadFramebuffer();
+		}
+		else
+		{
+			if(context->getDrawFramebufferName() == 0)
+			{
+				if(clientVersion < 3)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				else
+				{
+					switch(attachment)
+					{
+					case GL_BACK:
+					case GL_DEPTH:
+					case GL_STENCIL:
+						break;
+					default:
+						return error(GL_INVALID_ENUM);
+					}
+				}
+			}
+
+			framebuffer = context->getDrawFramebuffer();
+		}
+
+		GLenum attachmentType;
+		GLuint attachmentHandle;
+		GLint attachmentLayer;
+		Renderbuffer* renderbuffer = nullptr;
+		switch(attachment)
+		{
+		case GL_BACK:
+			if(clientVersion >= 3)
+			{
+				attachmentType = framebuffer->getColorbufferType(0);
+				attachmentHandle = framebuffer->getColorbufferName(0);
+				attachmentLayer = framebuffer->getColorbufferLayer(0);
+				renderbuffer = framebuffer->getColorbuffer(0);
+			}
+			else return error(GL_INVALID_ENUM);
+			break;
+		case GL_COLOR_ATTACHMENT0:
+		case GL_COLOR_ATTACHMENT1:
+		case GL_COLOR_ATTACHMENT2:
+		case GL_COLOR_ATTACHMENT3:
+		case GL_COLOR_ATTACHMENT4:
+		case GL_COLOR_ATTACHMENT5:
+		case GL_COLOR_ATTACHMENT6:
+		case GL_COLOR_ATTACHMENT7:
+		case GL_COLOR_ATTACHMENT8:
+		case GL_COLOR_ATTACHMENT9:
+		case GL_COLOR_ATTACHMENT10:
+		case GL_COLOR_ATTACHMENT11:
+		case GL_COLOR_ATTACHMENT12:
+		case GL_COLOR_ATTACHMENT13:
+		case GL_COLOR_ATTACHMENT14:
+		case GL_COLOR_ATTACHMENT15:
+		case GL_COLOR_ATTACHMENT16:
+		case GL_COLOR_ATTACHMENT17:
+		case GL_COLOR_ATTACHMENT18:
+		case GL_COLOR_ATTACHMENT19:
+		case GL_COLOR_ATTACHMENT20:
+		case GL_COLOR_ATTACHMENT21:
+		case GL_COLOR_ATTACHMENT22:
+		case GL_COLOR_ATTACHMENT23:
+		case GL_COLOR_ATTACHMENT24:
+		case GL_COLOR_ATTACHMENT25:
+		case GL_COLOR_ATTACHMENT26:
+		case GL_COLOR_ATTACHMENT27:
+		case GL_COLOR_ATTACHMENT28:
+		case GL_COLOR_ATTACHMENT29:
+		case GL_COLOR_ATTACHMENT30:
+		case GL_COLOR_ATTACHMENT31:
+			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
+			attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
+			attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
+			renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
+			break;
+		case GL_DEPTH:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			// fall through
+		case GL_DEPTH_ATTACHMENT:
+			attachmentType = framebuffer->getDepthbufferType();
+			attachmentHandle = framebuffer->getDepthbufferName();
+			attachmentLayer = framebuffer->getDepthbufferLayer();
+			renderbuffer = framebuffer->getDepthbuffer();
+			break;
+		case GL_STENCIL:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			// fall through
+		case GL_STENCIL_ATTACHMENT:
+			attachmentType = framebuffer->getStencilbufferType();
+			attachmentHandle = framebuffer->getStencilbufferName();
+			attachmentLayer = framebuffer->getStencilbufferLayer();
+			renderbuffer = framebuffer->getStencilbuffer();
+			break;
+		case GL_DEPTH_STENCIL_ATTACHMENT:
+			if(clientVersion >= 3)
+			{
+				attachmentType = framebuffer->getDepthbufferType();
+				attachmentHandle = framebuffer->getDepthbufferName();
+				attachmentLayer = framebuffer->getDepthbufferLayer();
+				if(attachmentHandle != framebuffer->getStencilbufferName())
+				{
+					// Different attachments to DEPTH and STENCIL, query fails
+					return error(GL_INVALID_OPERATION);
+				}
+				renderbuffer = framebuffer->getDepthbuffer();
+			}
+			else return error(GL_INVALID_ENUM);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		GLenum attachmentObjectType = GL_NONE;   // Type category
+		if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
+		{
+			attachmentObjectType = attachmentType;
+		}
+		else if(es2::IsTextureTarget(attachmentType))
+		{
+			attachmentObjectType = GL_TEXTURE;
+		}
+		else UNREACHABLE(attachmentType);
+
+		if(attachmentObjectType != GL_NONE)
+		{
+			switch(pname)
+			{
+			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+				*params = attachmentObjectType;
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+				if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE)
+				{
+					*params = attachmentHandle;
+				}
+				else
+				{
+					return error(GL_INVALID_ENUM);
+				}
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+				if(attachmentObjectType == GL_TEXTURE)
+				{
+					*params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
+				}
+				else
+				{
+					return error(GL_INVALID_ENUM);
+				}
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+				if(attachmentObjectType == GL_TEXTURE)
+				{
+					if(es2::IsCubemapTextureTarget(attachmentType))
+					{
+						*params = attachmentType;
+					}
+					else
+					{
+						*params = 0;
+					}
+				}
+				else
+				{
+					return error(GL_INVALID_ENUM);
+				}
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+				if(clientVersion >= 3)
+				{
+					*params = attachmentLayer;
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+				if(clientVersion >= 3)
+				{
+					*params = renderbuffer->getRedSize();
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+				if(clientVersion >= 3)
+				{
+					*params = renderbuffer->getGreenSize();
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+				if(clientVersion >= 3)
+				{
+					*params = renderbuffer->getBlueSize();
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+				if(clientVersion >= 3)
+				{
+					*params = renderbuffer->getAlphaSize();
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+				if(clientVersion >= 3)
+				{
+					*params = renderbuffer->getDepthSize();
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+				if(clientVersion >= 3)
+				{
+					*params = renderbuffer->getStencilSize();
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+				if(clientVersion >= 3)
+				{
+					if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+					{
+						return error(GL_INVALID_OPERATION);
+					}
+
+					*params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+				if(clientVersion >= 3)
+				{
+					*params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added
+				}
+				else return error(GL_INVALID_ENUM);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+		}
+		else
+		{
+			// ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+			// is NONE, then querying any other pname will generate INVALID_ENUM.
+
+			// ES 3.0.2 spec pg 235 states that if the attachment type is none,
+			// GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
+			// INVALID_OPERATION for all other pnames
+
+			switch(pname)
+			{
+			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+				*params = GL_NONE;
+				break;
+
+			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+				if(clientVersion < 3)
+				{
+					return error(GL_INVALID_ENUM);
+				}
+				*params = 0;
+				break;
+
+			default:
+				if(clientVersion < 3)
+				{
+					return error(GL_INVALID_ENUM);
+				}
+				else
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+			}
+		}
+	}
+}
+
+GLenum GetGraphicsResetStatusEXT(void)
+{
+	TRACE("()");
+
+	return GL_NO_ERROR;
+}
+
+void GetIntegerv(GLenum pname, GLint* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(!context)
+	{
+		// Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
+		#ifdef __ANDROID__
+			ALOGI("expected_badness glGetIntegerv() called without current context.");
+		#else
+			ERR("glGetIntegerv() called without current context.");
+		#endif
+
+		// This is not spec compliant! When there is no current GL context, functions should
+		// have no side effects. Google Maps queries these values before creating a context,
+		// so we need this as a bug-compatible workaround.
+		switch(pname)
+		{
+		case GL_MAX_TEXTURE_SIZE:                 *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE;  return;
+		case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return;
+		case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
+		case GL_STENCIL_BITS:                     *params = 8;                                     return;
+		case GL_ALIASED_LINE_WIDTH_RANGE:
+			params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
+			params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
+			return;
+		}
+	}
+
+	if(context)
+	{
+		if(!(context->getIntegerv(pname, params)))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that pname is valid, but there are no parameters to return
+
+			if(nativeType == GL_BOOL)
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
+				}
+
+				delete [] boolParams;
+			}
+			else if(nativeType == GL_FLOAT)
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
+					{
+						params[i] = es2::floatToInt(floatParams[i]);
+					}
+					else
+					{
+						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
+					}
+				}
+
+				delete [] floatParams;
+			}
+		}
+	}
+}
+
+void GetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		GLint clientVersion = egl::getClientVersion();
+
+		switch(pname)
+		{
+		case GL_DELETE_STATUS:
+			*params = programObject->isFlaggedForDeletion();
+			return;
+		case GL_LINK_STATUS:
+			*params = programObject->isLinked();
+			return;
+		case GL_VALIDATE_STATUS:
+			*params = programObject->isValidated();
+			return;
+		case GL_INFO_LOG_LENGTH:
+			*params = (GLint)programObject->getInfoLogLength();
+			return;
+		case GL_ATTACHED_SHADERS:
+			*params = programObject->getAttachedShadersCount();
+			return;
+		case GL_ACTIVE_ATTRIBUTES:
+			*params = (GLint)programObject->getActiveAttributeCount();
+			return;
+		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+			*params = programObject->getActiveAttributeMaxLength();
+			return;
+		case GL_ACTIVE_UNIFORMS:
+			*params = (GLint)programObject->getActiveUniformCount();
+			return;
+		case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+			*params = programObject->getActiveUniformMaxLength();
+			return;
+		case GL_ACTIVE_UNIFORM_BLOCKS:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)programObject->getActiveUniformBlockCount();
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
+			if(clientVersion >= 3)
+			{
+				*params = programObject->getActiveUniformBlockMaxLength();
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+			if(clientVersion >= 3)
+			{
+				*params = programObject->getTransformFeedbackBufferMode();
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TRANSFORM_FEEDBACK_VARYINGS:
+			if(clientVersion >= 3)
+			{
+				*params = programObject->getTransformFeedbackVaryingCount();
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+			if(clientVersion >= 3)
+			{
+				*params = programObject->getTransformFeedbackVaryingMaxLength();
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+			if(clientVersion >= 3)
+			{
+				*params = programObject->getBinaryRetrievableHint();
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_PROGRAM_BINARY_LENGTH:
+			if(clientVersion >= 3)
+			{
+				*params = programObject->getBinaryLength();
+				return;
+			}
+			else return error(GL_INVALID_ENUM);
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
+	      program, bufsize, length, infolog);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		programObject->getInfoLog(bufsize, length, infolog);
+	}
+}
+
+void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+	TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
+
+	switch(pname)
+	{
+	case GL_CURRENT_QUERY_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		params[0] = context->getActiveQuery(target);
+	}
+}
+
+void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
+{
+	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
+
+	switch(pname)
+	{
+	case GL_QUERY_RESULT_EXT:
+	case GL_QUERY_RESULT_AVAILABLE_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Query *queryObject = context->getQuery(name);
+
+		if(!queryObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(context->getActiveQuery(queryObject->getType()) == name)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_QUERY_RESULT_EXT:
+			params[0] = queryObject->getResult();
+			break;
+		case GL_QUERY_RESULT_AVAILABLE_EXT:
+			params[0] = queryObject->isResultAvailable();
+			break;
+		default:
+			ASSERT(false);
+		}
+	}
+}
+
+void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(target != GL_RENDERBUFFER)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(context->getRenderbufferName() == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
+
+		switch(pname)
+		{
+		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;
+		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;
+		case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;
+		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;
+		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;
+		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;
+		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;
+		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;
+		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;
+		case GL_RENDERBUFFER_SAMPLES_ANGLE:   *params = renderbuffer->getSamples();     break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		switch(pname)
+		{
+		case GL_SHADER_TYPE:
+			*params = shaderObject->getType();
+			return;
+		case GL_DELETE_STATUS:
+			*params = shaderObject->isFlaggedForDeletion();
+			return;
+		case GL_COMPILE_STATUS:
+			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
+			return;
+		case GL_INFO_LOG_LENGTH:
+			*params = (GLint)shaderObject->getInfoLogLength();
+			return;
+		case GL_SHADER_SOURCE_LENGTH:
+			*params = (GLint)shaderObject->getSourceLength();
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
+	      shader, bufsize, length, infolog);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		shaderObject->getInfoLog(bufsize, length, infolog);
+	}
+}
+
+void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
+	      shadertype, precisiontype, range, precision);
+
+	switch(shadertype)
+	{
+	case GL_VERTEX_SHADER:
+	case GL_FRAGMENT_SHADER:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(precisiontype)
+	{
+	case GL_LOW_FLOAT:
+	case GL_MEDIUM_FLOAT:
+	case GL_HIGH_FLOAT:
+		// IEEE 754 single-precision
+		range[0] = 127;
+		range[1] = 127;
+		*precision = 23;
+		break;
+	case GL_LOW_INT:
+	case GL_MEDIUM_INT:
+	case GL_HIGH_INT:
+		// Full integer precision is supported
+		range[0] = 31;
+		range[1] = 30;
+		*precision = 0;
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
+	      shader, bufsize, length, source);
+
+	if(bufsize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		shaderObject->getSource(bufsize, length, source);
+	}
+}
+
+const GLubyte* GetString(GLenum name)
+{
+	TRACE("(GLenum name = 0x%X)", name);
+
+	switch(name)
+	{
+	case GL_VENDOR:
+		return (GLubyte*)"Google Inc.";
+	case GL_RENDERER:
+		return (GLubyte*)"Google SwiftShader";
+	case GL_VERSION:
+	{
+		es2::Context *context = es2::getContext();
+		return (context && (context->getClientVersion() >= 3)) ?
+		       (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
+		       (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
+	}
+	case GL_SHADING_LANGUAGE_VERSION:
+	{
+		es2::Context *context = es2::getContext();
+		return (context && (context->getClientVersion() >= 3)) ?
+		       (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
+		       (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
+	}
+	case GL_EXTENSIONS:
+	{
+		es2::Context *context = es2::getContext();
+		return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr;
+	}
+	default:
+		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
+	}
+}
+
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture *texture;
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			else
+			{
+				texture = context->getTexture2DArray();
+			}
+			break;
+		case GL_TEXTURE_3D_OES:
+			texture = context->getTexture3D();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_MAG_FILTER:
+			*params = (GLfloat)texture->getMagFilter();
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			*params = (GLfloat)texture->getMinFilter();
+			break;
+		case GL_TEXTURE_WRAP_S:
+			*params = (GLfloat)texture->getWrapS();
+			break;
+		case GL_TEXTURE_WRAP_T:
+			*params = (GLfloat)texture->getWrapT();
+			break;
+		case GL_TEXTURE_WRAP_R_OES:
+			*params = (GLfloat)texture->getWrapR();
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			*params = texture->getMaxAnisotropy();
+			break;
+		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+			*params = (GLfloat)1;
+			break;
+		case GL_TEXTURE_BASE_LEVEL:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getBaseLevel();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_COMPARE_FUNC:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getCompareFunc();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_COMPARE_MODE:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getCompareMode();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_IMMUTABLE_FORMAT:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getImmutableFormat();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_IMMUTABLE_LEVELS:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getImmutableLevels();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_MAX_LEVEL:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getMaxLevel();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_MAX_LOD:
+			if(clientVersion >= 3)
+			{
+				*params = texture->getMaxLOD();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_MIN_LOD:
+			if(clientVersion >= 3)
+			{
+				*params = texture->getMinLOD();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_R:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getSwizzleR();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_G:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getSwizzleG();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_B:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getSwizzleB();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_A:
+			if(clientVersion >= 3)
+			{
+				*params = (GLfloat)texture->getSwizzleA();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture *texture;
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			else
+			{
+				texture = context->getTexture2DArray();
+			}
+			break;
+		case GL_TEXTURE_3D_OES:
+			texture = context->getTexture3D();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_MAG_FILTER:
+			*params = texture->getMagFilter();
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			*params = texture->getMinFilter();
+			break;
+		case GL_TEXTURE_WRAP_S:
+			*params = texture->getWrapS();
+			break;
+		case GL_TEXTURE_WRAP_T:
+			*params = texture->getWrapT();
+			break;
+		case GL_TEXTURE_WRAP_R_OES:
+			*params = texture->getWrapR();
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			*params = (GLint)texture->getMaxAnisotropy();
+			break;
+		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+			*params = 1;
+			break;
+		case GL_TEXTURE_BASE_LEVEL:
+			if(clientVersion >= 3)
+			{
+				*params = texture->getBaseLevel();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_COMPARE_FUNC:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getCompareFunc();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_COMPARE_MODE:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getCompareMode();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_IMMUTABLE_FORMAT:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getImmutableFormat();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_IMMUTABLE_LEVELS:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getImmutableLevels();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_MAX_LEVEL:
+			if(clientVersion >= 3)
+			{
+				*params = texture->getMaxLevel();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_MAX_LOD:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)roundf(texture->getMaxLOD());
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_MIN_LOD:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)roundf(texture->getMinLOD());
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_R:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getSwizzleR();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_G:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getSwizzleG();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_B:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getSwizzleB();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_TEXTURE_SWIZZLE_A:
+			if(clientVersion >= 3)
+			{
+				*params = (GLint)texture->getSwizzleA();
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
+	      program, location, bufSize, params);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformfv(location, &bufSize, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void GetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformfv(location, nullptr, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
+	      program, location, bufSize, params);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformiv(location, &bufSize, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void GetUniformiv(GLuint program, GLint location, GLint* params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformiv(location, nullptr, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+int GetUniformLocation(GLuint program, const GLchar* name)
+{
+	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
+
+	es2::Context *context = es2::getContext();
+
+	if(strstr(name, "gl_") == name)
+	{
+		return -1;
+	}
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION, -1);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE, -1);
+			}
+		}
+
+		if(!programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION, -1);
+		}
+
+		return programObject->getUniformLocation(name);
+	}
+
+	return -1;
+}
+
+void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= es2::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(pname)
+		{
+		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+			*params = (GLfloat)attribState.mSize;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+			*params = (GLfloat)attribState.mStride;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+			*params = (GLfloat)attribState.mType;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+			*params = (GLfloat)attribState.mBoundBuffer.name();
+			break;
+		case GL_CURRENT_VERTEX_ATTRIB:
+			{
+				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
+				for(int i = 0; i < 4; ++i)
+				{
+					params[i] = attrib.getCurrentValueF(i);
+				}
+			}
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+			if(clientVersion >= 3)
+			{
+				switch(attribState.mType)
+				{
+				case GL_BYTE:
+				case GL_UNSIGNED_BYTE:
+				case GL_SHORT:
+				case GL_UNSIGNED_SHORT:
+				case GL_INT:
+				case GL_INT_2_10_10_10_REV:
+				case GL_UNSIGNED_INT:
+				case GL_FIXED:
+					*params = (GLfloat)GL_TRUE;
+					break;
+				default:
+					*params = (GLfloat)GL_FALSE;
+					break;
+				}
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		default: return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= es2::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(pname)
+		{
+		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+			*params = attribState.mSize;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+			*params = attribState.mStride;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+			*params = attribState.mType;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+			*params = attribState.mBoundBuffer.name();
+			break;
+		case GL_CURRENT_VERTEX_ATTRIB:
+			{
+				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
+				for(int i = 0; i < 4; ++i)
+				{
+					float currentValue = attrib.getCurrentValueF(i);
+					params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
+				}
+			}
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+			if(clientVersion >= 3)
+			{
+				switch(attribState.mType)
+				{
+				case GL_BYTE:
+				case GL_UNSIGNED_BYTE:
+				case GL_SHORT:
+				case GL_UNSIGNED_SHORT:
+				case GL_INT:
+				case GL_INT_2_10_10_10_REV:
+				case GL_UNSIGNED_INT:
+				case GL_FIXED:
+					*params = GL_TRUE;
+					break;
+				default:
+					*params = GL_FALSE;
+					break;
+				}
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		default: return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= es2::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
+	}
+}
+
+void Hint(GLenum target, GLenum mode)
+{
+	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
+
+	switch(mode)
+	{
+	case GL_FASTEST:
+	case GL_NICEST:
+	case GL_DONT_CARE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+	switch(target)
+	{
+	case GL_GENERATE_MIPMAP_HINT:
+		if(context) context->setGenerateMipmapHint(mode);
+		break;
+	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+		if(context) context->setFragmentShaderDerivativeHint(mode);
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+GLboolean IsBuffer(GLuint buffer)
+{
+	TRACE("(GLuint buffer = %d)", buffer);
+
+	es2::Context *context = es2::getContext();
+
+	if(context && buffer)
+	{
+		es2::Buffer *bufferObject = context->getBuffer(buffer);
+
+		if(bufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsEnabled(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLint clientVersion = context->getClientVersion();
+
+		switch(cap)
+		{
+		case GL_CULL_FACE:                return context->isCullFaceEnabled();
+		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
+		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
+		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
+		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
+		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
+		case GL_BLEND:                    return context->isBlendEnabled();
+		case GL_DITHER:                   return context->isDitherEnabled();
+		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+			if(clientVersion >= 3)
+			{
+				return context->isPrimitiveRestartFixedIndexEnabled();
+			}
+			else return error(GL_INVALID_ENUM, false);
+		case GL_RASTERIZER_DISCARD:
+			if(clientVersion >= 3)
+			{
+				return context->isRasterizerDiscardEnabled();
+			}
+			else return error(GL_INVALID_ENUM, false);
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+	}
+
+	return false;
+}
+
+GLboolean IsFenceNV(GLuint fence)
+{
+	TRACE("(GLuint fence = %d)", fence);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return GL_FALSE;
+		}
+
+		return fenceObject->isFence();
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsFramebuffer(GLuint framebuffer)
+{
+	TRACE("(GLuint framebuffer = %d)", framebuffer);
+
+	es2::Context *context = es2::getContext();
+
+	if(context && framebuffer)
+	{
+		es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
+
+		if(framebufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	es2::Context *context = es2::getContext();
+
+	if(context && program)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(programObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsQueryEXT(GLuint name)
+{
+	TRACE("(GLuint name = %d)", name);
+
+	if(name == 0)
+	{
+		return GL_FALSE;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Query *queryObject = context->getQuery(name);
+
+		if(queryObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsRenderbuffer(GLuint renderbuffer)
+{
+	TRACE("(GLuint renderbuffer = %d)", renderbuffer);
+
+	es2::Context *context = es2::getContext();
+
+	if(context && renderbuffer)
+	{
+		es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
+
+		if(renderbufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsShader(GLuint shader)
+{
+	TRACE("(GLuint shader = %d)", shader);
+
+	es2::Context *context = es2::getContext();
+
+	if(context && shader)
+	{
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(shaderObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsTexture(GLuint texture)
+{
+	TRACE("(GLuint texture = %d)", texture);
+
+	es2::Context *context = es2::getContext();
+
+	if(context && texture)
+	{
+		es2::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+void LineWidth(GLfloat width)
+{
+	TRACE("(GLfloat width = %f)", width);
+
+	if(width <= 0.0f)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setLineWidth(width);
+	}
+}
+
+void LinkProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		programObject->link();
+	}
+}
+
+void PixelStorei(GLenum pname, GLint param)
+{
+	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLint clientVersion = context->getClientVersion();
+
+		switch(pname)
+		{
+		case GL_UNPACK_ALIGNMENT:
+			if(param != 1 && param != 2 && param != 4 && param != 8)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setUnpackAlignment(param);
+			break;
+		case GL_PACK_ALIGNMENT:
+			if(param != 1 && param != 2 && param != 4 && param != 8)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPackAlignment(param);
+			break;
+		case GL_PACK_ROW_LENGTH:
+			if(clientVersion >= 3)
+			{
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setPackRowLength(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_PACK_SKIP_PIXELS:
+			if(clientVersion >= 3)
+			{
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setPackSkipPixels(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_PACK_SKIP_ROWS:
+			if(clientVersion >= 3)
+			{
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setPackSkipRows(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_UNPACK_ROW_LENGTH:
+			if(clientVersion >= 3)
+			{
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setUnpackRowLength(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_UNPACK_IMAGE_HEIGHT:
+			if(clientVersion >= 3)
+			{
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setUnpackImageHeight(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_UNPACK_SKIP_PIXELS:
+			if(clientVersion >= 3)
+			{
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setUnpackSkipPixels(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_UNPACK_SKIP_ROWS:
+			if(clientVersion >= 3)
+			{
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setUnpackSkipRows(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		case GL_UNPACK_SKIP_IMAGES:
+			if(clientVersion >= 3) {
+				if(param < 0)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				context->setUnpackSkipImages(param);
+				break;
+			}
+			else return error(GL_INVALID_ENUM);
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PolygonOffset(GLfloat factor, GLfloat units)
+{
+	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setPolygonOffsetParams(factor, units);
+	}
+}
+
+void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+                    GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
+	      x, y, width, height, format, type, bufSize, data);
+
+	if(width < 0 || height < 0 || bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->readPixels(x, y, width, height, format, type, &bufSize, data);
+	}
+}
+
+void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
+	      x, y, width, height, format, type,  pixels);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
+	}
+}
+
+void ReleaseShaderCompiler(void)
+{
+	TRACE("()");
+
+	es2::Shader::releaseCompiler();
+}
+
+void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+	      target, samples, internalformat, width, height);
+
+	switch(target)
+	{
+	case GL_RENDERBUFFER:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width < 0 || height < 0 || samples < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   samples > es2::IMPLEMENTATION_MAX_SAMPLES)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		GLuint handle = context->getRenderbufferName();
+		if(handle == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLint clientVersion = context->getClientVersion();
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT32F:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			// fall through
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+		case GL_DEPTH_COMPONENT32_OES:
+			context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
+			break;
+		case GL_R8:
+		case GL_R8UI:
+		case GL_R8I:
+		case GL_R16UI:
+		case GL_R16I:
+		case GL_R32UI:
+		case GL_R32I:
+		case GL_RG8:
+		case GL_RG8UI:
+		case GL_RG8I:
+		case GL_RG16UI:
+		case GL_RG16I:
+		case GL_RG32UI:
+		case GL_RG32I:
+		case GL_SRGB8_ALPHA8:
+		case GL_RGB10_A2:
+		case GL_RGBA8UI:
+		case GL_RGBA8I:
+		case GL_RGB10_A2UI:
+		case GL_RGBA16UI:
+		case GL_RGBA16I:
+		case GL_RGBA32I:
+		case GL_RGBA32UI:
+		case GL_R11F_G11F_B10F:
+		case GL_R32F:
+		case GL_RG32F:
+		case GL_RGB32F:
+		case GL_RGBA32F:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			// fall through
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+		case GL_R16F:
+		case GL_RG16F:
+		case GL_RGB16F:
+		case GL_RGBA16F:
+			context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
+			break;
+		case GL_STENCIL_INDEX8:
+			context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
+			break;
+		case GL_DEPTH32F_STENCIL8:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			// fall through
+		case GL_DEPTH24_STENCIL8_OES:
+			context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
+}
+
+void SampleCoverage(GLclampf value, GLboolean invert)
+{
+	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
+
+	es2::Context* context = es2::getContext();
+
+	if(context)
+	{
+		context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
+	}
+}
+
+void SetFenceNV(GLuint fence, GLenum condition)
+{
+	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
+
+	if(condition != GL_ALL_COMPLETED_NV)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		fenceObject->setFence(condition);
+	}
+}
+
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context* context = es2::getContext();
+
+	if(context)
+	{
+		context->setScissorParams(x, y, width, height);
+	}
+}
+
+void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
+	      "const GLvoid* binary = %p, GLsizei length = %d)",
+	      n, shaders, binaryformat, binary, length);
+
+	// No binary shader formats are supported.
+	return error(GL_INVALID_ENUM);
+}
+
+void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
+{
+	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
+	      shader, count, string, length);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Shader *shaderObject = context->getShader(shader);
+
+		if(!shaderObject)
+		{
+			if(context->getProgram(shader))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		shaderObject->setSource(count, string, length);
+	}
+}
+
+void StencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
+}
+
+void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
+
+	switch(face)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(func)
+	{
+	case GL_NEVER:
+	case GL_ALWAYS:
+	case GL_LESS:
+	case GL_LEQUAL:
+	case GL_EQUAL:
+	case GL_GEQUAL:
+	case GL_GREATER:
+	case GL_NOTEQUAL:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilParams(func, ref, mask);
+		}
+
+		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilBackParams(func, ref, mask);
+		}
+	}
+}
+
+void StencilMask(GLuint mask)
+{
+	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
+}
+
+void StencilMaskSeparate(GLenum face, GLuint mask)
+{
+	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
+
+	switch(face)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilWritemask(mask);
+		}
+
+		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilBackWritemask(mask);
+		}
+	}
+}
+
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
+}
+
+void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
+	      face, fail, zfail, zpass);
+
+	switch(face)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(fail)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP:
+	case GL_DECR_WRAP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(zfail)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP:
+	case GL_DECR_WRAP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(zpass)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP:
+	case GL_DECR_WRAP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilOperations(fail, zfail, zpass);
+		}
+
+		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
+		{
+			context->setStencilBackOperations(fail, zfail, zpass);
+		}
+	}
+}
+
+GLboolean TestFenceNV(GLuint fence)
+{
+	TRACE("(GLuint fence = %d)", fence);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Fence *fenceObject = context->getFence(fence);
+
+		if(!fenceObject)
+		{
+			return error(GL_INVALID_OPERATION, GL_TRUE);
+		}
+
+		return fenceObject->testFence();
+	}
+
+	return GL_TRUE;
+}
+
+void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
+	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",
+	      target, level, internalformat, width, height, border, format, type, pixels);
+
+	if(!validImageSize(level, width, height))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLint clientVersion = context->getClientVersion();
+		if(clientVersion < 3)
+		{
+			if(internalformat != (GLint)format)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
+		GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);
+		if(validationError != GL_NONE)
+		{
+			return error(validationError);
+		}
+
+		if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
+		{
+			return;
+		}
+
+		if(border != 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+			if(width != height)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
+			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es2::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
+		}
+		else
+		{
+			es2::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
+		}
+	}
+}
+
+void TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture *texture;
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			else
+			{
+				texture = context->getTexture2DArray();
+			}
+			break;
+		case GL_TEXTURE_3D_OES:
+			texture = context->getTexture3D();
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_WRAP_S:
+			if(!texture->setWrapS((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_T:
+			if(!texture->setWrapT((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_R_OES:
+			if(!texture->setWrapR((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			if(!texture->setMinFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAG_FILTER:
+			if(!texture->setMagFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			if(!texture->setMaxAnisotropy(param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_BASE_LEVEL:
+			if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_COMPARE_FUNC:
+			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_COMPARE_MODE:
+			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MAX_LEVEL:
+			if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MAX_LOD:
+			if(clientVersion < 3 || !texture->setMaxLOD(param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MIN_LOD:
+			if(clientVersion < 3 || !texture->setMinLOD(param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_R:
+			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_G:
+			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_B:
+			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_A:
+			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	glTexParameterf(target, pname, *params);
+}
+
+void TexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture *texture;
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			else
+			{
+				texture = context->getTexture2DArray();
+			}
+			break;
+		case GL_TEXTURE_3D_OES:
+			texture = context->getTexture3D();
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			texture = context->getTextureCubeMap();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_WRAP_S:
+			if(!texture->setWrapS((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_T:
+			if(!texture->setWrapT((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_WRAP_R_OES:
+			if(!texture->setWrapR((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MIN_FILTER:
+			if(!texture->setMinFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAG_FILTER:
+			if(!texture->setMagFilter((GLenum)param))
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+			if(!texture->setMaxAnisotropy((GLfloat)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_BASE_LEVEL:
+			if(clientVersion < 3 || !texture->setBaseLevel(param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_COMPARE_FUNC:
+			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_COMPARE_MODE:
+			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MAX_LEVEL:
+			if(clientVersion < 3 || !texture->setMaxLevel(param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MAX_LOD:
+			if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_MIN_LOD:
+			if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_R:
+			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_G:
+			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_B:
+			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		case GL_TEXTURE_SWIZZLE_A:
+			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	glTexParameteri(target, pname, *params);
+}
+
+void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                   GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
+	      "const GLvoid* pixels = %p)",
+	      target, level, xoffset, yoffset, width, height, format, type, pixels);
+
+	if(!es2::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
+	{
+		return;
+	}
+
+	if(width == 0 || height == 0 || !pixels)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es2::Texture2D *texture = context->getTexture2D();
+
+			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
+
+			if(validationError == GL_NONE)
+			{
+				texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
+			}
+			else
+			{
+				return error(validationError);
+			}
+		}
+		else if(es2::IsCubemapTextureTarget(target))
+		{
+			es2::TextureCubeMap *texture = context->getTextureCubeMap();
+
+			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
+
+			if(validationError == GL_NONE)
+			{
+				texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
+			}
+			else
+			{
+				return error(validationError);
+			}
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void Uniform1f(GLint location, GLfloat x)
+{
+	glUniform1fv(location, 1, &x);
+}
+
+void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform1fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Uniform1i(GLint location, GLint x)
+{
+	glUniform1iv(location, 1, &x);
+}
+
+void Uniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform1iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Uniform2f(GLint location, GLfloat x, GLfloat y)
+{
+	GLfloat xy[2] = {x, y};
+
+	glUniform2fv(location, 1, (GLfloat*)&xy);
+}
+
+void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform2fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Uniform2i(GLint location, GLint x, GLint y)
+{
+	GLint xy[4] = {x, y};
+
+	glUniform2iv(location, 1, (GLint*)&xy);
+}
+
+void Uniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform2iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+	GLfloat xyz[3] = {x, y, z};
+
+	glUniform3fv(location, 1, (GLfloat*)&xyz);
+}
+
+void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform3fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Uniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+	GLint xyz[3] = {x, y, z};
+
+	glUniform3iv(location, 1, (GLint*)&xyz);
+}
+
+void Uniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform3iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	GLfloat xyzw[4] = {x, y, z, w};
+
+	glUniform4fv(location, 1, (GLfloat*)&xyzw);
+}
+
+void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform4fv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+	GLint xyzw[4] = {x, y, z, w};
+
+	glUniform4iv(location, 1, (GLint*)&xyzw);
+}
+
+void Uniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform4iv(location, count, v))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
+	      location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix2fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
+	      location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix3fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
+	      location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix4fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+void UseProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject && program != 0)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if(program != 0 && !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->useProgram(program);
+	}
+}
+
+void ValidateProgram(GLuint program)
+{
+	TRACE("(GLuint program = %d)", program);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		programObject->validate();
+	}
+}
+
+void VertexAttrib1f(GLuint index, GLfloat x)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLfloat vals[4] = { x, 0, 0, 1 };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+void VertexAttrib1fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLfloat vals[4] = { values[0], 0, 0, 1 };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLfloat vals[4] = { x, y, 0, 1 };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+void VertexAttrib2fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLfloat vals[4] = { values[0], values[1], 0, 1 };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLfloat vals[4] = { x, y, z, 1 };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+void VertexAttrib3fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLfloat vals[4] = { values[0], values[1], values[2], 1 };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLfloat vals[4] = { x, y, z, w };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+void VertexAttrib4fv(GLuint index, const GLfloat* values)
+{
+	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(index, values);
+	}
+}
+
+void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
+	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
+	      index, size, type, normalized, stride, ptr);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(size < 1 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	GLint clientVersion = egl::getClientVersion();
+
+	switch(type)
+	{
+	case GL_BYTE:
+	case GL_UNSIGNED_BYTE:
+	case GL_SHORT:
+	case GL_UNSIGNED_SHORT:
+	case GL_FIXED:
+	case GL_FLOAT:
+		break;
+	case GL_INT_2_10_10_10_REV:
+	case GL_UNSIGNED_INT_2_10_10_10_REV:
+		if(clientVersion >= 3)
+		{
+			if(size != 4)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		}
+		else return error(GL_INVALID_ENUM);
+	case GL_INT:
+	case GL_UNSIGNED_INT:
+	case GL_HALF_FLOAT:
+		if(clientVersion >= 3)
+		{
+			break;
+		}
+		else return error(GL_INVALID_ENUM);
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(stride < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
+	}
+}
+
+void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setViewportParams(x, y, width, height);
+	}
+}
+
+void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+{
+	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
+	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
+	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+	switch(filter)
+	{
+	case GL_NEAREST:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(context->getReadFramebufferName() == context->getDrawFramebufferName())
+		{
+			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
+	}
+}
+
+void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                          GLbitfield mask, GLenum filter)
+{
+	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
+	{
+		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
+		return error(GL_INVALID_OPERATION);
+	}
+
+	glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+                   GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
+	      target, level, internalformat, width, height, depth, border, format, type, pixels);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D_OES:
+		switch(format)
+		{
+		case GL_DEPTH_COMPONENT:
+		case GL_DEPTH_STENCIL_OES:
+			return error(GL_INVALID_OPERATION);
+		default:
+			break;
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
+	{
+		return;
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
+	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = context->getTexture3D();
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);
+	}
+}
+
+void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
+	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
+	{
+		return;
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if((width < 0) || (height < 0) || (depth < 0))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = context->getTexture3D();
+
+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+
+		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
+		if(validationError == GL_NONE)
+		{
+			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
+		}
+		else
+		{
+			return error(validationError);
+		}
+	}
+}
+
+void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+	      target, level, xoffset, yoffset, zoffset, x, y, width, height);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
+
+		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
+
+		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es2::Texture3D *texture = context->getTexture3D();
+
+		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
+
+		if(validationError != GL_NONE)
+		{
+			return error(validationError);
+		}
+
+		texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
+	}
+}
+
+void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+	      "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
+	      target, level, internalformat, width, height, depth, border, imageSize, data);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
+	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(internalformat)
+	{
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_COMPONENT16:
+	case GL_DEPTH_COMPONENT32_OES:
+	case GL_DEPTH_STENCIL_OES:
+	case GL_DEPTH24_STENCIL8_OES:
+		return error(GL_INVALID_OPERATION);
+	default:
+		{
+			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
+			if(validationError != GL_NONE)
+			{
+				return error(validationError);
+			}
+		}
+	}
+
+	if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = context->getTexture3D();
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+	}
+}
+
+void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
+	      "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
+	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
+	if(validationError != GL_NONE)
+	{
+		return error(validationError);
+	}
+
+	if(width == 0 || height == 0 || depth == 0 || !data)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = context->getTexture3D();
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+	}
+}
+
+void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
+	      "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
+
+	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(texture == 0)
+		{
+			textarget = GL_NONE;
+		}
+		else
+		{
+			es2::Texture *tex = context->getTexture(texture);
+
+			if(!tex)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			if(tex->isCompressed(textarget, level))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			switch(textarget)
+			{
+			case GL_TEXTURE_3D_OES:
+				if(tex->getTarget() != GL_TEXTURE_3D_OES)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(level != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		es2::Framebuffer *framebuffer = nullptr;
+		GLuint framebufferName = 0;
+		if(target == GL_READ_FRAMEBUFFER_ANGLE)
+		{
+			framebuffer = context->getReadFramebuffer();
+			framebufferName = context->getReadFramebufferName();
+		}
+		else
+		{
+			framebuffer = context->getDrawFramebuffer();
+			framebufferName = context->getDrawFramebufferName();
+		}
+
+		if(framebufferName == 0 || !framebuffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLint clientVersion = context->getClientVersion();
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT1:
+		case GL_COLOR_ATTACHMENT2:
+		case GL_COLOR_ATTACHMENT3:
+		case GL_COLOR_ATTACHMENT4:
+		case GL_COLOR_ATTACHMENT5:
+		case GL_COLOR_ATTACHMENT6:
+		case GL_COLOR_ATTACHMENT7:
+		case GL_COLOR_ATTACHMENT8:
+		case GL_COLOR_ATTACHMENT9:
+		case GL_COLOR_ATTACHMENT10:
+		case GL_COLOR_ATTACHMENT11:
+		case GL_COLOR_ATTACHMENT12:
+		case GL_COLOR_ATTACHMENT13:
+		case GL_COLOR_ATTACHMENT14:
+		case GL_COLOR_ATTACHMENT15:
+		case GL_COLOR_ATTACHMENT16:
+		case GL_COLOR_ATTACHMENT17:
+		case GL_COLOR_ATTACHMENT18:
+		case GL_COLOR_ATTACHMENT19:
+		case GL_COLOR_ATTACHMENT20:
+		case GL_COLOR_ATTACHMENT21:
+		case GL_COLOR_ATTACHMENT22:
+		case GL_COLOR_ATTACHMENT23:
+		case GL_COLOR_ATTACHMENT24:
+		case GL_COLOR_ATTACHMENT25:
+		case GL_COLOR_ATTACHMENT26:
+		case GL_COLOR_ATTACHMENT27:
+		case GL_COLOR_ATTACHMENT28:
+		case GL_COLOR_ATTACHMENT29:
+		case GL_COLOR_ATTACHMENT30:
+		case GL_COLOR_ATTACHMENT31:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			// fall through
+		case GL_COLOR_ATTACHMENT0:
+			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
+			break;
+		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
+		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	if(egl::getClientVersion() == 1)
+	{
+		return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
+	}
+
+	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
+
+	switch(target)
+	{
+	case GL_TEXTURE_2D:
+	case GL_TEXTURE_EXTERNAL_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture2D *texture = 0;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;
+		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
+		default:                      UNREACHABLE(target);
+		}
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		egl::Image *glImage = static_cast<egl::Image*>(image);
+
+		texture->setImage(glImage);
+	}
+}
+
+void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
+
+	UNIMPLEMENTED();
+}
+
+GLboolean IsRenderbufferOES(GLuint renderbuffer)
+{
+	return IsRenderbuffer(renderbuffer);
+}
+
+void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+	BindRenderbuffer(target, renderbuffer);
+}
+
+void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+	DeleteRenderbuffers(n, renderbuffers);
+}
+
+void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+	GenRenderbuffers(n, renderbuffers);
+}
+
+void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	RenderbufferStorage(target, internalformat, width, height);
+}
+
+void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+	GetRenderbufferParameteriv(target, pname, params);
+}
+
+GLboolean IsFramebufferOES(GLuint framebuffer)
+{
+	return IsFramebuffer(framebuffer);
+}
+
+void BindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+	BindFramebuffer(target, framebuffer);
+}
+
+void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+	DeleteFramebuffers(n, framebuffers);
+}
+
+void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+	GenFramebuffers(n, framebuffers);
+}
+
+GLenum CheckFramebufferStatusOES(GLenum target)
+{
+	return CheckFramebufferStatus(target);
+}
+
+void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
+void GenerateMipmapOES(GLenum target)
+{
+	GenerateMipmap(target);
+}
+
+void DrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+	TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
+
+	if(n < 0 || n > MAX_DRAW_BUFFERS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLuint drawFramebufferName = context->getDrawFramebufferName();
+
+		if((drawFramebufferName == 0) && (n != 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		for(unsigned int i = 0; i < (unsigned)n; i++)
+		{
+			switch(bufs[i])
+			{
+			case GL_BACK:
+				if(drawFramebufferName != 0)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			case GL_NONE:
+				break;
+			case GL_COLOR_ATTACHMENT0_EXT:
+			case GL_COLOR_ATTACHMENT1_EXT:
+			case GL_COLOR_ATTACHMENT2_EXT:
+			case GL_COLOR_ATTACHMENT3_EXT:
+			case GL_COLOR_ATTACHMENT4_EXT:
+			case GL_COLOR_ATTACHMENT5_EXT:
+			case GL_COLOR_ATTACHMENT6_EXT:
+			case GL_COLOR_ATTACHMENT7_EXT:
+			case GL_COLOR_ATTACHMENT8_EXT:
+			case GL_COLOR_ATTACHMENT9_EXT:
+			case GL_COLOR_ATTACHMENT10_EXT:
+			case GL_COLOR_ATTACHMENT11_EXT:
+			case GL_COLOR_ATTACHMENT12_EXT:
+			case GL_COLOR_ATTACHMENT13_EXT:
+			case GL_COLOR_ATTACHMENT14_EXT:
+			case GL_COLOR_ATTACHMENT15_EXT:
+				{
+					GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);
+
+					if(index >= MAX_COLOR_ATTACHMENTS)
+					{
+						return error(GL_INVALID_OPERATION);
+					}
+
+					if(index != i)
+					{
+						return error(GL_INVALID_OPERATION);
+					}
+
+					if(drawFramebufferName == 0)
+					{
+						return error(GL_INVALID_OPERATION);
+					}
+				}
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+		}
+
+		context->setFramebufferDrawBuffers(n, bufs);
+	}
+}
+
+}
+
+extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
+{
+	struct Extension
+	{
+		const char *name;
+		__eglMustCastToProperFunctionPointerType address;
+	};
+
+	static const Extension glExtensions[] =
+	{
+		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+		EXTENSION(glTexImage3DOES),
+		EXTENSION(glBlitFramebufferANGLE),
+		EXTENSION(glBlitFramebufferNV),
+		EXTENSION(glRenderbufferStorageMultisampleANGLE),
+		EXTENSION(glDeleteFencesNV),
+		EXTENSION(glGenFencesNV),
+		EXTENSION(glIsFenceNV),
+		EXTENSION(glTestFenceNV),
+		EXTENSION(glGetFenceivNV),
+		EXTENSION(glFinishFenceNV),
+		EXTENSION(glSetFenceNV),
+		EXTENSION(glGetGraphicsResetStatusEXT),
+		EXTENSION(glReadnPixelsEXT),
+		EXTENSION(glGetnUniformfvEXT),
+		EXTENSION(glGetnUniformivEXT),
+		EXTENSION(glGenQueriesEXT),
+		EXTENSION(glDeleteQueriesEXT),
+		EXTENSION(glIsQueryEXT),
+		EXTENSION(glBeginQueryEXT),
+		EXTENSION(glEndQueryEXT),
+		EXTENSION(glGetQueryivEXT),
+		EXTENSION(glGetQueryObjectuivEXT),
+		EXTENSION(glEGLImageTargetTexture2DOES),
+		EXTENSION(glEGLImageTargetRenderbufferStorageOES),
+		EXTENSION(glDrawElementsInstancedEXT),
+		EXTENSION(glDrawArraysInstancedEXT),
+		EXTENSION(glVertexAttribDivisorEXT),
+		EXTENSION(glDrawArraysInstancedANGLE),
+		EXTENSION(glDrawElementsInstancedANGLE),
+		EXTENSION(glVertexAttribDivisorANGLE),
+		EXTENSION(glIsRenderbufferOES),
+		EXTENSION(glBindRenderbufferOES),
+		EXTENSION(glDeleteRenderbuffersOES),
+		EXTENSION(glGenRenderbuffersOES),
+		EXTENSION(glRenderbufferStorageOES),
+		EXTENSION(glGetRenderbufferParameterivOES),
+		EXTENSION(glIsFramebufferOES),
+		EXTENSION(glBindFramebufferOES),
+		EXTENSION(glDeleteFramebuffersOES),
+		EXTENSION(glGenFramebuffersOES),
+		EXTENSION(glCheckFramebufferStatusOES),
+		EXTENSION(glFramebufferRenderbufferOES),
+		EXTENSION(glFramebufferTexture2DOES),
+		EXTENSION(glGetFramebufferAttachmentParameterivOES),
+		EXTENSION(glGenerateMipmapOES),
+		EXTENSION(glDrawBuffersEXT),
+
+		#undef EXTENSION
+	};
+
+	for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
+	{
+		if(strcmp(procname, glExtensions[ext].name) == 0)
+		{
+			return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
+		}
+	}
+
+	return nullptr;
+}
diff --git a/src/OpenGL/libGLESv2/libGLESv2.rc b/src/OpenGL/libGLESv2/libGLESv2.rc
index 7c89314..5b961a9 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.rc
+++ b/src/OpenGL/libGLESv2/libGLESv2.rc
@@ -28,18 +28,18 @@
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE 
+1 TEXTINCLUDE
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE 
+2 TEXTINCLUDE
 BEGIN
     "#include ""afxres.h""\r\n"
     "#include ""../common/version.h""\0"
 END
 
-3 TEXTINCLUDE 
+3 TEXTINCLUDE
 BEGIN
     "\r\n"
     "\0"
@@ -74,10 +74,10 @@
 				VALUE "FileDescription", "SwiftShader libGLESv2 64-bit Dynamic Link Library"
 			#else
 				VALUE "FileDescription", "SwiftShader libGLESv2 32-bit Dynamic Link Library"
-			#endif             
+			#endif
             VALUE "FileVersion", VERSION_STRING
             VALUE "InternalName", "libGLESv2"
-            VALUE "LegalCopyright", "Copyright (C) 2012 TransGaming Inc."
+            VALUE "LegalCopyright", "Copyright (C) 2016 Google Inc."
             VALUE "OriginalFilename", "libGLESv2.dll"
             VALUE "PrivateBuild", VERSION_STRING
             VALUE "ProductName", "SwiftShader libGLESv2 Dynamic Link Library"
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 3e0d25f..efa16c1 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1,4047 +1,4051 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-// libGLESv3.cpp: Implements the exported OpenGL ES 3.0 functions.

-

-#include "main.h"

-#include "Buffer.h"

-#include "Fence.h"

-#include "Framebuffer.h"

-#include "Program.h"

-#include "Query.h"

-#include "Sampler.h"

-#include "Texture.h"

-#include "mathutil.h"

-#include "TransformFeedback.h"

-#include "common/debug.h"

-

-#include <GLES3/gl3.h>

-#include <GLES2/gl2ext.h>

-

-#include <limits.h>

-

-using namespace es2;

-

-typedef std::pair<GLenum, GLenum> InternalFormatTypePair;

-typedef std::map<InternalFormatTypePair, GLenum> FormatMap;

-

-// A helper function to insert data into the format map with fewer characters.

-static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)

-{

-	map[InternalFormatTypePair(internalformat, type)] = format;

-}

-

-static bool validImageSize(GLint level, GLsizei width, GLsizei height)

-{

-	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)

-	{

-		return false;

-	}

-

-	return true;

-}

-

-

-static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)

-{

-	GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);

-	if(validationError != GL_NONE)

-	{

-		return error(validationError, false);

-	}

-

-	switch(textureFormat)

-	{

-	case GL_ALPHA:

-		if(colorbufferFormat != GL_ALPHA &&

-		   colorbufferFormat != GL_RGBA &&

-		   colorbufferFormat != GL_RGBA4 &&

-		   colorbufferFormat != GL_RGB5_A1 &&

-		   colorbufferFormat != GL_RGBA8)

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-		break;

-	case GL_LUMINANCE:

-	case GL_RGB:

-		if(colorbufferFormat != GL_RGB &&

-		   colorbufferFormat != GL_RGB565 &&

-		   colorbufferFormat != GL_RGB8 &&

-		   colorbufferFormat != GL_RGBA &&

-		   colorbufferFormat != GL_RGBA4 &&

-		   colorbufferFormat != GL_RGB5_A1 &&

-		   colorbufferFormat != GL_RGBA8)

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-		break;

-	case GL_LUMINANCE_ALPHA:

-	case GL_RGBA:

-		if(colorbufferFormat != GL_RGBA &&

-		   colorbufferFormat != GL_RGBA4 &&

-		   colorbufferFormat != GL_RGB5_A1 &&

-		   colorbufferFormat != GL_RGBA8)

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-		break;

-	case GL_DEPTH_COMPONENT:

-	case GL_DEPTH_STENCIL:

-		return error(GL_INVALID_OPERATION, false);

-	default:

-		return error(GL_INVALID_ENUM, false);

-	}

-	return true;

-}

-

-static FormatMap BuildFormatMap3D()

-{

-	FormatMap map;

-

-	//                       Internal format | Format | Type

-	InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);

-	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);

-	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);

-	InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_R8, GL_RED, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_R8_SNORM, GL_RED, GL_BYTE);

-	InsertFormatMapping(map, GL_R16F, GL_RED, GL_HALF_FLOAT);

-	InsertFormatMapping(map, GL_R16F, GL_RED, GL_FLOAT);

-	InsertFormatMapping(map, GL_R32F, GL_RED, GL_FLOAT);

-	InsertFormatMapping(map, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_R8I, GL_RED_INTEGER, GL_BYTE);

-	InsertFormatMapping(map, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT);

-	InsertFormatMapping(map, GL_R16I, GL_RED_INTEGER, GL_SHORT);

-	InsertFormatMapping(map, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);

-	InsertFormatMapping(map, GL_R32I, GL_RED_INTEGER, GL_INT);

-	InsertFormatMapping(map, GL_RG8, GL_RG, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RG8_SNORM, GL_RG, GL_BYTE);

-	InsertFormatMapping(map, GL_RG16F, GL_RG, GL_HALF_FLOAT);

-	InsertFormatMapping(map, GL_RG16F, GL_RG, GL_FLOAT);

-	InsertFormatMapping(map, GL_RG32F, GL_RG, GL_FLOAT);

-	InsertFormatMapping(map, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RG8I, GL_RG_INTEGER, GL_BYTE);

-	InsertFormatMapping(map, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT);

-	InsertFormatMapping(map, GL_RG16I, GL_RG_INTEGER, GL_SHORT);

-	InsertFormatMapping(map, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT);

-	InsertFormatMapping(map, GL_RG32I, GL_RG_INTEGER, GL_INT);

-	InsertFormatMapping(map, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);

-	InsertFormatMapping(map, GL_RGB8_SNORM, GL_RGB, GL_BYTE);

-	InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV);

-	InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT);

-	InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);

-	InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV);

-	InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT);

-	InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_FLOAT);

-	InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_HALF_FLOAT);

-	InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_FLOAT);

-	InsertFormatMapping(map, GL_RGB32F, GL_RGB, GL_FLOAT);

-	InsertFormatMapping(map, GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGB8I, GL_RGB_INTEGER, GL_BYTE);

-	InsertFormatMapping(map, GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT);

-	InsertFormatMapping(map, GL_RGB16I, GL_RGB_INTEGER, GL_SHORT);

-	InsertFormatMapping(map, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT);

-	InsertFormatMapping(map, GL_RGB32I, GL_RGB_INTEGER, GL_INT);

-	InsertFormatMapping(map, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);

-	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);

-	InsertFormatMapping(map, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE);

-	InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);

-	InsertFormatMapping(map, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);

-	InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);

-	InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_FLOAT);

-	InsertFormatMapping(map, GL_RGBA32F, GL_RGBA, GL_FLOAT);

-	InsertFormatMapping(map, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE);

-	InsertFormatMapping(map, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE);

-	InsertFormatMapping(map, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV);

-	InsertFormatMapping(map, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT);

-	InsertFormatMapping(map, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT);

-	InsertFormatMapping(map, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);

-	InsertFormatMapping(map, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);

-

-	InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);

-	InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);

-	InsertFormatMapping(map, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);

-	InsertFormatMapping(map, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);

-	InsertFormatMapping(map, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);

-	InsertFormatMapping(map, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);

-	InsertFormatMapping(map, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);

-

-	return map;

-}

-

-static bool ValidateType3D(GLenum type)

-{

-	switch(type)

-	{

-	case GL_UNSIGNED_BYTE:

-	case GL_BYTE:

-	case GL_UNSIGNED_SHORT:

-	case GL_SHORT:

-	case GL_UNSIGNED_INT:

-	case GL_INT:

-	case GL_HALF_FLOAT:

-	case GL_FLOAT:

-	case GL_UNSIGNED_SHORT_5_6_5:

-	case GL_UNSIGNED_SHORT_4_4_4_4:

-	case GL_UNSIGNED_SHORT_5_5_5_1:

-	case GL_UNSIGNED_INT_2_10_10_10_REV:

-	case GL_UNSIGNED_INT_10F_11F_11F_REV:

-	case GL_UNSIGNED_INT_5_9_9_9_REV:

-	case GL_UNSIGNED_INT_24_8:

-	case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:

-		return true;

-	default:

-		break;

-	}

-	return false;

-}

-

-static bool ValidateFormat3D(GLenum format)

-{

-	switch(format)

-	{

-	case GL_RED:

-	case GL_RG:

-	case GL_RGB:

-	case GL_RGBA:

-	case GL_DEPTH_COMPONENT:

-	case GL_DEPTH_STENCIL:

-	case GL_LUMINANCE_ALPHA:

-	case GL_LUMINANCE:

-	case GL_ALPHA:

-	case GL_RED_INTEGER:

-	case GL_RG_INTEGER:

-	case GL_RGB_INTEGER:

-	case GL_RGBA_INTEGER:

-		return true;

-	default:

-		break;

-	}

-	return false;

-}

-

-static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)

-{

-	static const FormatMap formatMap = BuildFormatMap3D();

-	FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));

-	if(iter != formatMap.end())

-	{

-		return iter->second == format;

-	}

-	return false;

-}

-

-typedef std::map<GLenum, GLenum> FormatMapStorage;

-

-// A helper function to insert data into the format map with fewer characters.

-static void InsertFormatStorageMapping(FormatMapStorage& map, GLenum internalformat, GLenum type)

-{

-	map[internalformat] = type;

-}

-

-static FormatMapStorage BuildFormatMapStorage2D()

-{

-	FormatMapStorage map;

-

-	//                              Internal format | Type

-	InsertFormatStorageMapping(map, GL_R8, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_R8_SNORM, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_R16F, GL_HALF_FLOAT);

-	InsertFormatStorageMapping(map, GL_R32F, GL_FLOAT);

-	InsertFormatStorageMapping(map, GL_R8UI, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_R8I, GL_BYTE);

-	InsertFormatStorageMapping(map, GL_R16UI, GL_UNSIGNED_SHORT);

-	InsertFormatStorageMapping(map, GL_R16I, GL_SHORT);

-	InsertFormatStorageMapping(map, GL_R32UI, GL_UNSIGNED_INT);

-	InsertFormatStorageMapping(map, GL_R32I, GL_INT);

-	InsertFormatStorageMapping(map, GL_RG8, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_RG8_SNORM, GL_BYTE);

-	InsertFormatStorageMapping(map, GL_RG16F, GL_HALF_FLOAT);

-	InsertFormatStorageMapping(map, GL_RG32F, GL_FLOAT);

-	InsertFormatStorageMapping(map, GL_RG8UI, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_RG8I, GL_BYTE);

-	InsertFormatStorageMapping(map, GL_RG16UI, GL_UNSIGNED_SHORT);

-	InsertFormatStorageMapping(map, GL_RG16I, GL_SHORT);

-	InsertFormatStorageMapping(map, GL_RG32UI, GL_UNSIGNED_INT);

-	InsertFormatStorageMapping(map, GL_RG32I, GL_INT);

-	InsertFormatStorageMapping(map, GL_RGB8, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_SRGB8, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5);

-	InsertFormatStorageMapping(map, GL_RGB8_SNORM, GL_BYTE);

-	InsertFormatStorageMapping(map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV);

-	InsertFormatStorageMapping(map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV);

-	InsertFormatStorageMapping(map, GL_RGB16F, GL_HALF_FLOAT);

-	InsertFormatStorageMapping(map, GL_RGB32F, GL_FLOAT);

-	InsertFormatStorageMapping(map, GL_RGB8UI, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_RGB8I, GL_BYTE);

-	InsertFormatStorageMapping(map, GL_RGB16UI, GL_UNSIGNED_SHORT);

-	InsertFormatStorageMapping(map, GL_RGB16I, GL_SHORT);

-	InsertFormatStorageMapping(map, GL_RGB32UI, GL_UNSIGNED_INT);

-	InsertFormatStorageMapping(map, GL_RGB32I, GL_INT);

-	InsertFormatStorageMapping(map, GL_RGBA8, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_RGBA8_SNORM, GL_BYTE);

-	InsertFormatStorageMapping(map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);

-	InsertFormatStorageMapping(map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);

-	InsertFormatStorageMapping(map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV);

-	InsertFormatStorageMapping(map, GL_RGBA16F, GL_HALF_FLOAT);

-	InsertFormatStorageMapping(map, GL_RGBA32F, GL_FLOAT);

-	InsertFormatStorageMapping(map, GL_RGBA8UI, GL_UNSIGNED_BYTE);

-	InsertFormatStorageMapping(map, GL_RGBA8I, GL_BYTE);

-	InsertFormatStorageMapping(map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV);

-	InsertFormatStorageMapping(map, GL_RGBA16UI, GL_UNSIGNED_SHORT);

-	InsertFormatStorageMapping(map, GL_RGBA16I, GL_SHORT);

-	InsertFormatStorageMapping(map, GL_RGBA32UI, GL_UNSIGNED_INT);

-	InsertFormatStorageMapping(map, GL_RGBA32I, GL_INT);

-

-	InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT);

-	InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT);

-	InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT32F, GL_FLOAT);

-	InsertFormatStorageMapping(map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8);

-	InsertFormatStorageMapping(map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);

-

-	return map;

-}

-

-static bool GetStorageType(GLenum internalformat, GLenum& type)

-{

-	static const FormatMapStorage formatMap = BuildFormatMapStorage2D();

-	FormatMapStorage::const_iterator iter = formatMap.find(internalformat);

-	if(iter != formatMap.end())

-	{

-		type = iter->second;

-		return true;

-	}

-	return false;

-}

-

-static bool ValidateQueryTarget(GLenum target)

-{

-	switch(target)

-	{

-	case GL_ANY_SAMPLES_PASSED:

-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:

-	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:

-		break;

-	default:

-		return false;

-	}

-

-	return true;

-}

-

-bool ValidateTexParamParameters(GLenum pname, GLint param)

-{

-	switch(pname)

-	{

-	case GL_TEXTURE_WRAP_S:

-	case GL_TEXTURE_WRAP_T:

-	case GL_TEXTURE_WRAP_R:

-		switch(param)

-		{

-		case GL_REPEAT:

-		case GL_CLAMP_TO_EDGE:

-		case GL_MIRRORED_REPEAT:

-			return true;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-

-	case GL_TEXTURE_MIN_FILTER:

-		switch(param)

-		{

-		case GL_NEAREST:

-		case GL_LINEAR:

-		case GL_NEAREST_MIPMAP_NEAREST:

-		case GL_LINEAR_MIPMAP_NEAREST:

-		case GL_NEAREST_MIPMAP_LINEAR:

-		case GL_LINEAR_MIPMAP_LINEAR:

-			return true;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-		break;

-

-	case GL_TEXTURE_MAG_FILTER:

-		switch(param)

-		{

-		case GL_NEAREST:

-		case GL_LINEAR:

-			return true;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-		break;

-

-	case GL_TEXTURE_USAGE_ANGLE:

-		switch(param)

-		{

-		case GL_NONE:

-		case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:

-			return true;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-		break;

-

-	case GL_TEXTURE_MAX_ANISOTROPY_EXT:

-		// we assume the parameter passed to this validation method is truncated, not rounded

-		if(param < 1)

-		{

-			return error(GL_INVALID_VALUE, false);

-		}

-		return true;

-

-	case GL_TEXTURE_MIN_LOD:

-	case GL_TEXTURE_MAX_LOD:

-		// any value is permissible

-		return true;

-

-	case GL_TEXTURE_COMPARE_MODE:

-		// Acceptable mode parameters from GLES 3.0.2 spec, table 3.17

-		switch(param)

-		{

-		case GL_NONE:

-		case GL_COMPARE_REF_TO_TEXTURE:

-			return true;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-		break;

-

-	case GL_TEXTURE_COMPARE_FUNC:

-		// Acceptable function parameters from GLES 3.0.2 spec, table 3.17

-		switch(param)

-		{

-		case GL_LEQUAL:

-		case GL_GEQUAL:

-		case GL_LESS:

-		case GL_GREATER:

-		case GL_EQUAL:

-		case GL_NOTEQUAL:

-		case GL_ALWAYS:

-		case GL_NEVER:

-			return true;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-		break;

-

-	case GL_TEXTURE_SWIZZLE_R:

-	case GL_TEXTURE_SWIZZLE_G:

-	case GL_TEXTURE_SWIZZLE_B:

-	case GL_TEXTURE_SWIZZLE_A:

-		switch(param)

-		{

-		case GL_RED:

-		case GL_GREEN:

-		case GL_BLUE:

-		case GL_ALPHA:

-		case GL_ZERO:

-		case GL_ONE:

-			return true;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-		break;

-

-	case GL_TEXTURE_BASE_LEVEL:

-	case GL_TEXTURE_MAX_LEVEL:

-		if(param < 0)

-		{

-			return error(GL_INVALID_VALUE, false);

-		}

-		return true;

-

-	default:

-		return error(GL_INVALID_ENUM, false);

-	}

-}

-

-static bool ValidateSamplerObjectParameter(GLenum pname)

-{

-	switch(pname)

-	{

-	case GL_TEXTURE_MIN_FILTER:

-	case GL_TEXTURE_MAG_FILTER:

-	case GL_TEXTURE_WRAP_S:

-	case GL_TEXTURE_WRAP_T:

-	case GL_TEXTURE_WRAP_R:

-	case GL_TEXTURE_MIN_LOD:

-	case GL_TEXTURE_MAX_LOD:

-	case GL_TEXTURE_COMPARE_MODE:

-	case GL_TEXTURE_COMPARE_FUNC:

-		return true;

-	default:

-		return false;

-	}

-}

-

-extern "C"

-{

-

-GL_APICALL void GL_APIENTRY glReadBuffer(GLenum src)

-{

-	TRACE("(GLenum src = 0x%X)", src);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLuint readFramebufferName = context->getReadFramebufferName();

-

-		switch(src)

-		{

-		case GL_BACK:

-			if(readFramebufferName != 0)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			context->setFramebufferReadBuffer(src);

-			break;

-		case GL_NONE:

-			context->setFramebufferReadBuffer(src);

-			break;

-		case GL_COLOR_ATTACHMENT0:

-		case GL_COLOR_ATTACHMENT1:

-		case GL_COLOR_ATTACHMENT2:

-		case GL_COLOR_ATTACHMENT3:

-		case GL_COLOR_ATTACHMENT4:

-		case GL_COLOR_ATTACHMENT5:

-		case GL_COLOR_ATTACHMENT6:

-		case GL_COLOR_ATTACHMENT7:

-		case GL_COLOR_ATTACHMENT8:

-		case GL_COLOR_ATTACHMENT9:

-		case GL_COLOR_ATTACHMENT10:

-		case GL_COLOR_ATTACHMENT11:

-		case GL_COLOR_ATTACHMENT12:

-		case GL_COLOR_ATTACHMENT13:

-		case GL_COLOR_ATTACHMENT14:

-		case GL_COLOR_ATTACHMENT15:

-		case GL_COLOR_ATTACHMENT16:

-		case GL_COLOR_ATTACHMENT17:

-		case GL_COLOR_ATTACHMENT18:

-		case GL_COLOR_ATTACHMENT19:

-		case GL_COLOR_ATTACHMENT20:

-		case GL_COLOR_ATTACHMENT21:

-		case GL_COLOR_ATTACHMENT22:

-		case GL_COLOR_ATTACHMENT23:

-		case GL_COLOR_ATTACHMENT24:

-		case GL_COLOR_ATTACHMENT25:

-		case GL_COLOR_ATTACHMENT26:

-		case GL_COLOR_ATTACHMENT27:

-		case GL_COLOR_ATTACHMENT28:

-		case GL_COLOR_ATTACHMENT29:

-		case GL_COLOR_ATTACHMENT30:

-		case GL_COLOR_ATTACHMENT31:

-		{

-			GLuint index = (src - GL_COLOR_ATTACHMENT0);

-			if(index >= MAX_COLOR_ATTACHMENTS)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			if(readFramebufferName == 0)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			context->setFramebufferReadBuffer(src);

-		}

-			break;

-		default:

-			error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)

-{

-	TRACE("(GLenum mode = 0x%X, GLuint start = %d, GLuint end = %d, "

-		  "GLsizei count = %d, GLenum type = 0x%x, const void* indices = %p)",

-		  mode, start, end, count, type, indices);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(type)

-	{

-	case GL_UNSIGNED_BYTE:

-	case GL_UNSIGNED_SHORT:

-	case GL_UNSIGNED_INT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((count < 0) || (end < start))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-	}

-}

-

-GL_APICALL void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "

-	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "

-	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",

-	      target, level, internalformat, width, height, depth, border, format, type, pixels);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D:

-	case GL_TEXTURE_2D_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!ValidateType3D(type) || !ValidateFormat3D(format))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;

-	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!ValidateInternalFormat3D(internalformat, format, type))

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-		"GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "

-		"GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",

-		target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D:

-	case GL_TEXTURE_2D_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!ValidateType3D(type) || !ValidateFormat3D(format))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if((width < 0) || (height < 0) || (depth < 0) || (xoffset < 0) || (yoffset < 0) || (zoffset < 0))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();

-

-		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);

-

-		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);

-		if(validationError == GL_NONE)

-		{

-			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);

-		}

-		else

-		{

-			return error(validationError);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-		"GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",

-		target, level, xoffset, yoffset, zoffset, x, y, width, height);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D:

-	case GL_TEXTURE_2D_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if((width < 0) || (height < 0) || (xoffset < 0) || (yoffset < 0) || (zoffset < 0))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);

-		}

-

-		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();

-

-		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLenum colorbufferFormat = source->getFormat();

-		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();

-

-		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);

-		if(validationError != GL_NONE)

-		{

-			return error(validationError);

-		}

-

-		GLenum textureFormat = texture->getFormat(target, level);

-

-		if(!validateColorBufferFormat(textureFormat, colorbufferFormat))

-		{

-			return;

-		}

-

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

-	}

-}

-

-GL_APICALL void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "

-		"GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",

-		target, level, internalformat, width, height, depth, border, imageSize, data);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D:

-	case GL_TEXTURE_2D_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;

-	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) || (border != 0) || (imageSize < 0))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(internalformat)

-	{

-	case GL_DEPTH_COMPONENT:

-	case GL_DEPTH_COMPONENT16:

-	case GL_DEPTH_COMPONENT32_OES:

-	case GL_DEPTH_STENCIL:

-	case GL_DEPTH24_STENCIL8:

-		return error(GL_INVALID_OPERATION);

-	default:

-		{

-			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);

-			if(validationError != GL_NONE)

-			{

-				return error(validationError);

-			}

-		}

-	}

-

-	if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)

-{

-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "

-	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "

-	      "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",

-	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);

-

-	switch(target)

-	{

-	case GL_TEXTURE_3D:

-	case GL_TEXTURE_2D_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);

-	if(validationError != GL_NONE)

-	{

-		return error(validationError);

-	}

-

-	if(width == 0 || height == 0 || depth == 0 || !data)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGenQueries(GLsizei n, GLuint *ids)

-{

-	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			ids[i] = context->createQuery();

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids)

-{

-	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteQuery(ids[i]);

-		}

-	}

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsQuery(GLuint id)

-{

-	TRACE("(GLuint id = %d)", id);

-

-	if(id == 0)

-	{

-		return GL_FALSE;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Query *queryObject = context->getQuery(id);

-

-		if(queryObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GL_APICALL void GL_APIENTRY glBeginQuery(GLenum target, GLuint id)

-{

-	TRACE("(GLenum target = 0x%X, GLuint id = %d)", target, id);

-

-	if(!ValidateQueryTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(id == 0)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->beginQuery(target, id);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glEndQuery(GLenum target)

-{

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

-

-	if(!ValidateQueryTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->endQuery(target);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)",

-		  target, pname, params);

-

-	if(!ValidateQueryTarget(target) || (pname != GL_CURRENT_QUERY))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		params[0] = context->getActiveQuery(target);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)

-{

-	TRACE("(GLuint id = %d, GLenum pname = 0x%X, GLint *params = %p)",

-	      id, pname, params);

-

-	switch(pname)

-	{

-	case GL_QUERY_RESULT:

-	case GL_QUERY_RESULT_AVAILABLE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Query *queryObject = context->getQuery(id);

-

-		if(!queryObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(context->getActiveQuery(queryObject->getType()) == id)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_QUERY_RESULT:

-			params[0] = queryObject->getResult();

-			break;

-		case GL_QUERY_RESULT_AVAILABLE:

-			params[0] = queryObject->isResultAvailable();

-			break;

-		default:

-			ASSERT(false);

-		}

-	}

-}

-

-GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)

-{

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

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer = nullptr;

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM, GL_TRUE);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION, GL_TRUE);

-		}

-

-		return buffer->unmap() ? GL_TRUE : GL_FALSE;

-	}

-

-	return GL_TRUE;

-}

-

-GL_APICALL void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)",

-	      target, pname, params);

-

-	if(pname != GL_BUFFER_MAP_POINTER)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer = nullptr;

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

-		*params = buffer->isMapped() ? (void*)(((const char*)buffer->data()) + buffer->offset()) : nullptr;

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs)

-{

-	TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);

-

-	if(n < 0 || n > MAX_DRAW_BUFFERS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLuint drawFramebufferName = context->getDrawFramebufferName();

-

-		if((drawFramebufferName == 0) && (n != 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		for(unsigned int i = 0; i < (unsigned)n; i++)

-		{

-			switch(bufs[i])

-			{

-			case GL_BACK:

-				if(drawFramebufferName != 0)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			case GL_NONE:

-				break;

-			case GL_COLOR_ATTACHMENT0:

-			case GL_COLOR_ATTACHMENT1:

-			case GL_COLOR_ATTACHMENT2:

-			case GL_COLOR_ATTACHMENT3:

-			case GL_COLOR_ATTACHMENT4:

-			case GL_COLOR_ATTACHMENT5:

-			case GL_COLOR_ATTACHMENT6:

-			case GL_COLOR_ATTACHMENT7:

-			case GL_COLOR_ATTACHMENT8:

-			case GL_COLOR_ATTACHMENT9:

-			case GL_COLOR_ATTACHMENT10:

-			case GL_COLOR_ATTACHMENT11:

-			case GL_COLOR_ATTACHMENT12:

-			case GL_COLOR_ATTACHMENT13:

-			case GL_COLOR_ATTACHMENT14:

-			case GL_COLOR_ATTACHMENT15:

-			case GL_COLOR_ATTACHMENT16:

-			case GL_COLOR_ATTACHMENT17:

-			case GL_COLOR_ATTACHMENT18:

-			case GL_COLOR_ATTACHMENT19:

-			case GL_COLOR_ATTACHMENT20:

-			case GL_COLOR_ATTACHMENT21:

-			case GL_COLOR_ATTACHMENT22:

-			case GL_COLOR_ATTACHMENT23:

-			case GL_COLOR_ATTACHMENT24:

-			case GL_COLOR_ATTACHMENT25:

-			case GL_COLOR_ATTACHMENT26:

-			case GL_COLOR_ATTACHMENT27:

-			case GL_COLOR_ATTACHMENT28:

-			case GL_COLOR_ATTACHMENT29:

-			case GL_COLOR_ATTACHMENT30:

-			case GL_COLOR_ATTACHMENT31:

-				{

-					GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0);

-

-					if(index >= MAX_COLOR_ATTACHMENTS)

-					{

-						return error(GL_INVALID_OPERATION);

-					}

-

-					if(index != i)

-					{

-						return error(GL_INVALID_OPERATION);

-					}

-

-					if(drawFramebufferName == 0)

-					{

-						return error(GL_INVALID_OPERATION);

-					}

-				}

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-		}

-

-		context->setFramebufferDrawBuffers(n, bufs);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix2x3fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix3x2fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix2x4fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix4x2fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix3x4fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniformMatrix4x3fv(location, count, transpose, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)

-{

-	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "

-	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "

-	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",

-	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);

-

-	switch(filter)

-	{

-	case GL_NEAREST:

-	case GL_LINEAR:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(context->getReadFramebufferName() == context->getDrawFramebufferName())

-		{

-			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",

-	      target, samples, internalformat, width, height);

-

-	switch(target)

-	{

-	case GL_RENDERBUFFER:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width < 0 || height < 0 || samples < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   samples > es2::IMPLEMENTATION_MAX_SAMPLES)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		GLuint handle = context->getRenderbufferName();

-		if(handle == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT16:

-		case GL_DEPTH_COMPONENT24:

-		case GL_DEPTH_COMPONENT32_OES:

-		case GL_DEPTH_COMPONENT32F:

-			context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));

-			break;

-		case GL_R8UI:

-		case GL_R8I:

-		case GL_R16UI:

-		case GL_R16I:

-		case GL_R32UI:

-		case GL_R32I:

-		case GL_RG8UI:

-		case GL_RG8I:

-		case GL_RG16UI:

-		case GL_RG16I:

-		case GL_RG32UI:

-		case GL_RG32I:

-		case GL_RGB8UI:

-		case GL_RGB8I:

-		case GL_RGB16UI:

-		case GL_RGB16I:

-		case GL_RGB32UI:

-		case GL_RGB32I:

-		case GL_RGBA8UI:

-		case GL_RGBA8I:

-		case GL_RGB10_A2UI:

-		case GL_RGBA16UI:

-		case GL_RGBA16I:

-		case GL_RGBA32UI:

-		case GL_RGBA32I:

-			if(samples > 0)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_SRGB8_ALPHA8:

-		case GL_RGB10_A2:

-		case GL_R8:

-		case GL_RG8:

-		case GL_RGB8:

-		case GL_RGBA8:

-			context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));

-			break;

-		case GL_STENCIL_INDEX8:

-			context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));

-			break;

-		case GL_DEPTH24_STENCIL8:

-		case GL_DEPTH32F_STENCIL8:

-			context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));

-			break;

-

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)

-{

-	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %d, GLint level = %d, GLint layer = %d)",

-	      target, attachment, texture, level, layer);

-

-	// GLES 3.0.4 spec, p.209, section 4.4.2

-	// If texture is zero, any image or array of images attached to the attachment point

-	// named by attachment is detached. Any additional parameters(level, textarget,

-	// and / or layer) are ignored when texture is zero.

-	if(texture != 0 && (layer < 0 || level < 0))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		Texture* textureObject = context->getTexture(texture);

-		GLenum textarget = GL_NONE;

-		if(texture != 0)

-		{

-			if(!textureObject)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-

-			textarget = textureObject->getTarget();

-			switch(textarget)

-			{

-			case GL_TEXTURE_3D:

-			case GL_TEXTURE_2D_ARRAY:

-				if(layer >= es2::IMPLEMENTATION_MAX_TEXTURE_SIZE || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				break;

-			default:

-				return error(GL_INVALID_OPERATION);

-			}

-

-			if(textureObject->isCompressed(textarget, level))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-		}

-

-		es2::Framebuffer *framebuffer = nullptr;

-		switch(target)

-		{

-		case GL_DRAW_FRAMEBUFFER:

-		case GL_FRAMEBUFFER:

-			framebuffer = context->getDrawFramebuffer();

-			break;

-		case GL_READ_FRAMEBUFFER:

-			framebuffer = context->getReadFramebuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!framebuffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0:

-		case GL_COLOR_ATTACHMENT1:

-		case GL_COLOR_ATTACHMENT2:

-		case GL_COLOR_ATTACHMENT3:

-		case GL_COLOR_ATTACHMENT4:

-		case GL_COLOR_ATTACHMENT5:

-		case GL_COLOR_ATTACHMENT6:

-		case GL_COLOR_ATTACHMENT7:

-		case GL_COLOR_ATTACHMENT8:

-		case GL_COLOR_ATTACHMENT9:

-		case GL_COLOR_ATTACHMENT10:

-		case GL_COLOR_ATTACHMENT11:

-		case GL_COLOR_ATTACHMENT12:

-		case GL_COLOR_ATTACHMENT13:

-		case GL_COLOR_ATTACHMENT14:

-		case GL_COLOR_ATTACHMENT15:

-		case GL_COLOR_ATTACHMENT16:

-		case GL_COLOR_ATTACHMENT17:

-		case GL_COLOR_ATTACHMENT18:

-		case GL_COLOR_ATTACHMENT19:

-		case GL_COLOR_ATTACHMENT20:

-		case GL_COLOR_ATTACHMENT21:

-		case GL_COLOR_ATTACHMENT22:

-		case GL_COLOR_ATTACHMENT23:

-		case GL_COLOR_ATTACHMENT24:

-		case GL_COLOR_ATTACHMENT25:

-		case GL_COLOR_ATTACHMENT26:

-		case GL_COLOR_ATTACHMENT27:

-		case GL_COLOR_ATTACHMENT28:

-		case GL_COLOR_ATTACHMENT29:

-		case GL_COLOR_ATTACHMENT30:

-		case GL_COLOR_ATTACHMENT31:

-			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level, layer);

-			break;

-		case GL_DEPTH_ATTACHMENT:

-			framebuffer->setDepthbuffer(textarget, texture, level, layer);

-			break;

-		case GL_STENCIL_ATTACHMENT:

-			framebuffer->setStencilbuffer(textarget, texture, level, layer);

-			break;

-		case GL_DEPTH_STENCIL_ATTACHMENT:

-			framebuffer->setDepthbuffer(textarget, texture, level, layer);

-			framebuffer->setStencilbuffer(textarget, texture, level, layer);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)

-{

-	TRACE("(GLenum target = 0x%X,  GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = %X)",

-	      target, offset, length, access);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer = nullptr;

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM, nullptr);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION, nullptr);

-		}

-

-		GLsizeiptr bufferSize = buffer->size();

-		if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))

-		{

-			error(GL_INVALID_VALUE);

-		}

-

-		if((access & ~(GL_MAP_READ_BIT |

-		               GL_MAP_WRITE_BIT |

-		               GL_MAP_INVALIDATE_RANGE_BIT |

-		               GL_MAP_INVALIDATE_BUFFER_BIT |

-		               GL_MAP_FLUSH_EXPLICIT_BIT |

-		               GL_MAP_UNSYNCHRONIZED_BIT)) != 0)

-		{

-			error(GL_INVALID_VALUE);

-		}

-

-		return buffer->mapRange(offset, length, access);

-	}

-

-	return nullptr;

-}

-

-GL_APICALL void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)

-{

-	TRACE("(GLenum target = 0x%X,  GLintptr offset = %d, GLsizeiptr length = %d)",

-	      target, offset, length);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer = nullptr;

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

-		GLsizeiptr bufferSize = buffer->size();

-		if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))

-		{

-			error(GL_INVALID_VALUE);

-		}

-

-		buffer->flushMappedRange(offset, length);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glBindVertexArray(GLuint array)

-{

-	TRACE("(GLuint array = %d)", array);

-

-	if(array == 0)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->isVertexArray(array))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->bindVertexArray(array);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint *arrays)

-{

-	TRACE("(GLsizei n = %d, const GLuint *arrays = %p)", n, arrays);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteVertexArray(arrays[i]);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint *arrays)

-{

-	TRACE("(GLsizei n = %d, const GLuint *arrays = %p)", n, arrays);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			arrays[i] = context->createVertexArray();

-		}

-	}

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsVertexArray(GLuint array)

-{

-	TRACE("(GLuint array = %d)", array);

-

-	if(array == 0)

-	{

-		return GL_FALSE;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::VertexArray *arrayObject = context->getVertexArray(array);

-

-		if(arrayObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GL_APICALL void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint *data)

-{

-	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLint* data = %p)",

-	      target, index, data);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->getTransformFeedbackiv(index, target, data) &&

-		   !context->getUniformBufferiv(index, target, data) &&

-		   !context->getIntegerv(target, data))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(target, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that target is valid, but there are no parameters to return

-

-			if(nativeType == GL_BOOL)

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(target, boolParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;

-				}

-

-				delete[] boolParams;

-			}

-			else if(nativeType == GL_FLOAT)

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(target, floatParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)

-					{

-						data[i] = es2::floatToInt(floatParams[i]);

-					}

-					else

-					{

-						data[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

-					}

-				}

-

-				delete[] floatParams;

-			}

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode)

-{

-	TRACE("(GLenum primitiveMode = 0x%X)", primitiveMode);

-

-	switch(primitiveMode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_TRIANGLES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();

-

-		if(transformFeedbackObject)

-		{

-			if(transformFeedbackObject->isActive())

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			transformFeedbackObject->begin(primitiveMode);

-		}

-		else

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glEndTransformFeedback(void)

-{

-	TRACE("()");

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();

-

-		if(transformFeedbackObject)

-		{

-			if(!transformFeedbackObject->isActive())

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			transformFeedbackObject->end();

-		}

-		else

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)

-{

-	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLuint buffer = %d, GLintptr offset = %d, GLsizeiptr size = %d)",

-	      target, index, buffer, offset, size);

-

-	if(buffer != 0 && size <= 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TRANSFORM_FEEDBACK_BUFFER:

-			if(index >= MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			if(size & 0x3 || offset & 0x3) // size and offset must be multiples of 4

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);

-			context->bindGenericTransformFeedbackBuffer(buffer);

-			break;

-		case GL_UNIFORM_BUFFER:

-			if(index >= MAX_UNIFORM_BUFFER_BINDINGS)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			if(offset % UNIFORM_BUFFER_OFFSET_ALIGNMENT != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->bindIndexedUniformBuffer(buffer, index, offset, size);

-			context->bindGenericUniformBuffer(buffer);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)

-{

-	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLuint buffer = %d)",

-	      target, index, buffer);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TRANSFORM_FEEDBACK_BUFFER:

-			if(index >= MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);

-			context->bindGenericTransformFeedbackBuffer(buffer);

-			break;

-		case GL_UNIFORM_BUFFER:

-			if(index >= MAX_UNIFORM_BUFFER_BINDINGS)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->bindIndexedUniformBuffer(buffer, index, 0, 0);

-			context->bindGenericUniformBuffer(buffer);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode)

-{

-	TRACE("(GLuint program = %d, GLsizei count = %d, const GLchar *const*varyings = %p, GLenum bufferMode = 0x%X)",

-	      program, count, varyings, bufferMode);

-

-	switch(bufferMode)

-	{

-	case GL_SEPARATE_ATTRIBS:

-		if(count > MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-	case GL_INTERLEAVED_ATTRIBS:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLsizei *size = %p, GLenum *type = %p, GLchar *name = %p)",

-	      program, index, bufSize, length, size, type, name);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		if(index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)

-{

-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLsizei *size = %p, GLenum *type = %p, GLchar *name = %p)",

-	      index, size, type, stride, pointer);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(size < 1 || size > 4 || stride < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(type)

-	{

-	case GL_BYTE:

-	case GL_UNSIGNED_BYTE:

-	case GL_SHORT:

-	case GL_UNSIGNED_SHORT:

-	case GL_INT:

-	case GL_UNSIGNED_INT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, stride, pointer);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint *params = %p)",

-	      index, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= es2::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);

-

-		switch(pname)

-		{

-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:

-			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:

-			*params = attribState.mSize;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:

-			*params = attribState.mStride;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:

-			*params = attribState.mType;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:

-			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:

-			*params = attribState.mBoundBuffer.name();

-			break;

-		case GL_CURRENT_VERTEX_ATTRIB:

-			{

-				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];

-				for(int i = 0; i < 4; ++i)

-				{

-					params[i] = attrib.getCurrentValueI(i);

-				}

-			}

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:

-			switch(attribState.mType)

-			{

-			case GL_BYTE:

-			case GL_UNSIGNED_BYTE:

-			case GL_SHORT:

-			case GL_UNSIGNED_SHORT:

-			case GL_INT:

-			case GL_INT_2_10_10_10_REV:

-			case GL_UNSIGNED_INT:

-			case GL_FIXED:

-				*params = GL_TRUE;

-				break;

-			default:

-				*params = GL_FALSE;

-				break;

-			}

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:

-			*params = attribState.mDivisor;

-			break;

-		default: return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)

-{

-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLuint *params = %p)",

-		index, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= es2::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);

-

-		switch(pname)

-		{

-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:

-			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:

-			*params = attribState.mSize;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:

-			*params = attribState.mStride;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:

-			*params = attribState.mType;

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:

-			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:

-			*params = attribState.mBoundBuffer.name();

-			break;

-		case GL_CURRENT_VERTEX_ATTRIB:

-			{

-				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];

-				for(int i = 0; i < 4; ++i)

-				{

-					params[i] = attrib.getCurrentValueUI(i);

-				}

-			}

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:

-			switch(attribState.mType)

-			{

-			case GL_BYTE:

-			case GL_UNSIGNED_BYTE:

-			case GL_SHORT:

-			case GL_UNSIGNED_SHORT:

-			case GL_INT:

-			case GL_INT_2_10_10_10_REV:

-			case GL_UNSIGNED_INT:

-			case GL_FIXED:

-				*params = GL_TRUE;

-				break;

-			default:

-				*params = GL_FALSE;

-				break;

-			}

-			break;

-		case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:

-			*params = attribState.mDivisor;

-			break;

-		default: return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)

-{

-	TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",

-	      index, x, y, z, w);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLint vals[4] = { x, y, z, w };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)

-{

-	TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",

-	      index, x, y, z, w);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		GLuint vals[4] = { x, y, z, w };

-		context->setVertexAttrib(index, vals);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint *v)

-{

-	TRACE("(GLuint index = %d, GLint *v = %p)", index, v);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setVertexAttrib(index, v);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint *v)

-{

-	TRACE("(GLuint index = %d, GLint *v = %p)", index, v);

-

-	if(index >= es2::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->setVertexAttrib(index, v);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint *params)

-{

-	TRACE("(GLuint program = %d, GLint location = %d, GLuint *params = %p)",

-	      program, location, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(program == 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject || !programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->getUniformuiv(location, NULL, params))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name)

-{

-	TRACE("(GLuint program = %d, const GLchar *name = %p)", program, name);

-

-	es2::Context *context = es2::getContext();

-

-	if(strstr(name, "gl_") == name)

-	{

-		return -1;

-	}

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			if(context->getShader(program))

-			{

-				return error(GL_INVALID_OPERATION, -1);

-			}

-			else

-			{

-				return error(GL_INVALID_VALUE, -1);

-			}

-		}

-

-		if(!programObject->isLinked())

-		{

-			return error(GL_INVALID_OPERATION, -1);

-		}

-	}

-

-	UNIMPLEMENTED();

-	return -1;

-}

-

-GL_APICALL void GL_APIENTRY glUniform1ui(GLint location, GLuint v0)

-{

-	glUniform1uiv(location, 1, &v0);

-}

-

-GL_APICALL void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1)

-{

-	GLuint xy[2] = { v0, v1 };

-

-	glUniform2uiv(location, 1, (GLuint*)&xy);

-}

-

-GL_APICALL void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)

-{

-	GLuint xyz[3] = { v0, v1, v2 };

-

-	glUniform3uiv(location, 1, (GLuint*)&xyz);

-}

-

-GL_APICALL void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)

-{

-	GLuint xyzw[4] = { v0, v1, v2, v3 };

-

-	glUniform4uiv(location, 1, (GLuint*)&xyzw);

-}

-

-GL_APICALL void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",

-	      location, count, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform1uiv(location, count, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",

-	      location, count, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform2uiv(location, count, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",

-	      location, count, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform3uiv(location, count, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint *value)

-{

-	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",

-	      location, count, value);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(location == -1)

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *program = context->getCurrentProgram();

-

-		if(!program)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!program->setUniform4uiv(location, count, value))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)

-{

-	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint *value = %p)",

-	      buffer, drawbuffer, value);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(buffer)

-		{

-		case GL_COLOR:

-			if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				context->clearColorBuffer(drawbuffer, value);

-			}

-			break;

-		case GL_STENCIL:

-			if(drawbuffer != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				context->clearStencilBuffer(value[0]);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)

-{

-	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint *value = %p)",

-	      buffer, drawbuffer, value);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(buffer)

-		{

-		case GL_COLOR:

-			if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				context->clearColorBuffer(drawbuffer, value);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)

-{

-	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat *value = %p)",

-	      buffer, drawbuffer, value);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(buffer)

-		{

-		case GL_COLOR:

-			if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				context->clearColorBuffer(drawbuffer, value);

-			}

-			break;

-		case GL_DEPTH:

-			if(drawbuffer != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				context->clearDepthBuffer(value[0]);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)

-{

-	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth = %f, GLint stencil = %d)",

-	      buffer, drawbuffer, depth, stencil);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(buffer)

-		{

-		case GL_DEPTH_STENCIL:

-			if(drawbuffer != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			else

-			{

-				context->clearDepthBuffer(depth);

-				context->clearStencilBuffer(stencil);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL const GLubyte *GL_APIENTRY glGetStringi(GLenum name, GLuint index)

-{

-	TRACE("(GLenum name = 0x%X, GLuint index = %d)", name, index);

-

-	es2::Context *context = es2::getContext();

-	if(context)

-	{

-		GLuint numExtensions;

-		context->getExtensions(0, &numExtensions);

-

-		if(index >= numExtensions)

-		{

-			return error(GL_INVALID_VALUE, (GLubyte*)NULL);

-		}

-

-		switch(name)

-		{

-		case GL_EXTENSIONS:

-			return context->getExtensions(index);

-		default:

-			return error(GL_INVALID_ENUM, (GLubyte*)NULL);

-		}

-	}

-

-	return (GLubyte*)NULL;

-}

-

-GL_APICALL void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)

-{

-	TRACE("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X,  GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",

-	      readTarget, writeTarget, readOffset, writeOffset, size);

-

-	if(readOffset < 0 || writeOffset < 0 || size < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *readBuffer = nullptr, *writeBuffer = nullptr;

-		if(!context->getBuffer(readTarget, &readBuffer) || !context->getBuffer(writeTarget, &writeBuffer))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		if(!readBuffer || readBuffer->isMapped() || !writeBuffer || writeBuffer->isMapped())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-		if(readBuffer == writeBuffer)

-		{

-			// If same buffer, check for overlap

-			if(((readOffset >= writeOffset) && (readOffset < (writeOffset + size))) ||

-			   ((writeOffset >= readOffset) && (writeOffset < (readOffset + size))))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		if((static_cast<size_t>(readOffset + size) > readBuffer->size()) ||

-		   (static_cast<size_t>(writeOffset + size) > writeBuffer->size()))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		writeBuffer->bufferSubData(((char*)readBuffer->data()) + readOffset, size, writeOffset);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices)

-{

-	TRACE("(GLuint program = %d, GLsizei uniformCount = %d, const GLchar *const*uniformNames = %p, GLuint *uniformIndices = %p)",

-	      program, uniformCount, uniformNames, uniformIndices);

-

-	if (uniformCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if(!programObject->isLinked())

-		{

-			for(int uniformId = 0; uniformId < uniformCount; uniformId++)

-			{

-				uniformIndices[uniformId] = GL_INVALID_INDEX;

-			}

-		}

-		else

-		{

-			for(int uniformId = 0; uniformId < uniformCount; uniformId++)

-			{

-				uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);

-			}

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params)

-{

-	TRACE("(GLuint program = %d, GLsizei uniformCount = %d, const GLchar *const*uniformNames = %p, GLenum pname = 0x%X, GLuint *uniformIndices = %p)",

-	      program, uniformCount, uniformIndices, pname, uniformIndices);

-

-	switch(pname)

-	{

-	case GL_UNIFORM_TYPE:

-	case GL_UNIFORM_SIZE:

-	case GL_UNIFORM_NAME_LENGTH:

-	case GL_UNIFORM_BLOCK_INDEX:

-	case GL_UNIFORM_OFFSET:

-	case GL_UNIFORM_ARRAY_STRIDE:

-	case GL_UNIFORM_MATRIX_STRIDE:

-	case GL_UNIFORM_IS_ROW_MAJOR:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(uniformCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		for(int uniformId = 0; uniformId < uniformCount; uniformId++)

-		{

-			const GLuint index = uniformIndices[uniformId];

-

-			if(index >= programObject->getActiveUniformCount())

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

-		for(int uniformId = 0; uniformId < uniformCount; uniformId++)

-		{

-			const GLuint index = uniformIndices[uniformId];

-			params[uniformId] = programObject->getActiveUniformi(index, pname);

-		}

-	}

-}

-

-GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)

-{

-	TRACE("(GLuint program = %d, const GLchar *uniformBlockName = %p)",

-	      program, uniformBlockName);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION, GL_INVALID_INDEX);

-		}

-

-		return programObject->getUniformBlockIndex(uniformBlockName);

-	}

-

-	return GL_INVALID_INDEX;

-}

-

-GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)

-{

-	TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLenum pname = 0x%X, GLint *params = %p)",

-	      program, uniformBlockIndex, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_UNIFORM_BLOCK_BINDING:

-			*params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));

-			break;

-		case GL_UNIFORM_BLOCK_DATA_SIZE:

-		case GL_UNIFORM_BLOCK_NAME_LENGTH:

-		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:

-		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:

-		case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:

-		case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:

-			programObject->getActiveUniformBlockiv(uniformBlockIndex, pname, params);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName)

-{

-	TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLchar *uniformBlockName = %p)",

-	      program, uniformBlockIndex, bufSize, length, uniformBlockName);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)

-{

-	TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLuint uniformBlockBinding = %d)",

-	      program, uniformBlockIndex, uniformBlockBinding);

-

-	if(uniformBlockBinding >= MAX_UNIFORM_BUFFER_BINDINGS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		programObject->bindUniformBlock(uniformBlockIndex, uniformBlockIndex);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)

-{

-	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",

-	      mode, first, count, instanceCount);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0 || instanceCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->drawArrays(mode, first, count, instanceCount);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)

-{

-	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",

-	      mode, count, type, indices, instanceCount);

-

-	switch(mode)

-	{

-	case GL_POINTS:

-	case GL_LINES:

-	case GL_LINE_LOOP:

-	case GL_LINE_STRIP:

-	case GL_TRIANGLES:

-	case GL_TRIANGLE_FAN:

-	case GL_TRIANGLE_STRIP:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(type)

-	{

-	case GL_UNSIGNED_BYTE:

-	case GL_UNSIGNED_SHORT:

-	case GL_UNSIGNED_INT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(count < 0 || instanceCount < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();

-		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);

-	}

-}

-

-GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)

-{

-	TRACE("(GLenum condition = 0x%X, GLbitfield flags = %X)", condition, flags);

-

-	switch(condition)

-	{

-	case GL_SYNC_GPU_COMMANDS_COMPLETE:

-		break;

-	default:

-		return error(GL_INVALID_ENUM, nullptr);

-	}

-

-	if(flags != 0)

-	{

-		return error(GL_INVALID_VALUE, nullptr);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		return context->createFenceSync(condition, flags);

-	}

-

-	return nullptr;

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsSync(GLsync sync)

-{

-	TRACE("(GLsync sync = %p)", sync);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);

-

-		if(fenceSyncObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GL_APICALL void GL_APIENTRY glDeleteSync(GLsync sync)

-{

-	TRACE("(GLsync sync = %p)", sync);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		context->deleteFenceSync(sync);

-	}

-}

-

-GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)

-{

-	TRACE("(GLsync sync = %p, GLbitfield flags = %X, GLuint64 timeout = %llu)", sync, flags, timeout);

-

-	if((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)

-	{

-		error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);

-

-		if(fenceSyncObject)

-		{

-			return fenceSyncObject->clientWait(flags, timeout);

-		}

-		else

-		{

-			return error(GL_INVALID_VALUE, GL_FALSE);

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GL_APICALL void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)

-{

-	TRACE("(GLsync sync = %p, GLbitfield flags = %X, GLuint64 timeout = %llu)", sync, flags, timeout);

-

-	if(flags != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(timeout != GL_TIMEOUT_IGNORED)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);

-

-		if(fenceSyncObject)

-		{

-			fenceSyncObject->serverWait(flags, timeout);

-		}

-		else

-		{

-			return error(GL_INVALID_VALUE);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *data)

-{

-	TRACE("(GLenum pname = 0x%X, GLint64 *data = %p)", pname, data);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!(context->getIntegerv(pname, data)))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that pname is valid, but there are no parameters to return

-

-			if(nativeType == GL_BOOL)

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;

-				}

-

-				delete[] boolParams;

-			}

-			else if(nativeType == GL_FLOAT)

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)

-					{

-						data[i] = (GLint64)(es2::floatToInt(floatParams[i]));

-					}

-					else

-					{

-						data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

-					}

-				}

-

-				delete[] floatParams;

-			}

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)

-{

-	TRACE("(GLsync sync = %p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei *length = %p, GLint *values = %p)",

-	      sync, pname, bufSize, length, values);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	UNIMPLEMENTED();

-}

-

-GL_APICALL void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data)

-{

-	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLint64 *data = %p)", target, index, data);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->getTransformFeedbackiv(index, target, data) &&

-		   !context->getUniformBufferiv(index, target, data) &&

-		   !context->getIntegerv(target, data))

-		{

-			GLenum nativeType;

-			unsigned int numParams = 0;

-			if(!context->getQueryParameterInfo(target, &nativeType, &numParams))

-				return error(GL_INVALID_ENUM);

-

-			if(numParams == 0)

-				return; // it is known that target is valid, but there are no parameters to return

-

-			if(nativeType == GL_BOOL)

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(target, boolParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;

-				}

-

-				delete[] boolParams;

-			}

-			else if(nativeType == GL_FLOAT)

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(target, floatParams);

-

-				for(unsigned int i = 0; i < numParams; ++i)

-				{

-					if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)

-					{

-						data[i] = (GLint64)(es2::floatToInt(floatParams[i]));

-					}

-					else

-					{

-						data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

-					}

-				}

-

-				delete[] floatParams;

-			}

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64 *params = %p)", target, pname, params);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Buffer *buffer = nullptr;

-

-		if(!context->getBuffer(target, &buffer))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			// A null buffer means that "0" is bound to the requested buffer target

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_BUFFER_USAGE:

-			*params = buffer->usage();

-			break;

-		case GL_BUFFER_SIZE:

-			*params = buffer->size();

-			break;

-		case GL_BUFFER_ACCESS_FLAGS:

-			*params = buffer->access();

-			break;

-		case GL_BUFFER_MAPPED:

-			*params = buffer->isMapped();

-			break;

-		case GL_BUFFER_MAP_LENGTH:

-			*params = buffer->length();

-			break;

-		case GL_BUFFER_MAP_OFFSET:

-			*params = buffer->offset();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGenSamplers(GLsizei count, GLuint *samplers)

-{

-	TRACE("(GLsizei count = %d, GLuint *samplers = %p)", count, samplers);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < count; i++)

-		{

-			samplers[i] = context->createSampler();

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint *samplers)

-{

-	TRACE("(GLsizei count = %d, GLuint *samplers = %p)", count, samplers);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < count; i++)

-		{

-			context->deleteSampler(samplers[i]);

-		}

-	}

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsSampler(GLuint sampler)

-{

-	TRACE("(GLuint sampler = %d)", sampler);

-

-	if(sampler == 0)

-	{

-		return GL_FALSE;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(context->isSampler(sampler))

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GL_APICALL void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler)

-{

-	TRACE("(GLuint unit = %d, GLuint sampler = %d)", unit, sampler);

-

-	if(unit >= es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(sampler != 0 && !context->isSampler(sampler))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->bindSampler(unit, sampler);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)

-{

-	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLint param = %d)",

-	      sampler, pname, param);

-

-	glSamplerParameteriv(sampler, pname, &param);

-}

-

-GL_APICALL void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)

-{

-	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, const GLint *param = %p)",

-	      sampler, pname, param);

-

-	if(!ValidateSamplerObjectParameter(pname))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!ValidateTexParamParameters(pname, *param))

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->isSampler(sampler))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->samplerParameteri(sampler, pname, *param);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)

-{

-	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLfloat param = %f)",

-	      sampler, pname, param);

-

-	glSamplerParameterfv(sampler, pname, &param);

-}

-

-GL_APICALL void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)

-{

-	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, const GLfloat *param = %p)",

-	      sampler, pname, param);

-

-	if(!ValidateSamplerObjectParameter(pname))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!ValidateTexParamParameters(pname, *param))

-	{

-		return;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->isSampler(sampler))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->samplerParameterf(sampler, pname, *param);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)

-{

-	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLint *params = %p)",

-	      sampler, pname, params);

-

-	if(!ValidateSamplerObjectParameter(pname))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->isSampler(sampler))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		*params = context->getSamplerParameteri(sampler, pname);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)

-{

-	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLfloat *params = %p)",

-	      sampler, pname, params);

-

-	if(!ValidateSamplerObjectParameter(pname))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(!context->isSampler(sampler))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		*params = context->getSamplerParameterf(sampler, pname);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)

-{

-	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(index >= es2::MAX_VERTEX_ATTRIBS)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		context->setVertexAttribDivisor(index, divisor);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)

-{

-	TRACE("(GLenum target = 0x%X, GLuint id = %d)", target, id);

-

-	if(target != GL_TRANSFORM_FEEDBACK)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();

-

-		if(transformFeedbackObject && transformFeedbackObject->isActive() && !transformFeedbackObject->isPaused())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->bindTransformFeedback(id);

-	}

-}

-

-GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids)

-{

-	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			if (ids[i] != 0)

-			{

-				context->deleteTransformFeedback(ids[i]);

-			}

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint *ids)

-{

-	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			ids[i] = context->createTransformFeedback();

-		}

-	}

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id)

-{

-	TRACE("(GLuint id = %d)", id);

-

-	if(id == 0)

-	{

-		return GL_FALSE;

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback(id);

-

-		if(transformFeedbackObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GL_APICALL void GL_APIENTRY glPauseTransformFeedback(void)

-{

-	TRACE("()");

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();

-

-		if(transformFeedbackObject)

-		{

-			if(!transformFeedbackObject->isActive() || transformFeedbackObject->isPaused())

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			transformFeedbackObject->setPaused(true);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glResumeTransformFeedback(void)

-{

-	TRACE("()");

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();

-

-		if(transformFeedbackObject)

-		{

-			if(!transformFeedbackObject->isActive() || !transformFeedbackObject->isPaused())

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			transformFeedbackObject->setPaused(false);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)

-{

-	TRACE("(GLuint program = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLenum *binaryFormat = %p, void *binary = %p)",

-	      program, bufSize, length, binaryFormat, binary);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	UNIMPLEMENTED();

-}

-

-GL_APICALL void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)

-{

-	TRACE("(GLuint program = %d, GLenum binaryFormat = 0x%X, const void *binary = %p, GLsizei length = %d)",

-	      program, binaryFormat, binaryFormat, length);

-

-	if(length < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	UNIMPLEMENTED();

-}

-

-GL_APICALL void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)

-{

-	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint value = %d)",

-	      program, pname, value);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		es2::Program *programObject = context->getProgram(program);

-

-		if(!programObject)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(pname)

-		{

-		case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:

-			programObject->setBinaryRetrievable(value != GL_FALSE);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)

-{

-	TRACE("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = %p)",

-	      target, numAttachments, attachments);

-

-	glInvalidateSubFramebuffer(target, numAttachments, attachments, 0, 0, std::numeric_limits<GLsizei>::max(), std::numeric_limits<GLsizei>::max());

-}

-

-GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = %p, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",

-	      target, numAttachments, attachments, x, y, width, height);

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		if(numAttachments < 0 || width < 0 || height < 0)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		es2::Framebuffer *framebuffer = nullptr;

-		switch(target)

-		{

-		case GL_DRAW_FRAMEBUFFER:

-		case GL_FRAMEBUFFER:

-			framebuffer = context->getDrawFramebuffer();

-		case GL_READ_FRAMEBUFFER:

-			framebuffer = context->getReadFramebuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(framebuffer)

-		{

-			for(int i = 0; i < numAttachments; i++)

-			{

-				switch(attachments[i])

-				{

-				case GL_COLOR:

-				case GL_DEPTH:

-				case GL_STENCIL:

-					if(!framebuffer->isDefaultFramebuffer())

-					{

-						return error(GL_INVALID_ENUM);

-					}

-					break;

-				case GL_DEPTH_ATTACHMENT:

-				case GL_STENCIL_ATTACHMENT:

-				case GL_DEPTH_STENCIL_ATTACHMENT:

-					break;

-				default:

-					if(attachments[i] >= GL_COLOR_ATTACHMENT0 &&

-					   attachments[i] <= GL_COLOR_ATTACHMENT31)

-					{

-						if(attachments[i] - GL_COLOR_ATTACHMENT0 >= MAX_DRAW_BUFFERS)

-						{

-							return error(GL_INVALID_OPERATION);

-						}

-					}

-					else

-					{

-						return error(GL_INVALID_ENUM);

-					}

-					break;

-				}

-			}

-		}

-

-		// UNIMPLEMENTED();   // It is valid for this function to be treated as a no-op

-	}

-}

-

-GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",

-	      target, levels, internalformat, width, height);

-

-	if(width < 1 || height < 1 || levels < 1)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	GLenum type;

-	if(!GetStorageType(internalformat, type))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-		{

-			es2::Texture2D *texture = context->getTexture2D();

-			if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			for(int level = 0; level < levels; ++level)

-			{

-				texture->setImage(level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

-				width = std::max(1, (width / 2));

-				height = std::max(1, (height / 2));

-			}

-			texture->makeImmutable(levels);

-		}

-			break;

-		case GL_TEXTURE_CUBE_MAP:

-		{

-			es2::TextureCubeMap *texture = context->getTextureCubeMap();

-			if(!texture || texture->name == 0 || texture->getImmutableFormat())

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			for(int level = 0; level < levels; ++level)

-			{

-				for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)

-				{

-					texture->setImage(face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

-				}

-				width = std::max(1, (width / 2));

-				height = std::max(1, (height / 2));

-			}

-			texture->makeImmutable(levels);

-		}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)

-{

-	TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d)",

-	      target, levels, internalformat, width, height, depth);

-

-	if(width < 1 || height < 1 || depth < 1 || levels < 1)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	GLenum type;

-	if(!GetStorageType(internalformat, type))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es2::Context *context = es2::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_3D:

-		{

-			if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			es2::Texture3D *texture = context->getTexture3D();

-			if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			for(int level = 0; level < levels; ++level)

-			{

-				texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

-				width = std::max(1, (width / 2));

-				height = std::max(1, (height / 2));

-				depth = std::max(1, (depth / 2));

-			}

-			texture->makeImmutable(levels);

-		}

-			break;

-		case GL_TEXTURE_2D_ARRAY:

-		{

-			if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			es2::Texture3D *texture = context->getTexture2DArray();

-			if(!texture || texture->name == 0 || texture->getImmutableFormat())

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			for(int level = 0; level < levels; ++level)

-			{

-				for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)

-				{

-					texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);

-				}

-				width = std::max(1, (width / 2));

-				height = std::max(1, (height / 2));

-			}

-			texture->makeImmutable(levels);

-		}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, GLint *params = %p)",

-	      target, internalformat, pname, bufSize, params);

-

-	if(bufSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(bufSize == 0)

-	{

-		return;

-	}

-

-	if(!IsColorRenderable(internalformat, egl::getClientVersion()) && !IsDepthRenderable(internalformat) && !IsStencilRenderable(internalformat))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(target)

-	{

-	case GL_RENDERBUFFER:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	// Integer types have no multisampling

-	GLint numMultisampleCounts = NUM_MULTISAMPLE_COUNTS;

-	switch(internalformat)

-	{

-	case GL_R8UI:

-	case GL_R8I:

-	case GL_R16UI:

-	case GL_R16I:

-	case GL_R32UI:

-	case GL_R32I:

-	case GL_RG8UI:

-	case GL_RG8I:

-	case GL_RG16UI:

-	case GL_RG16I:

-	case GL_RG32UI:

-	case GL_RG32I:

-	case GL_RGB8UI:

-	case GL_RGB8I:

-	case GL_RGB16UI:

-	case GL_RGB16I:

-	case GL_RGB32UI:

-	case GL_RGB32I:

-	case GL_RGBA8UI:

-	case GL_RGBA8I:

-	case GL_RGB10_A2UI:

-	case GL_RGBA16UI:

-	case GL_RGBA16I:

-	case GL_RGBA32UI:

-	case GL_RGBA32I:

-		numMultisampleCounts = 0;

-		break;

-	default:

-		break;

-	}

-

-	switch(pname)

-	{

-	case GL_NUM_SAMPLE_COUNTS:

-		*params = numMultisampleCounts;

-		break;

-	case GL_SAMPLES:

-		for(int i = 0; i < numMultisampleCounts && i < bufSize; i++)

-		{

-			params[i] = multisampleCount[i];

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-}

+// 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.
+
+// libGLESv3.cpp: Implements the exported OpenGL ES 3.0 functions.
+
+#include "main.h"
+#include "Buffer.h"
+#include "Fence.h"
+#include "Framebuffer.h"
+#include "Program.h"
+#include "Query.h"
+#include "Sampler.h"
+#include "Texture.h"
+#include "mathutil.h"
+#include "TransformFeedback.h"
+#include "common/debug.h"
+
+#include <GLES3/gl3.h>
+#include <GLES2/gl2ext.h>
+
+#include <limits.h>
+
+using namespace es2;
+
+typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
+typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
+
+// A helper function to insert data into the format map with fewer characters.
+static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
+{
+	map[InternalFormatTypePair(internalformat, type)] = format;
+}
+
+static bool validImageSize(GLint level, GLsizei width, GLsizei height)
+{
+	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+
+static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
+{
+	GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
+	if(validationError != GL_NONE)
+	{
+		return error(validationError, false);
+	}
+
+	switch(textureFormat)
+	{
+	case GL_ALPHA:
+		if(colorbufferFormat != GL_ALPHA &&
+		   colorbufferFormat != GL_RGBA &&
+		   colorbufferFormat != GL_RGBA4 &&
+		   colorbufferFormat != GL_RGB5_A1 &&
+		   colorbufferFormat != GL_RGBA8)
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+		break;
+	case GL_LUMINANCE:
+	case GL_RGB:
+		if(colorbufferFormat != GL_RGB &&
+		   colorbufferFormat != GL_RGB565 &&
+		   colorbufferFormat != GL_RGB8 &&
+		   colorbufferFormat != GL_RGBA &&
+		   colorbufferFormat != GL_RGBA4 &&
+		   colorbufferFormat != GL_RGB5_A1 &&
+		   colorbufferFormat != GL_RGBA8)
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+		break;
+	case GL_LUMINANCE_ALPHA:
+	case GL_RGBA:
+		if(colorbufferFormat != GL_RGBA &&
+		   colorbufferFormat != GL_RGBA4 &&
+		   colorbufferFormat != GL_RGB5_A1 &&
+		   colorbufferFormat != GL_RGBA8)
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+		break;
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_STENCIL:
+		return error(GL_INVALID_OPERATION, false);
+	default:
+		return error(GL_INVALID_ENUM, false);
+	}
+	return true;
+}
+
+static FormatMap BuildFormatMap3D()
+{
+	FormatMap map;
+
+	//                       Internal format | Format | Type
+	InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
+	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
+	InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
+	InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_R8, GL_RED, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_R8_SNORM, GL_RED, GL_BYTE);
+	InsertFormatMapping(map, GL_R16F, GL_RED, GL_HALF_FLOAT);
+	InsertFormatMapping(map, GL_R16F, GL_RED, GL_FLOAT);
+	InsertFormatMapping(map, GL_R32F, GL_RED, GL_FLOAT);
+	InsertFormatMapping(map, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_R8I, GL_RED_INTEGER, GL_BYTE);
+	InsertFormatMapping(map, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT);
+	InsertFormatMapping(map, GL_R16I, GL_RED_INTEGER, GL_SHORT);
+	InsertFormatMapping(map, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
+	InsertFormatMapping(map, GL_R32I, GL_RED_INTEGER, GL_INT);
+	InsertFormatMapping(map, GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RG8_SNORM, GL_RG, GL_BYTE);
+	InsertFormatMapping(map, GL_RG16F, GL_RG, GL_HALF_FLOAT);
+	InsertFormatMapping(map, GL_RG16F, GL_RG, GL_FLOAT);
+	InsertFormatMapping(map, GL_RG32F, GL_RG, GL_FLOAT);
+	InsertFormatMapping(map, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RG8I, GL_RG_INTEGER, GL_BYTE);
+	InsertFormatMapping(map, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT);
+	InsertFormatMapping(map, GL_RG16I, GL_RG_INTEGER, GL_SHORT);
+	InsertFormatMapping(map, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT);
+	InsertFormatMapping(map, GL_RG32I, GL_RG_INTEGER, GL_INT);
+	InsertFormatMapping(map, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
+	InsertFormatMapping(map, GL_RGB8_SNORM, GL_RGB, GL_BYTE);
+	InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV);
+	InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT);
+	InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
+	InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV);
+	InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT);
+	InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_FLOAT);
+	InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
+	InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_FLOAT);
+	InsertFormatMapping(map, GL_RGB32F, GL_RGB, GL_FLOAT);
+	InsertFormatMapping(map, GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGB8I, GL_RGB_INTEGER, GL_BYTE);
+	InsertFormatMapping(map, GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT);
+	InsertFormatMapping(map, GL_RGB16I, GL_RGB_INTEGER, GL_SHORT);
+	InsertFormatMapping(map, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT);
+	InsertFormatMapping(map, GL_RGB32I, GL_RGB_INTEGER, GL_INT);
+	InsertFormatMapping(map, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
+	InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
+	InsertFormatMapping(map, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE);
+	InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
+	InsertFormatMapping(map, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
+	InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
+	InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_FLOAT);
+	InsertFormatMapping(map, GL_RGBA32F, GL_RGBA, GL_FLOAT);
+	InsertFormatMapping(map, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE);
+	InsertFormatMapping(map, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE);
+	InsertFormatMapping(map, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV);
+	InsertFormatMapping(map, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT);
+	InsertFormatMapping(map, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT);
+	InsertFormatMapping(map, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
+	InsertFormatMapping(map, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
+
+	InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
+	InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
+	InsertFormatMapping(map, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
+	InsertFormatMapping(map, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
+	InsertFormatMapping(map, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
+	InsertFormatMapping(map, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
+	InsertFormatMapping(map, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+	return map;
+}
+
+static bool ValidateType3D(GLenum type)
+{
+	switch(type)
+	{
+	case GL_UNSIGNED_BYTE:
+	case GL_BYTE:
+	case GL_UNSIGNED_SHORT:
+	case GL_SHORT:
+	case GL_UNSIGNED_INT:
+	case GL_INT:
+	case GL_HALF_FLOAT:
+	case GL_FLOAT:
+	case GL_UNSIGNED_SHORT_5_6_5:
+	case GL_UNSIGNED_SHORT_4_4_4_4:
+	case GL_UNSIGNED_SHORT_5_5_5_1:
+	case GL_UNSIGNED_INT_2_10_10_10_REV:
+	case GL_UNSIGNED_INT_10F_11F_11F_REV:
+	case GL_UNSIGNED_INT_5_9_9_9_REV:
+	case GL_UNSIGNED_INT_24_8:
+	case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
+static bool ValidateFormat3D(GLenum format)
+{
+	switch(format)
+	{
+	case GL_RED:
+	case GL_RG:
+	case GL_RGB:
+	case GL_RGBA:
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_STENCIL:
+	case GL_LUMINANCE_ALPHA:
+	case GL_LUMINANCE:
+	case GL_ALPHA:
+	case GL_RED_INTEGER:
+	case GL_RG_INTEGER:
+	case GL_RGB_INTEGER:
+	case GL_RGBA_INTEGER:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
+static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
+{
+	static const FormatMap formatMap = BuildFormatMap3D();
+	FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
+	if(iter != formatMap.end())
+	{
+		return iter->second == format;
+	}
+	return false;
+}
+
+typedef std::map<GLenum, GLenum> FormatMapStorage;
+
+// A helper function to insert data into the format map with fewer characters.
+static void InsertFormatStorageMapping(FormatMapStorage& map, GLenum internalformat, GLenum type)
+{
+	map[internalformat] = type;
+}
+
+static FormatMapStorage BuildFormatMapStorage2D()
+{
+	FormatMapStorage map;
+
+	//                              Internal format | Type
+	InsertFormatStorageMapping(map, GL_R8, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_R8_SNORM, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_R16F, GL_HALF_FLOAT);
+	InsertFormatStorageMapping(map, GL_R32F, GL_FLOAT);
+	InsertFormatStorageMapping(map, GL_R8UI, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_R8I, GL_BYTE);
+	InsertFormatStorageMapping(map, GL_R16UI, GL_UNSIGNED_SHORT);
+	InsertFormatStorageMapping(map, GL_R16I, GL_SHORT);
+	InsertFormatStorageMapping(map, GL_R32UI, GL_UNSIGNED_INT);
+	InsertFormatStorageMapping(map, GL_R32I, GL_INT);
+	InsertFormatStorageMapping(map, GL_RG8, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_RG8_SNORM, GL_BYTE);
+	InsertFormatStorageMapping(map, GL_RG16F, GL_HALF_FLOAT);
+	InsertFormatStorageMapping(map, GL_RG32F, GL_FLOAT);
+	InsertFormatStorageMapping(map, GL_RG8UI, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_RG8I, GL_BYTE);
+	InsertFormatStorageMapping(map, GL_RG16UI, GL_UNSIGNED_SHORT);
+	InsertFormatStorageMapping(map, GL_RG16I, GL_SHORT);
+	InsertFormatStorageMapping(map, GL_RG32UI, GL_UNSIGNED_INT);
+	InsertFormatStorageMapping(map, GL_RG32I, GL_INT);
+	InsertFormatStorageMapping(map, GL_RGB8, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_SRGB8, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5);
+	InsertFormatStorageMapping(map, GL_RGB8_SNORM, GL_BYTE);
+	InsertFormatStorageMapping(map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV);
+	InsertFormatStorageMapping(map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV);
+	InsertFormatStorageMapping(map, GL_RGB16F, GL_HALF_FLOAT);
+	InsertFormatStorageMapping(map, GL_RGB32F, GL_FLOAT);
+	InsertFormatStorageMapping(map, GL_RGB8UI, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_RGB8I, GL_BYTE);
+	InsertFormatStorageMapping(map, GL_RGB16UI, GL_UNSIGNED_SHORT);
+	InsertFormatStorageMapping(map, GL_RGB16I, GL_SHORT);
+	InsertFormatStorageMapping(map, GL_RGB32UI, GL_UNSIGNED_INT);
+	InsertFormatStorageMapping(map, GL_RGB32I, GL_INT);
+	InsertFormatStorageMapping(map, GL_RGBA8, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_RGBA8_SNORM, GL_BYTE);
+	InsertFormatStorageMapping(map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);
+	InsertFormatStorageMapping(map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);
+	InsertFormatStorageMapping(map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV);
+	InsertFormatStorageMapping(map, GL_RGBA16F, GL_HALF_FLOAT);
+	InsertFormatStorageMapping(map, GL_RGBA32F, GL_FLOAT);
+	InsertFormatStorageMapping(map, GL_RGBA8UI, GL_UNSIGNED_BYTE);
+	InsertFormatStorageMapping(map, GL_RGBA8I, GL_BYTE);
+	InsertFormatStorageMapping(map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV);
+	InsertFormatStorageMapping(map, GL_RGBA16UI, GL_UNSIGNED_SHORT);
+	InsertFormatStorageMapping(map, GL_RGBA16I, GL_SHORT);
+	InsertFormatStorageMapping(map, GL_RGBA32UI, GL_UNSIGNED_INT);
+	InsertFormatStorageMapping(map, GL_RGBA32I, GL_INT);
+
+	InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT);
+	InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT);
+	InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT32F, GL_FLOAT);
+	InsertFormatStorageMapping(map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8);
+	InsertFormatStorageMapping(map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+	return map;
+}
+
+static bool GetStorageType(GLenum internalformat, GLenum& type)
+{
+	static const FormatMapStorage formatMap = BuildFormatMapStorage2D();
+	FormatMapStorage::const_iterator iter = formatMap.find(internalformat);
+	if(iter != formatMap.end())
+	{
+		type = iter->second;
+		return true;
+	}
+	return false;
+}
+
+static bool ValidateQueryTarget(GLenum target)
+{
+	switch(target)
+	{
+	case GL_ANY_SAMPLES_PASSED:
+	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool ValidateTexParamParameters(GLenum pname, GLint param)
+{
+	switch(pname)
+	{
+	case GL_TEXTURE_WRAP_S:
+	case GL_TEXTURE_WRAP_T:
+	case GL_TEXTURE_WRAP_R:
+		switch(param)
+		{
+		case GL_REPEAT:
+		case GL_CLAMP_TO_EDGE:
+		case GL_MIRRORED_REPEAT:
+			return true;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+
+	case GL_TEXTURE_MIN_FILTER:
+		switch(param)
+		{
+		case GL_NEAREST:
+		case GL_LINEAR:
+		case GL_NEAREST_MIPMAP_NEAREST:
+		case GL_LINEAR_MIPMAP_NEAREST:
+		case GL_NEAREST_MIPMAP_LINEAR:
+		case GL_LINEAR_MIPMAP_LINEAR:
+			return true;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+		break;
+
+	case GL_TEXTURE_MAG_FILTER:
+		switch(param)
+		{
+		case GL_NEAREST:
+		case GL_LINEAR:
+			return true;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+		break;
+
+	case GL_TEXTURE_USAGE_ANGLE:
+		switch(param)
+		{
+		case GL_NONE:
+		case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
+			return true;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+		break;
+
+	case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+		// we assume the parameter passed to this validation method is truncated, not rounded
+		if(param < 1)
+		{
+			return error(GL_INVALID_VALUE, false);
+		}
+		return true;
+
+	case GL_TEXTURE_MIN_LOD:
+	case GL_TEXTURE_MAX_LOD:
+		// any value is permissible
+		return true;
+
+	case GL_TEXTURE_COMPARE_MODE:
+		// Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
+		switch(param)
+		{
+		case GL_NONE:
+		case GL_COMPARE_REF_TO_TEXTURE:
+			return true;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+		break;
+
+	case GL_TEXTURE_COMPARE_FUNC:
+		// Acceptable function parameters from GLES 3.0.2 spec, table 3.17
+		switch(param)
+		{
+		case GL_LEQUAL:
+		case GL_GEQUAL:
+		case GL_LESS:
+		case GL_GREATER:
+		case GL_EQUAL:
+		case GL_NOTEQUAL:
+		case GL_ALWAYS:
+		case GL_NEVER:
+			return true;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+		break;
+
+	case GL_TEXTURE_SWIZZLE_R:
+	case GL_TEXTURE_SWIZZLE_G:
+	case GL_TEXTURE_SWIZZLE_B:
+	case GL_TEXTURE_SWIZZLE_A:
+		switch(param)
+		{
+		case GL_RED:
+		case GL_GREEN:
+		case GL_BLUE:
+		case GL_ALPHA:
+		case GL_ZERO:
+		case GL_ONE:
+			return true;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+		break;
+
+	case GL_TEXTURE_BASE_LEVEL:
+	case GL_TEXTURE_MAX_LEVEL:
+		if(param < 0)
+		{
+			return error(GL_INVALID_VALUE, false);
+		}
+		return true;
+
+	default:
+		return error(GL_INVALID_ENUM, false);
+	}
+}
+
+static bool ValidateSamplerObjectParameter(GLenum pname)
+{
+	switch(pname)
+	{
+	case GL_TEXTURE_MIN_FILTER:
+	case GL_TEXTURE_MAG_FILTER:
+	case GL_TEXTURE_WRAP_S:
+	case GL_TEXTURE_WRAP_T:
+	case GL_TEXTURE_WRAP_R:
+	case GL_TEXTURE_MIN_LOD:
+	case GL_TEXTURE_MAX_LOD:
+	case GL_TEXTURE_COMPARE_MODE:
+	case GL_TEXTURE_COMPARE_FUNC:
+		return true;
+	default:
+		return false;
+	}
+}
+
+extern "C"
+{
+
+GL_APICALL void GL_APIENTRY glReadBuffer(GLenum src)
+{
+	TRACE("(GLenum src = 0x%X)", src);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLuint readFramebufferName = context->getReadFramebufferName();
+
+		switch(src)
+		{
+		case GL_BACK:
+			if(readFramebufferName != 0)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			context->setFramebufferReadBuffer(src);
+			break;
+		case GL_NONE:
+			context->setFramebufferReadBuffer(src);
+			break;
+		case GL_COLOR_ATTACHMENT0:
+		case GL_COLOR_ATTACHMENT1:
+		case GL_COLOR_ATTACHMENT2:
+		case GL_COLOR_ATTACHMENT3:
+		case GL_COLOR_ATTACHMENT4:
+		case GL_COLOR_ATTACHMENT5:
+		case GL_COLOR_ATTACHMENT6:
+		case GL_COLOR_ATTACHMENT7:
+		case GL_COLOR_ATTACHMENT8:
+		case GL_COLOR_ATTACHMENT9:
+		case GL_COLOR_ATTACHMENT10:
+		case GL_COLOR_ATTACHMENT11:
+		case GL_COLOR_ATTACHMENT12:
+		case GL_COLOR_ATTACHMENT13:
+		case GL_COLOR_ATTACHMENT14:
+		case GL_COLOR_ATTACHMENT15:
+		case GL_COLOR_ATTACHMENT16:
+		case GL_COLOR_ATTACHMENT17:
+		case GL_COLOR_ATTACHMENT18:
+		case GL_COLOR_ATTACHMENT19:
+		case GL_COLOR_ATTACHMENT20:
+		case GL_COLOR_ATTACHMENT21:
+		case GL_COLOR_ATTACHMENT22:
+		case GL_COLOR_ATTACHMENT23:
+		case GL_COLOR_ATTACHMENT24:
+		case GL_COLOR_ATTACHMENT25:
+		case GL_COLOR_ATTACHMENT26:
+		case GL_COLOR_ATTACHMENT27:
+		case GL_COLOR_ATTACHMENT28:
+		case GL_COLOR_ATTACHMENT29:
+		case GL_COLOR_ATTACHMENT30:
+		case GL_COLOR_ATTACHMENT31:
+		{
+			GLuint index = (src - GL_COLOR_ATTACHMENT0);
+			if(index >= MAX_COLOR_ATTACHMENTS)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			if(readFramebufferName == 0)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			context->setFramebufferReadBuffer(src);
+		}
+			break;
+		default:
+			error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)
+{
+	TRACE("(GLenum mode = 0x%X, GLuint start = %d, GLuint end = %d, "
+		  "GLsizei count = %d, GLenum type = 0x%x, const void* indices = %p)",
+		  mode, start, end, count, type, indices);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(type)
+	{
+	case GL_UNSIGNED_BYTE:
+	case GL_UNSIGNED_SHORT:
+	case GL_UNSIGNED_INT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((count < 0) || (end < start))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawElements(mode, start, end, count, type, indices);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
+	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
+	      target, level, internalformat, width, height, depth, border, format, type, pixels);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D:
+	case GL_TEXTURE_2D_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!ValidateType3D(type) || !ValidateFormat3D(format))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
+	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!ValidateInternalFormat3D(internalformat, format, type))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+		"GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
+		"GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
+		target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D:
+	case GL_TEXTURE_2D_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!ValidateType3D(type) || !ValidateFormat3D(format))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if((width < 0) || (height < 0) || (depth < 0) || (xoffset < 0) || (yoffset < 0) || (zoffset < 0))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
+
+		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+
+		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
+		if(validationError == GL_NONE)
+		{
+			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
+		}
+		else
+		{
+			return error(validationError);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+		"GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+		target, level, xoffset, yoffset, zoffset, x, y, width, height);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D:
+	case GL_TEXTURE_2D_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if((width < 0) || (height < 0) || (xoffset < 0) || (yoffset < 0) || (zoffset < 0))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
+
+		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
+
+		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLenum colorbufferFormat = source->getFormat();
+		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
+
+		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
+		if(validationError != GL_NONE)
+		{
+			return error(validationError);
+		}
+
+		GLenum textureFormat = texture->getFormat(target, level);
+
+		if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
+		{
+			return;
+		}
+
+		texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+		"GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
+		target, level, internalformat, width, height, depth, border, imageSize, data);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D:
+	case GL_TEXTURE_2D_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
+	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) || (border != 0) || (imageSize < 0))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(internalformat)
+	{
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_COMPONENT16:
+	case GL_DEPTH_COMPONENT32_OES:
+	case GL_DEPTH_STENCIL:
+	case GL_DEPTH24_STENCIL8:
+		return error(GL_INVALID_OPERATION);
+	default:
+		{
+			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
+			if(validationError != GL_NONE)
+			{
+				return error(validationError);
+			}
+		}
+	}
+
+	if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
+{
+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
+	      "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
+	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+
+	switch(target)
+	{
+	case GL_TEXTURE_3D:
+	case GL_TEXTURE_2D_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
+	if(validationError != GL_NONE)
+	{
+		return error(validationError);
+	}
+
+	if(width == 0 || height == 0 || depth == 0 || !data)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGenQueries(GLsizei n, GLuint *ids)
+{
+	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			ids[i] = context->createQuery();
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids)
+{
+	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteQuery(ids[i]);
+		}
+	}
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsQuery(GLuint id)
+{
+	TRACE("(GLuint id = %d)", id);
+
+	if(id == 0)
+	{
+		return GL_FALSE;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Query *queryObject = context->getQuery(id);
+
+		if(queryObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GL_APICALL void GL_APIENTRY glBeginQuery(GLenum target, GLuint id)
+{
+	TRACE("(GLenum target = 0x%X, GLuint id = %d)", target, id);
+
+	if(!ValidateQueryTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(id == 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->beginQuery(target, id);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glEndQuery(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	if(!ValidateQueryTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->endQuery(target);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)",
+		  target, pname, params);
+
+	if(!ValidateQueryTarget(target) || (pname != GL_CURRENT_QUERY))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		params[0] = context->getActiveQuery(target);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
+{
+	TRACE("(GLuint id = %d, GLenum pname = 0x%X, GLint *params = %p)",
+	      id, pname, params);
+
+	switch(pname)
+	{
+	case GL_QUERY_RESULT:
+	case GL_QUERY_RESULT_AVAILABLE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Query *queryObject = context->getQuery(id);
+
+		if(!queryObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(context->getActiveQuery(queryObject->getType()) == id)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_QUERY_RESULT:
+			params[0] = queryObject->getResult();
+			break;
+		case GL_QUERY_RESULT_AVAILABLE:
+			params[0] = queryObject->isResultAvailable();
+			break;
+		default:
+			ASSERT(false);
+		}
+	}
+}
+
+GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer = nullptr;
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM, GL_TRUE);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION, GL_TRUE);
+		}
+
+		return buffer->unmap() ? GL_TRUE : GL_FALSE;
+	}
+
+	return GL_TRUE;
+}
+
+GL_APICALL void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)",
+	      target, pname, params);
+
+	if(pname != GL_BUFFER_MAP_POINTER)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer = nullptr;
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		*params = buffer->isMapped() ? (void*)(((const char*)buffer->data()) + buffer->offset()) : nullptr;
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs)
+{
+	TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
+
+	if(n < 0 || n > MAX_DRAW_BUFFERS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLuint drawFramebufferName = context->getDrawFramebufferName();
+
+		if((drawFramebufferName == 0) && (n != 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		for(unsigned int i = 0; i < (unsigned)n; i++)
+		{
+			switch(bufs[i])
+			{
+			case GL_BACK:
+				if(drawFramebufferName != 0)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			case GL_NONE:
+				break;
+			case GL_COLOR_ATTACHMENT0:
+			case GL_COLOR_ATTACHMENT1:
+			case GL_COLOR_ATTACHMENT2:
+			case GL_COLOR_ATTACHMENT3:
+			case GL_COLOR_ATTACHMENT4:
+			case GL_COLOR_ATTACHMENT5:
+			case GL_COLOR_ATTACHMENT6:
+			case GL_COLOR_ATTACHMENT7:
+			case GL_COLOR_ATTACHMENT8:
+			case GL_COLOR_ATTACHMENT9:
+			case GL_COLOR_ATTACHMENT10:
+			case GL_COLOR_ATTACHMENT11:
+			case GL_COLOR_ATTACHMENT12:
+			case GL_COLOR_ATTACHMENT13:
+			case GL_COLOR_ATTACHMENT14:
+			case GL_COLOR_ATTACHMENT15:
+			case GL_COLOR_ATTACHMENT16:
+			case GL_COLOR_ATTACHMENT17:
+			case GL_COLOR_ATTACHMENT18:
+			case GL_COLOR_ATTACHMENT19:
+			case GL_COLOR_ATTACHMENT20:
+			case GL_COLOR_ATTACHMENT21:
+			case GL_COLOR_ATTACHMENT22:
+			case GL_COLOR_ATTACHMENT23:
+			case GL_COLOR_ATTACHMENT24:
+			case GL_COLOR_ATTACHMENT25:
+			case GL_COLOR_ATTACHMENT26:
+			case GL_COLOR_ATTACHMENT27:
+			case GL_COLOR_ATTACHMENT28:
+			case GL_COLOR_ATTACHMENT29:
+			case GL_COLOR_ATTACHMENT30:
+			case GL_COLOR_ATTACHMENT31:
+				{
+					GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0);
+
+					if(index >= MAX_COLOR_ATTACHMENTS)
+					{
+						return error(GL_INVALID_OPERATION);
+					}
+
+					if(index != i)
+					{
+						return error(GL_INVALID_OPERATION);
+					}
+
+					if(drawFramebufferName == 0)
+					{
+						return error(GL_INVALID_OPERATION);
+					}
+				}
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+		}
+
+		context->setFramebufferDrawBuffers(n, bufs);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix2x3fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix3x2fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix2x4fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix4x2fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix3x4fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniformMatrix4x3fv(location, count, transpose, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+{
+	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
+	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
+	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+	switch(filter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(context->getReadFramebufferName() == context->getDrawFramebufferName())
+		{
+			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+	      target, samples, internalformat, width, height);
+
+	switch(target)
+	{
+	case GL_RENDERBUFFER:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width < 0 || height < 0 || samples < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   samples > es2::IMPLEMENTATION_MAX_SAMPLES)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		GLuint handle = context->getRenderbufferName();
+		if(handle == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+		case GL_DEPTH_COMPONENT32_OES:
+		case GL_DEPTH_COMPONENT32F:
+			context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
+			break;
+		case GL_R8UI:
+		case GL_R8I:
+		case GL_R16UI:
+		case GL_R16I:
+		case GL_R32UI:
+		case GL_R32I:
+		case GL_RG8UI:
+		case GL_RG8I:
+		case GL_RG16UI:
+		case GL_RG16I:
+		case GL_RG32UI:
+		case GL_RG32I:
+		case GL_RGB8UI:
+		case GL_RGB8I:
+		case GL_RGB16UI:
+		case GL_RGB16I:
+		case GL_RGB32UI:
+		case GL_RGB32I:
+		case GL_RGBA8UI:
+		case GL_RGBA8I:
+		case GL_RGB10_A2UI:
+		case GL_RGBA16UI:
+		case GL_RGBA16I:
+		case GL_RGBA32UI:
+		case GL_RGBA32I:
+			if(samples > 0)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_SRGB8_ALPHA8:
+		case GL_RGB10_A2:
+		case GL_R8:
+		case GL_RG8:
+		case GL_RGB8:
+		case GL_RGBA8:
+			context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
+			break;
+		case GL_STENCIL_INDEX8:
+			context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
+			break;
+		case GL_DEPTH24_STENCIL8:
+		case GL_DEPTH32F_STENCIL8:
+			context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
+			break;
+
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
+{
+	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %d, GLint level = %d, GLint layer = %d)",
+	      target, attachment, texture, level, layer);
+
+	// GLES 3.0.4 spec, p.209, section 4.4.2
+	// If texture is zero, any image or array of images attached to the attachment point
+	// named by attachment is detached. Any additional parameters(level, textarget,
+	// and / or layer) are ignored when texture is zero.
+	if(texture != 0 && (layer < 0 || level < 0))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		Texture* textureObject = context->getTexture(texture);
+		GLenum textarget = GL_NONE;
+		if(texture != 0)
+		{
+			if(!textureObject)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+
+			textarget = textureObject->getTarget();
+			switch(textarget)
+			{
+			case GL_TEXTURE_3D:
+			case GL_TEXTURE_2D_ARRAY:
+				if(layer >= es2::IMPLEMENTATION_MAX_TEXTURE_SIZE || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				break;
+			default:
+				return error(GL_INVALID_OPERATION);
+			}
+
+			if(textureObject->isCompressed(textarget, level))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
+		es2::Framebuffer *framebuffer = nullptr;
+		switch(target)
+		{
+		case GL_DRAW_FRAMEBUFFER:
+		case GL_FRAMEBUFFER:
+			framebuffer = context->getDrawFramebuffer();
+			break;
+		case GL_READ_FRAMEBUFFER:
+			framebuffer = context->getReadFramebuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!framebuffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0:
+		case GL_COLOR_ATTACHMENT1:
+		case GL_COLOR_ATTACHMENT2:
+		case GL_COLOR_ATTACHMENT3:
+		case GL_COLOR_ATTACHMENT4:
+		case GL_COLOR_ATTACHMENT5:
+		case GL_COLOR_ATTACHMENT6:
+		case GL_COLOR_ATTACHMENT7:
+		case GL_COLOR_ATTACHMENT8:
+		case GL_COLOR_ATTACHMENT9:
+		case GL_COLOR_ATTACHMENT10:
+		case GL_COLOR_ATTACHMENT11:
+		case GL_COLOR_ATTACHMENT12:
+		case GL_COLOR_ATTACHMENT13:
+		case GL_COLOR_ATTACHMENT14:
+		case GL_COLOR_ATTACHMENT15:
+		case GL_COLOR_ATTACHMENT16:
+		case GL_COLOR_ATTACHMENT17:
+		case GL_COLOR_ATTACHMENT18:
+		case GL_COLOR_ATTACHMENT19:
+		case GL_COLOR_ATTACHMENT20:
+		case GL_COLOR_ATTACHMENT21:
+		case GL_COLOR_ATTACHMENT22:
+		case GL_COLOR_ATTACHMENT23:
+		case GL_COLOR_ATTACHMENT24:
+		case GL_COLOR_ATTACHMENT25:
+		case GL_COLOR_ATTACHMENT26:
+		case GL_COLOR_ATTACHMENT27:
+		case GL_COLOR_ATTACHMENT28:
+		case GL_COLOR_ATTACHMENT29:
+		case GL_COLOR_ATTACHMENT30:
+		case GL_COLOR_ATTACHMENT31:
+			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level, layer);
+			break;
+		case GL_DEPTH_ATTACHMENT:
+			framebuffer->setDepthbuffer(textarget, texture, level, layer);
+			break;
+		case GL_STENCIL_ATTACHMENT:
+			framebuffer->setStencilbuffer(textarget, texture, level, layer);
+			break;
+		case GL_DEPTH_STENCIL_ATTACHMENT:
+			framebuffer->setDepthbuffer(textarget, texture, level, layer);
+			framebuffer->setStencilbuffer(textarget, texture, level, layer);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+{
+	TRACE("(GLenum target = 0x%X,  GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = %X)",
+	      target, offset, length, access);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer = nullptr;
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM, nullptr);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION, nullptr);
+		}
+
+		GLsizeiptr bufferSize = buffer->size();
+		if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))
+		{
+			error(GL_INVALID_VALUE);
+		}
+
+		if((access & ~(GL_MAP_READ_BIT |
+		               GL_MAP_WRITE_BIT |
+		               GL_MAP_INVALIDATE_RANGE_BIT |
+		               GL_MAP_INVALIDATE_BUFFER_BIT |
+		               GL_MAP_FLUSH_EXPLICIT_BIT |
+		               GL_MAP_UNSYNCHRONIZED_BIT)) != 0)
+		{
+			error(GL_INVALID_VALUE);
+		}
+
+		return buffer->mapRange(offset, length, access);
+	}
+
+	return nullptr;
+}
+
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+	TRACE("(GLenum target = 0x%X,  GLintptr offset = %d, GLsizeiptr length = %d)",
+	      target, offset, length);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer = nullptr;
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		GLsizeiptr bufferSize = buffer->size();
+		if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))
+		{
+			error(GL_INVALID_VALUE);
+		}
+
+		buffer->flushMappedRange(offset, length);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glBindVertexArray(GLuint array)
+{
+	TRACE("(GLuint array = %d)", array);
+
+	if(array == 0)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->isVertexArray(array))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->bindVertexArray(array);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint *arrays)
+{
+	TRACE("(GLsizei n = %d, const GLuint *arrays = %p)", n, arrays);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteVertexArray(arrays[i]);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint *arrays)
+{
+	TRACE("(GLsizei n = %d, const GLuint *arrays = %p)", n, arrays);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			arrays[i] = context->createVertexArray();
+		}
+	}
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArray(GLuint array)
+{
+	TRACE("(GLuint array = %d)", array);
+
+	if(array == 0)
+	{
+		return GL_FALSE;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::VertexArray *arrayObject = context->getVertexArray(array);
+
+		if(arrayObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GL_APICALL void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint *data)
+{
+	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLint* data = %p)",
+	      target, index, data);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->getTransformFeedbackiv(index, target, data) &&
+		   !context->getUniformBufferiv(index, target, data) &&
+		   !context->getIntegerv(target, data))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(target, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that target is valid, but there are no parameters to return
+
+			if(nativeType == GL_BOOL)
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(target, boolParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
+				}
+
+				delete[] boolParams;
+			}
+			else if(nativeType == GL_FLOAT)
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(target, floatParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
+					{
+						data[i] = es2::floatToInt(floatParams[i]);
+					}
+					else
+					{
+						data[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
+					}
+				}
+
+				delete[] floatParams;
+			}
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode)
+{
+	TRACE("(GLenum primitiveMode = 0x%X)", primitiveMode);
+
+	switch(primitiveMode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_TRIANGLES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
+
+		if(transformFeedbackObject)
+		{
+			if(transformFeedbackObject->isActive())
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			transformFeedbackObject->begin(primitiveMode);
+		}
+		else
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glEndTransformFeedback(void)
+{
+	TRACE("()");
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
+
+		if(transformFeedbackObject)
+		{
+			if(!transformFeedbackObject->isActive())
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			transformFeedbackObject->end();
+		}
+		else
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLuint buffer = %d, GLintptr offset = %d, GLsizeiptr size = %d)",
+	      target, index, buffer, offset, size);
+
+	if(buffer != 0 && size <= 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TRANSFORM_FEEDBACK_BUFFER:
+			if(index >= MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			if(size & 0x3 || offset & 0x3) // size and offset must be multiples of 4
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
+			context->bindGenericTransformFeedbackBuffer(buffer);
+			break;
+		case GL_UNIFORM_BUFFER:
+			if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			if(offset % UNIFORM_BUFFER_OFFSET_ALIGNMENT != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->bindIndexedUniformBuffer(buffer, index, offset, size);
+			context->bindGenericUniformBuffer(buffer);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLuint buffer = %d)",
+	      target, index, buffer);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TRANSFORM_FEEDBACK_BUFFER:
+			if(index >= MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
+			context->bindGenericTransformFeedbackBuffer(buffer);
+			break;
+		case GL_UNIFORM_BUFFER:
+			if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->bindIndexedUniformBuffer(buffer, index, 0, 0);
+			context->bindGenericUniformBuffer(buffer);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode)
+{
+	TRACE("(GLuint program = %d, GLsizei count = %d, const GLchar *const*varyings = %p, GLenum bufferMode = 0x%X)",
+	      program, count, varyings, bufferMode);
+
+	switch(bufferMode)
+	{
+	case GL_SEPARATE_ATTRIBS:
+		if(count > MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+	case GL_INTERLEAVED_ATTRIBS:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLsizei *size = %p, GLenum *type = %p, GLchar *name = %p)",
+	      program, index, bufSize, length, size, type, name);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		if(index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLsizei *size = %p, GLenum *type = %p, GLchar *name = %p)",
+	      index, size, type, stride, pointer);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(size < 1 || size > 4 || stride < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(type)
+	{
+	case GL_BYTE:
+	case GL_UNSIGNED_BYTE:
+	case GL_SHORT:
+	case GL_UNSIGNED_SHORT:
+	case GL_INT:
+	case GL_UNSIGNED_INT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, stride, pointer);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint *params = %p)",
+	      index, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= es2::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
+
+		switch(pname)
+		{
+		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+			*params = attribState.mSize;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+			*params = attribState.mStride;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+			*params = attribState.mType;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+			*params = attribState.mBoundBuffer.name();
+			break;
+		case GL_CURRENT_VERTEX_ATTRIB:
+			{
+				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
+				for(int i = 0; i < 4; ++i)
+				{
+					params[i] = attrib.getCurrentValueI(i);
+				}
+			}
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+			switch(attribState.mType)
+			{
+			case GL_BYTE:
+			case GL_UNSIGNED_BYTE:
+			case GL_SHORT:
+			case GL_UNSIGNED_SHORT:
+			case GL_INT:
+			case GL_INT_2_10_10_10_REV:
+			case GL_UNSIGNED_INT:
+			case GL_FIXED:
+				*params = GL_TRUE;
+				break;
+			default:
+				*params = GL_FALSE;
+				break;
+			}
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+			*params = attribState.mDivisor;
+			break;
+		default: return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
+{
+	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLuint *params = %p)",
+		index, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= es2::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
+
+		switch(pname)
+		{
+		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+			*params = attribState.mSize;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+			*params = attribState.mStride;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+			*params = attribState.mType;
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+			*params = attribState.mBoundBuffer.name();
+			break;
+		case GL_CURRENT_VERTEX_ATTRIB:
+			{
+				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
+				for(int i = 0; i < 4; ++i)
+				{
+					params[i] = attrib.getCurrentValueUI(i);
+				}
+			}
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+			switch(attribState.mType)
+			{
+			case GL_BYTE:
+			case GL_UNSIGNED_BYTE:
+			case GL_SHORT:
+			case GL_UNSIGNED_SHORT:
+			case GL_INT:
+			case GL_INT_2_10_10_10_REV:
+			case GL_UNSIGNED_INT:
+			case GL_FIXED:
+				*params = GL_TRUE;
+				break;
+			default:
+				*params = GL_FALSE;
+				break;
+			}
+			break;
+		case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+			*params = attribState.mDivisor;
+			break;
+		default: return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+	TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
+	      index, x, y, z, w);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLint vals[4] = { x, y, z, w };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+	TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
+	      index, x, y, z, w);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		GLuint vals[4] = { x, y, z, w };
+		context->setVertexAttrib(index, vals);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint *v)
+{
+	TRACE("(GLuint index = %d, GLint *v = %p)", index, v);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(index, v);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint *v)
+{
+	TRACE("(GLuint index = %d, GLint *v = %p)", index, v);
+
+	if(index >= es2::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(index, v);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint *params)
+{
+	TRACE("(GLuint program = %d, GLint location = %d, GLuint *params = %p)",
+	      program, location, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(program == 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->getUniformuiv(location, nullptr, params))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name)
+{
+	TRACE("(GLuint program = %d, const GLchar *name = %p)", program, name);
+
+	es2::Context *context = es2::getContext();
+
+	if(strstr(name, "gl_") == name)
+	{
+		return -1;
+	}
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			if(context->getShader(program))
+			{
+				return error(GL_INVALID_OPERATION, -1);
+			}
+			else
+			{
+				return error(GL_INVALID_VALUE, -1);
+			}
+		}
+
+		if(!programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION, -1);
+		}
+	}
+
+	UNIMPLEMENTED();
+	return -1;
+}
+
+GL_APICALL void GL_APIENTRY glUniform1ui(GLint location, GLuint v0)
+{
+	glUniform1uiv(location, 1, &v0);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+	GLuint xy[2] = { v0, v1 };
+
+	glUniform2uiv(location, 1, (GLuint*)&xy);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+	GLuint xyz[3] = { v0, v1, v2 };
+
+	glUniform3uiv(location, 1, (GLuint*)&xyz);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+	GLuint xyzw[4] = { v0, v1, v2, v3 };
+
+	glUniform4uiv(location, 1, (GLuint*)&xyzw);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
+	      location, count, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform1uiv(location, count, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
+	      location, count, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform2uiv(location, count, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
+	      location, count, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform3uiv(location, count, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint *value)
+{
+	TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
+	      location, count, value);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(location == -1)
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *program = context->getCurrentProgram();
+
+		if(!program)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!program->setUniform4uiv(location, count, value))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
+{
+	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint *value = %p)",
+	      buffer, drawbuffer, value);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(buffer)
+		{
+		case GL_COLOR:
+			if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				context->clearColorBuffer(drawbuffer, value);
+			}
+			break;
+		case GL_STENCIL:
+			if(drawbuffer != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				context->clearStencilBuffer(value[0]);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
+{
+	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint *value = %p)",
+	      buffer, drawbuffer, value);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(buffer)
+		{
+		case GL_COLOR:
+			if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				context->clearColorBuffer(drawbuffer, value);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
+{
+	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat *value = %p)",
+	      buffer, drawbuffer, value);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(buffer)
+		{
+		case GL_COLOR:
+			if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				context->clearColorBuffer(drawbuffer, value);
+			}
+			break;
+		case GL_DEPTH:
+			if(drawbuffer != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				context->clearDepthBuffer(value[0]);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+	TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth = %f, GLint stencil = %d)",
+	      buffer, drawbuffer, depth, stencil);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(buffer)
+		{
+		case GL_DEPTH_STENCIL:
+			if(drawbuffer != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			else
+			{
+				context->clearDepthBuffer(depth);
+				context->clearStencilBuffer(stencil);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL const GLubyte *GL_APIENTRY glGetStringi(GLenum name, GLuint index)
+{
+	TRACE("(GLenum name = 0x%X, GLuint index = %d)", name, index);
+
+	es2::Context *context = es2::getContext();
+	if(context)
+	{
+		GLuint numExtensions;
+		context->getExtensions(0, &numExtensions);
+
+		if(index >= numExtensions)
+		{
+			return error(GL_INVALID_VALUE, (GLubyte*)nullptr);
+		}
+
+		switch(name)
+		{
+		case GL_EXTENSIONS:
+			return context->getExtensions(index);
+		default:
+			return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
+		}
+	}
+
+	return (GLubyte*)nullptr;
+}
+
+GL_APICALL void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
+{
+	TRACE("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X,  GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
+	      readTarget, writeTarget, readOffset, writeOffset, size);
+
+	if(readOffset < 0 || writeOffset < 0 || size < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *readBuffer = nullptr, *writeBuffer = nullptr;
+		if(!context->getBuffer(readTarget, &readBuffer) || !context->getBuffer(writeTarget, &writeBuffer))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		if(!readBuffer || readBuffer->isMapped() || !writeBuffer || writeBuffer->isMapped())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+		if(readBuffer == writeBuffer)
+		{
+			// If same buffer, check for overlap
+			if(((readOffset >= writeOffset) && (readOffset < (writeOffset + size))) ||
+			   ((writeOffset >= readOffset) && (writeOffset < (readOffset + size))))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		if((static_cast<size_t>(readOffset + size) > readBuffer->size()) ||
+		   (static_cast<size_t>(writeOffset + size) > writeBuffer->size()))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		writeBuffer->bufferSubData(((char*)readBuffer->data()) + readOffset, size, writeOffset);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices)
+{
+	TRACE("(GLuint program = %d, GLsizei uniformCount = %d, const GLchar *const*uniformNames = %p, GLuint *uniformIndices = %p)",
+	      program, uniformCount, uniformNames, uniformIndices);
+
+	if(uniformCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if(!programObject->isLinked())
+		{
+			for(int uniformId = 0; uniformId < uniformCount; uniformId++)
+			{
+				uniformIndices[uniformId] = GL_INVALID_INDEX;
+			}
+		}
+		else
+		{
+			for(int uniformId = 0; uniformId < uniformCount; uniformId++)
+			{
+				uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
+			}
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params)
+{
+	TRACE("(GLuint program = %d, GLsizei uniformCount = %d, const GLchar *const*uniformNames = %p, GLenum pname = 0x%X, GLuint *uniformIndices = %p)",
+	      program, uniformCount, uniformIndices, pname, uniformIndices);
+
+	switch(pname)
+	{
+	case GL_UNIFORM_TYPE:
+	case GL_UNIFORM_SIZE:
+	case GL_UNIFORM_NAME_LENGTH:
+	case GL_UNIFORM_BLOCK_INDEX:
+	case GL_UNIFORM_OFFSET:
+	case GL_UNIFORM_ARRAY_STRIDE:
+	case GL_UNIFORM_MATRIX_STRIDE:
+	case GL_UNIFORM_IS_ROW_MAJOR:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(uniformCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		for(int uniformId = 0; uniformId < uniformCount; uniformId++)
+		{
+			const GLuint index = uniformIndices[uniformId];
+
+			if(index >= programObject->getActiveUniformCount())
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		for(int uniformId = 0; uniformId < uniformCount; uniformId++)
+		{
+			const GLuint index = uniformIndices[uniformId];
+			params[uniformId] = programObject->getActiveUniformi(index, pname);
+		}
+	}
+}
+
+GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
+{
+	TRACE("(GLuint program = %d, const GLchar *uniformBlockName = %p)",
+	      program, uniformBlockName);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
+		}
+
+		return programObject->getUniformBlockIndex(uniformBlockName);
+	}
+
+	return GL_INVALID_INDEX;
+}
+
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)
+{
+	TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLenum pname = 0x%X, GLint *params = %p)",
+	      program, uniformBlockIndex, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_UNIFORM_BLOCK_BINDING:
+			*params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
+			break;
+		case GL_UNIFORM_BLOCK_DATA_SIZE:
+		case GL_UNIFORM_BLOCK_NAME_LENGTH:
+		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+		case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+		case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+			programObject->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName)
+{
+	TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLchar *uniformBlockName = %p)",
+	      program, uniformBlockIndex, bufSize, length, uniformBlockName);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+	TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLuint uniformBlockBinding = %d)",
+	      program, uniformBlockIndex, uniformBlockBinding);
+
+	if(uniformBlockBinding >= MAX_UNIFORM_BUFFER_BINDINGS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		programObject->bindUniformBlock(uniformBlockIndex, uniformBlockIndex);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
+	      mode, first, count, instanceCount);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0 || instanceCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawArrays(mode, first, count, instanceCount);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
+	      mode, count, type, indices, instanceCount);
+
+	switch(mode)
+	{
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(type)
+	{
+	case GL_UNSIGNED_BYTE:
+	case GL_UNSIGNED_SHORT:
+	case GL_UNSIGNED_INT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(count < 0 || instanceCount < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
+	}
+}
+
+GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
+{
+	TRACE("(GLenum condition = 0x%X, GLbitfield flags = %X)", condition, flags);
+
+	switch(condition)
+	{
+	case GL_SYNC_GPU_COMMANDS_COMPLETE:
+		break;
+	default:
+		return error(GL_INVALID_ENUM, nullptr);
+	}
+
+	if(flags != 0)
+	{
+		return error(GL_INVALID_VALUE, nullptr);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		return context->createFenceSync(condition, flags);
+	}
+
+	return nullptr;
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsSync(GLsync sync)
+{
+	TRACE("(GLsync sync = %p)", sync);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
+
+		if(fenceSyncObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GL_APICALL void GL_APIENTRY glDeleteSync(GLsync sync)
+{
+	TRACE("(GLsync sync = %p)", sync);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		context->deleteFenceSync(sync);
+	}
+}
+
+GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+	TRACE("(GLsync sync = %p, GLbitfield flags = %X, GLuint64 timeout = %llu)", sync, flags, timeout);
+
+	if((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
+	{
+		error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
+
+		if(fenceSyncObject)
+		{
+			return fenceSyncObject->clientWait(flags, timeout);
+		}
+		else
+		{
+			return error(GL_INVALID_VALUE, GL_FALSE);
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GL_APICALL void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+	TRACE("(GLsync sync = %p, GLbitfield flags = %X, GLuint64 timeout = %llu)", sync, flags, timeout);
+
+	if(flags != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(timeout != GL_TIMEOUT_IGNORED)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
+
+		if(fenceSyncObject)
+		{
+			fenceSyncObject->serverWait(flags, timeout);
+		}
+		else
+		{
+			return error(GL_INVALID_VALUE);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *data)
+{
+	TRACE("(GLenum pname = 0x%X, GLint64 *data = %p)", pname, data);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!(context->getIntegerv(pname, data)))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that pname is valid, but there are no parameters to return
+
+			if(nativeType == GL_BOOL)
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
+				}
+
+				delete[] boolParams;
+			}
+			else if(nativeType == GL_FLOAT)
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
+					{
+						data[i] = (GLint64)(es2::floatToInt(floatParams[i]));
+					}
+					else
+					{
+						data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
+					}
+				}
+
+				delete[] floatParams;
+			}
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
+{
+	TRACE("(GLsync sync = %p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei *length = %p, GLint *values = %p)",
+	      sync, pname, bufSize, length, values);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	UNIMPLEMENTED();
+}
+
+GL_APICALL void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data)
+{
+	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLint64 *data = %p)", target, index, data);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->getTransformFeedbackiv(index, target, data) &&
+		   !context->getUniformBufferiv(index, target, data) &&
+		   !context->getIntegerv(target, data))
+		{
+			GLenum nativeType;
+			unsigned int numParams = 0;
+			if(!context->getQueryParameterInfo(target, &nativeType, &numParams))
+				return error(GL_INVALID_ENUM);
+
+			if(numParams == 0)
+				return; // it is known that target is valid, but there are no parameters to return
+
+			if(nativeType == GL_BOOL)
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(target, boolParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
+				}
+
+				delete[] boolParams;
+			}
+			else if(nativeType == GL_FLOAT)
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(target, floatParams);
+
+				for(unsigned int i = 0; i < numParams; ++i)
+				{
+					if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
+					{
+						data[i] = (GLint64)(es2::floatToInt(floatParams[i]));
+					}
+					else
+					{
+						data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
+					}
+				}
+
+				delete[] floatParams;
+			}
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64 *params = %p)", target, pname, params);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Buffer *buffer = nullptr;
+
+		if(!context->getBuffer(target, &buffer))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			// A null buffer means that "0" is bound to the requested buffer target
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_BUFFER_USAGE:
+			*params = buffer->usage();
+			break;
+		case GL_BUFFER_SIZE:
+			*params = buffer->size();
+			break;
+		case GL_BUFFER_ACCESS_FLAGS:
+			*params = buffer->access();
+			break;
+		case GL_BUFFER_MAPPED:
+			*params = buffer->isMapped();
+			break;
+		case GL_BUFFER_MAP_LENGTH:
+			*params = buffer->length();
+			break;
+		case GL_BUFFER_MAP_OFFSET:
+			*params = buffer->offset();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGenSamplers(GLsizei count, GLuint *samplers)
+{
+	TRACE("(GLsizei count = %d, GLuint *samplers = %p)", count, samplers);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < count; i++)
+		{
+			samplers[i] = context->createSampler();
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint *samplers)
+{
+	TRACE("(GLsizei count = %d, GLuint *samplers = %p)", count, samplers);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < count; i++)
+		{
+			context->deleteSampler(samplers[i]);
+		}
+	}
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsSampler(GLuint sampler)
+{
+	TRACE("(GLuint sampler = %d)", sampler);
+
+	if(sampler == 0)
+	{
+		return GL_FALSE;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(context->isSampler(sampler))
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GL_APICALL void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler)
+{
+	TRACE("(GLuint unit = %d, GLuint sampler = %d)", unit, sampler);
+
+	if(unit >= es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(sampler != 0 && !context->isSampler(sampler))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->bindSampler(unit, sampler);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLint param = %d)",
+	      sampler, pname, param);
+
+	glSamplerParameteriv(sampler, pname, &param);
+}
+
+GL_APICALL void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
+{
+	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, const GLint *param = %p)",
+	      sampler, pname, param);
+
+	if(!ValidateSamplerObjectParameter(pname))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!ValidateTexParamParameters(pname, *param))
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->isSampler(sampler))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->samplerParameteri(sampler, pname, *param);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLfloat param = %f)",
+	      sampler, pname, param);
+
+	glSamplerParameterfv(sampler, pname, &param);
+}
+
+GL_APICALL void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
+{
+	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, const GLfloat *param = %p)",
+	      sampler, pname, param);
+
+	if(!ValidateSamplerObjectParameter(pname))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!ValidateTexParamParameters(pname, *param))
+	{
+		return;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->isSampler(sampler))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->samplerParameterf(sampler, pname, *param);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
+{
+	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLint *params = %p)",
+	      sampler, pname, params);
+
+	if(!ValidateSamplerObjectParameter(pname))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->isSampler(sampler))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		*params = context->getSamplerParameteri(sampler, pname);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
+{
+	TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLfloat *params = %p)",
+	      sampler, pname, params);
+
+	if(!ValidateSamplerObjectParameter(pname))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(!context->isSampler(sampler))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		*params = context->getSamplerParameterf(sampler, pname);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
+{
+	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(index >= es2::MAX_VERTEX_ATTRIBS)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		context->setVertexAttribDivisor(index, divisor);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)
+{
+	TRACE("(GLenum target = 0x%X, GLuint id = %d)", target, id);
+
+	if(target != GL_TRANSFORM_FEEDBACK)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
+
+		if(transformFeedbackObject && transformFeedbackObject->isActive() && !transformFeedbackObject->isPaused())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->bindTransformFeedback(id);
+	}
+}
+
+GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
+{
+	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			if(ids[i] != 0)
+			{
+				context->deleteTransformFeedback(ids[i]);
+			}
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint *ids)
+{
+	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			ids[i] = context->createTransformFeedback();
+		}
+	}
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id)
+{
+	TRACE("(GLuint id = %d)", id);
+
+	if(id == 0)
+	{
+		return GL_FALSE;
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback(id);
+
+		if(transformFeedbackObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GL_APICALL void GL_APIENTRY glPauseTransformFeedback(void)
+{
+	TRACE("()");
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
+
+		if(transformFeedbackObject)
+		{
+			if(!transformFeedbackObject->isActive() || transformFeedbackObject->isPaused())
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			transformFeedbackObject->setPaused(true);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glResumeTransformFeedback(void)
+{
+	TRACE("()");
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
+
+		if(transformFeedbackObject)
+		{
+			if(!transformFeedbackObject->isActive() || !transformFeedbackObject->isPaused())
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			transformFeedbackObject->setPaused(false);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
+{
+	TRACE("(GLuint program = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLenum *binaryFormat = %p, void *binary = %p)",
+	      program, bufSize, length, binaryFormat, binary);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	UNIMPLEMENTED();
+}
+
+GL_APICALL void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
+{
+	TRACE("(GLuint program = %d, GLenum binaryFormat = 0x%X, const void *binary = %p, GLsizei length = %d)",
+	      program, binaryFormat, binaryFormat, length);
+
+	if(length < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	UNIMPLEMENTED();
+}
+
+GL_APICALL void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint value = %d)",
+	      program, pname, value);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(pname)
+		{
+		case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+			programObject->setBinaryRetrievable(value != GL_FALSE);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
+{
+	TRACE("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = %p)",
+	      target, numAttachments, attachments);
+
+	glInvalidateSubFramebuffer(target, numAttachments, attachments, 0, 0, std::numeric_limits<GLsizei>::max(), std::numeric_limits<GLsizei>::max());
+}
+
+GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = %p, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+	      target, numAttachments, attachments, x, y, width, height);
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		if(numAttachments < 0 || width < 0 || height < 0)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		es2::Framebuffer *framebuffer = nullptr;
+		switch(target)
+		{
+		case GL_DRAW_FRAMEBUFFER:
+		case GL_FRAMEBUFFER:
+			framebuffer = context->getDrawFramebuffer();
+		case GL_READ_FRAMEBUFFER:
+			framebuffer = context->getReadFramebuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(framebuffer)
+		{
+			for(int i = 0; i < numAttachments; i++)
+			{
+				switch(attachments[i])
+				{
+				case GL_COLOR:
+				case GL_DEPTH:
+				case GL_STENCIL:
+					if(!framebuffer->isDefaultFramebuffer())
+					{
+						return error(GL_INVALID_ENUM);
+					}
+					break;
+				case GL_DEPTH_ATTACHMENT:
+				case GL_STENCIL_ATTACHMENT:
+				case GL_DEPTH_STENCIL_ATTACHMENT:
+					break;
+				default:
+					if(attachments[i] >= GL_COLOR_ATTACHMENT0 &&
+					   attachments[i] <= GL_COLOR_ATTACHMENT31)
+					{
+						if(attachments[i] - GL_COLOR_ATTACHMENT0 >= MAX_DRAW_BUFFERS)
+						{
+							return error(GL_INVALID_OPERATION);
+						}
+					}
+					else
+					{
+						return error(GL_INVALID_ENUM);
+					}
+					break;
+				}
+			}
+		}
+
+		// UNIMPLEMENTED();   // It is valid for this function to be treated as a no-op
+	}
+}
+
+GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+	      target, levels, internalformat, width, height);
+
+	if(width < 1 || height < 1 || levels < 1)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	GLenum type;
+	if(!GetStorageType(internalformat, type))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+		{
+			es2::Texture2D *texture = context->getTexture2D();
+			if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			for(int level = 0; level < levels; ++level)
+			{
+				texture->setImage(level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
+				width = std::max(1, (width / 2));
+				height = std::max(1, (height / 2));
+			}
+			texture->makeImmutable(levels);
+		}
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+		{
+			es2::TextureCubeMap *texture = context->getTextureCubeMap();
+			if(!texture || texture->name == 0 || texture->getImmutableFormat())
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			for(int level = 0; level < levels; ++level)
+			{
+				for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
+				{
+					texture->setImage(face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
+				}
+				width = std::max(1, (width / 2));
+				height = std::max(1, (height / 2));
+			}
+			texture->makeImmutable(levels);
+		}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+	TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d)",
+	      target, levels, internalformat, width, height, depth);
+
+	if(width < 1 || height < 1 || depth < 1 || levels < 1)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	GLenum type;
+	if(!GetStorageType(internalformat, type))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_3D:
+		{
+			if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			es2::Texture3D *texture = context->getTexture3D();
+			if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			for(int level = 0; level < levels; ++level)
+			{
+				texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
+				width = std::max(1, (width / 2));
+				height = std::max(1, (height / 2));
+				depth = std::max(1, (depth / 2));
+			}
+			texture->makeImmutable(levels);
+		}
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+		{
+			if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			es2::Texture3D *texture = context->getTexture2DArray();
+			if(!texture || texture->name == 0 || texture->getImmutableFormat())
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			for(int level = 0; level < levels; ++level)
+			{
+				for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
+				{
+					texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
+				}
+				width = std::max(1, (width / 2));
+				height = std::max(1, (height / 2));
+			}
+			texture->makeImmutable(levels);
+		}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, GLint *params = %p)",
+	      target, internalformat, pname, bufSize, params);
+
+	if(bufSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(bufSize == 0)
+	{
+		return;
+	}
+
+	if(!IsColorRenderable(internalformat, egl::getClientVersion()) && !IsDepthRenderable(internalformat) && !IsStencilRenderable(internalformat))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(target)
+	{
+	case GL_RENDERBUFFER:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	// Integer types have no multisampling
+	GLint numMultisampleCounts = NUM_MULTISAMPLE_COUNTS;
+	switch(internalformat)
+	{
+	case GL_R8UI:
+	case GL_R8I:
+	case GL_R16UI:
+	case GL_R16I:
+	case GL_R32UI:
+	case GL_R32I:
+	case GL_RG8UI:
+	case GL_RG8I:
+	case GL_RG16UI:
+	case GL_RG16I:
+	case GL_RG32UI:
+	case GL_RG32I:
+	case GL_RGB8UI:
+	case GL_RGB8I:
+	case GL_RGB16UI:
+	case GL_RGB16I:
+	case GL_RGB32UI:
+	case GL_RGB32I:
+	case GL_RGBA8UI:
+	case GL_RGBA8I:
+	case GL_RGB10_A2UI:
+	case GL_RGBA16UI:
+	case GL_RGBA16I:
+	case GL_RGBA32UI:
+	case GL_RGBA32I:
+		numMultisampleCounts = 0;
+		break;
+	default:
+		break;
+	}
+
+	switch(pname)
+	{
+	case GL_NUM_SAMPLE_COUNTS:
+		*params = numMultisampleCounts;
+		break;
+	case GL_SAMPLES:
+		for(int i = 0; i < numMultisampleCounts && i < bufSize; i++)
+		{
+			params[i] = multisampleCount[i];
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+}
diff --git a/src/OpenGL/libGLESv2/main.cpp b/src/OpenGL/libGLESv2/main.cpp
index 6fd3fef..99d24e1 100644
--- a/src/OpenGL/libGLESv2/main.cpp
+++ b/src/OpenGL/libGLESv2/main.cpp
@@ -1,1543 +1,1546 @@
-// 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.

-//

-

-// main.cpp: DLL entry point and management of thread-local data.

-

-#include "main.h"

-

-#include "libGLESv2.hpp"

-#include "Framebuffer.h"

-#include "libEGL/main.h"

-#include "libEGL/Surface.h"

-#include "Common/Thread.hpp"

-#include "Common/SharedLibrary.hpp"

-#include "common/debug.h"

-

-#if !defined(_MSC_VER)

-#define CONSTRUCTOR __attribute__((constructor))

-#define DESTRUCTOR __attribute__((destructor))

-#else

-#define CONSTRUCTOR

-#define DESTRUCTOR

-#endif

-

-static void glAttachThread()

-{

-    TRACE("()");

-}

-

-static void glDetachThread()

-{

-    TRACE("()");

-}

-

-CONSTRUCTOR static void glAttachProcess()

-{

-    TRACE("()");

-

-    glAttachThread();

-}

-

-DESTRUCTOR static void glDetachProcess()

-{

-    TRACE("()");

-

-	glDetachThread();

-}

-

-#if defined(_WIN32)

-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)

-{

-    switch(reason)

-    {

-    case DLL_PROCESS_ATTACH:

-        glAttachProcess();

-        break;

-    case DLL_THREAD_ATTACH:

-        glAttachThread();

-        break;

-    case DLL_THREAD_DETACH:

-        glDetachThread();

-        break;

-    case DLL_PROCESS_DETACH:

-        glDetachProcess();

-        break;

-    default:

-        break;

-    }

-

-    return TRUE;

-}

-#endif

-

-namespace es2

-{

-es2::Context *getContext()

-{

-	egl::Context *context = libEGL->clientGetCurrentContext();

-

-	if(context && (context->getClientVersion() == 2 ||

-	               context->getClientVersion() == 3))

-	{

-		return static_cast<es2::Context*>(context);

-	}

-

-	return 0;

-}

-

-Device *getDevice()

-{

-    Context *context = getContext();

-

-    return context ? context->getDevice() : 0;

-}

-

-// Records an error code

-void error(GLenum errorCode)

-{

-    es2::Context *context = es2::getContext();

-

-    if(context)

-    {

-        switch(errorCode)

-        {

-        case GL_INVALID_ENUM:

-            context->recordInvalidEnum();

-            TRACE("\t! Error generated: invalid enum\n");

-            break;

-        case GL_INVALID_VALUE:

-            context->recordInvalidValue();

-            TRACE("\t! Error generated: invalid value\n");

-            break;

-        case GL_INVALID_OPERATION:

-            context->recordInvalidOperation();

-            TRACE("\t! Error generated: invalid operation\n");

-            break;

-        case GL_OUT_OF_MEMORY:

-            context->recordOutOfMemory();

-            TRACE("\t! Error generated: out of memory\n");

-            break;

-        case GL_INVALID_FRAMEBUFFER_OPERATION:

-            context->recordInvalidFramebufferOperation();

-            TRACE("\t! Error generated: invalid framebuffer operation\n");

-            break;

-        default: UNREACHABLE(errorCode);

-        }

-    }

-}

-}

-

-namespace egl

-{

-GLint getClientVersion()

-{

-	Context *context = libEGL->clientGetCurrentContext();

-

-    return context ? context->getClientVersion() : 0;

-}

-}

-

-namespace es2

-{

-void ActiveTexture(GLenum texture);

-void AttachShader(GLuint program, GLuint shader);

-void BeginQueryEXT(GLenum target, GLuint name);

-void BindAttribLocation(GLuint program, GLuint index, const GLchar* name);

-void BindBuffer(GLenum target, GLuint buffer);

-void BindFramebuffer(GLenum target, GLuint framebuffer);

-void BindRenderbuffer(GLenum target, GLuint renderbuffer);

-void BindTexture(GLenum target, GLuint texture);

-void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

-void BlendEquation(GLenum mode);

-void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);

-void BlendFunc(GLenum sfactor, GLenum dfactor);

-void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);

-void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);

-void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);

-GLenum CheckFramebufferStatus(GLenum target);

-void Clear(GLbitfield mask);

-void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

-void ClearDepthf(GLclampf depth);

-void ClearStencil(GLint s);

-void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);

-void CompileShader(GLuint shader);

-void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                          GLint border, GLsizei imageSize, const GLvoid* data);

-void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                             GLenum format, GLsizei imageSize, const GLvoid* data);

-void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);

-void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);

-GLuint CreateProgram(void);

-GLuint CreateShader(GLenum type);

-void CullFace(GLenum mode);

-void DeleteBuffers(GLsizei n, const GLuint* buffers);

-void DeleteFencesNV(GLsizei n, const GLuint* fences);

-void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers);

-void DeleteProgram(GLuint program);

-void DeleteQueriesEXT(GLsizei n, const GLuint *ids);

-void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);

-void DeleteShader(GLuint shader);

-void DeleteTextures(GLsizei n, const GLuint* textures);

-void DepthFunc(GLenum func);

-void DepthMask(GLboolean flag);

-void DepthRangef(GLclampf zNear, GLclampf zFar);

-void DetachShader(GLuint program, GLuint shader);

-void Disable(GLenum cap);

-void DisableVertexAttribArray(GLuint index);

-void DrawArrays(GLenum mode, GLint first, GLsizei count);

-void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);

-void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);

-void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);

-void VertexAttribDivisorEXT(GLuint index, GLuint divisor);

-void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);

-void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);

-void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);

-void Enable(GLenum cap);

-void EnableVertexAttribArray(GLuint index);

-void EndQueryEXT(GLenum target);

-void FinishFenceNV(GLuint fence);

-void Finish(void);

-void Flush(void);

-void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);

-void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);

-void FrontFace(GLenum mode);

-void GenBuffers(GLsizei n, GLuint* buffers);

-void GenerateMipmap(GLenum target);

-void GenFencesNV(GLsizei n, GLuint* fences);

-void GenFramebuffers(GLsizei n, GLuint* framebuffers);

-void GenQueriesEXT(GLsizei n, GLuint* ids);

-void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);

-void GenTextures(GLsizei n, GLuint* textures);

-void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);

-void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);

-void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);

-int GetAttribLocation(GLuint program, const GLchar* name);

-void GetBooleanv(GLenum pname, GLboolean* params);

-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);

-GLenum GetError(void);

-void GetFenceivNV(GLuint fence, GLenum pname, GLint *params);

-void GetFloatv(GLenum pname, GLfloat* params);

-void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);

-GLenum GetGraphicsResetStatusEXT(void);

-void GetIntegerv(GLenum pname, GLint* params);

-void GetProgramiv(GLuint program, GLenum pname, GLint* params);

-void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);

-void GetQueryivEXT(GLenum target, GLenum pname, GLint *params);

-void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params);

-void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);

-void GetShaderiv(GLuint shader, GLenum pname, GLint* params);

-void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);

-void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);

-void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);

-const GLubyte* GetString(GLenum name);

-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);

-void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);

-void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params);

-void GetUniformfv(GLuint program, GLint location, GLfloat* params);

-void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params);

-void GetUniformiv(GLuint program, GLint location, GLint* params);

-int GetUniformLocation(GLuint program, const GLchar* name);

-void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);

-void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);

-void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);

-void Hint(GLenum target, GLenum mode);

-GLboolean IsBuffer(GLuint buffer);

-GLboolean IsEnabled(GLenum cap);

-GLboolean IsFenceNV(GLuint fence);

-GLboolean IsFramebuffer(GLuint framebuffer);

-GLboolean IsProgram(GLuint program);

-GLboolean IsQueryEXT(GLuint name);

-GLboolean IsRenderbuffer(GLuint renderbuffer);

-GLboolean IsShader(GLuint shader);

-GLboolean IsTexture(GLuint texture);

-void LineWidth(GLfloat width);

-void LinkProgram(GLuint program);

-void PixelStorei(GLenum pname, GLint param);

-void PolygonOffset(GLfloat factor, GLfloat units);

-void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,

-                    GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);

-void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);

-void ReleaseShaderCompiler(void);

-void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);

-void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);

-void SampleCoverage(GLclampf value, GLboolean invert);

-void SetFenceNV(GLuint fence, GLenum condition);

-void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);

-void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);

-void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length);

-void StencilFunc(GLenum func, GLint ref, GLuint mask);

-void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);

-void StencilMask(GLuint mask);

-void StencilMaskSeparate(GLenum face, GLuint mask);

-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);

-void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);

-GLboolean TestFenceNV(GLuint fence);

-void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                 GLint border, GLenum format, GLenum type, const GLvoid* pixels);

-void TexParameterf(GLenum target, GLenum pname, GLfloat param);

-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);

-void TexParameteri(GLenum target, GLenum pname, GLint param);

-void TexParameteriv(GLenum target, GLenum pname, const GLint* params);

-void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                   GLenum format, GLenum type, const GLvoid* pixels);

-void Uniform1f(GLint location, GLfloat x);

-void Uniform1fv(GLint location, GLsizei count, const GLfloat* v);

-void Uniform1i(GLint location, GLint x);

-void Uniform1iv(GLint location, GLsizei count, const GLint* v);

-void Uniform2f(GLint location, GLfloat x, GLfloat y);

-void Uniform2fv(GLint location, GLsizei count, const GLfloat* v);

-void Uniform2i(GLint location, GLint x, GLint y);

-void Uniform2iv(GLint location, GLsizei count, const GLint* v);

-void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);

-void Uniform3fv(GLint location, GLsizei count, const GLfloat* v);

-void Uniform3i(GLint location, GLint x, GLint y, GLint z);

-void Uniform3iv(GLint location, GLsizei count, const GLint* v);

-void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);

-void Uniform4fv(GLint location, GLsizei count, const GLfloat* v);

-void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);

-void Uniform4iv(GLint location, GLsizei count, const GLint* v);

-void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);

-void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);

-void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);

-void UseProgram(GLuint program);

-void ValidateProgram(GLuint program);

-void VertexAttrib1f(GLuint index, GLfloat x);

-void VertexAttrib1fv(GLuint index, const GLfloat* values);

-void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y);

-void VertexAttrib2fv(GLuint index, const GLfloat* values);

-void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);

-void VertexAttrib3fv(GLuint index, const GLfloat* values);

-void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);

-void VertexAttrib4fv(GLuint index, const GLfloat* values);

-GL_APICALL void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);

-GL_APICALL void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);

-GL_APICALL void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);

-GL_APICALL void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                                     GLbitfield mask, GLenum filter);

-GL_APICALL void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,

-                              GLint border, GLenum format, GLenum type, const GLvoid* pixels);

-GL_APICALL void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);

-GL_APICALL void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);

-GL_APICALL void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);

-GL_APICALL void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);

-GL_APICALL void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);

-GL_APICALL void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);

-GL_APICALL void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);

-GL_APICALL GLboolean IsRenderbufferOES(GLuint renderbuffer);

-GL_APICALL void BindRenderbufferOES(GLenum target, GLuint renderbuffer);

-GL_APICALL void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);

-GL_APICALL void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);

-GL_APICALL void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);

-GL_APICALL void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);

-GL_APICALL GLboolean IsFramebufferOES(GLuint framebuffer);

-GL_APICALL void BindFramebufferOES(GLenum target, GLuint framebuffer);

-GL_APICALL void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);

-GL_APICALL void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);

-GL_APICALL GLenum CheckFramebufferStatusOES(GLenum target);

-GL_APICALL void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);

-GL_APICALL void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);

-GL_APICALL void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);

-GL_APICALL void GenerateMipmapOES(GLenum target);

-GL_APICALL void DrawBuffersEXT(GLsizei n, const GLenum *bufs);

-}

-

-extern "C"

-{

-GL_APICALL void GL_APIENTRY glActiveTexture(GLenum texture)

-{

-	return es2::ActiveTexture(texture);

-}

-

-GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)

-{

-	return es2::AttachShader(program, shader);

-}

-

-GL_APICALL void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint name)

-{

-	return es2::BeginQueryEXT(target, name);

-}

-

-GL_APICALL void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)

-{

-	return es2::BindAttribLocation(program, index, name);

-}

-

-GL_APICALL void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)

-{

-	return es2::BindBuffer(target, buffer);

-}

-

-GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)

-{

-	return es2::BindFramebuffer(target, framebuffer);

-}

-

-GL_APICALL void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)

-{

-	return es2::BindFramebuffer(target, framebuffer);

-}

-

-GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)

-{

-	return es2::BindRenderbuffer(target, renderbuffer);

-}

-

-GL_APICALL void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)

-{

-	return es2::BindRenderbuffer(target, renderbuffer);

-}

-

-GL_APICALL void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)

-{

-	return es2::BindTexture(target, texture);

-}

-

-GL_APICALL void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	return es2::BlendColor(red, green, blue, alpha);

-}

-

-GL_APICALL void GL_APIENTRY glBlendEquation(GLenum mode)

-{

-	return es2::BlendEquation(mode);

-}

-

-GL_APICALL void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)

-{

-	return es2::BlendEquationSeparate(modeRGB, modeAlpha);

-}

-

-GL_APICALL void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)

-{

-	return es2::BlendFunc(sfactor, dfactor);

-}

-

-GL_APICALL void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)

-{

-	return es2::BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);

-}

-

-GL_APICALL void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)

-{

-	return es2::BufferData(target, size, data, usage);

-}

-

-GL_APICALL void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)

-{

-	return es2::BufferSubData(target, offset, size, data);

-}

-

-GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)

-{

-	return es2::CheckFramebufferStatus(target);

-}

-

-GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)

-{

-	return es2::CheckFramebufferStatus(target);

-}

-

-GL_APICALL void GL_APIENTRY glClear(GLbitfield mask)

-{

-	return es2::Clear(mask);

-}

-

-GL_APICALL void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	return es2::ClearColor(red, green, blue, alpha);

-}

-

-GL_APICALL void GL_APIENTRY glClearDepthf(GLclampf depth)

-{

-	return es2::ClearDepthf(depth);

-}

-

-GL_APICALL void GL_APIENTRY glClearStencil(GLint s)

-{

-	return es2::ClearStencil(s);

-}

-

-GL_APICALL void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)

-{

-	return es2::ColorMask(red, green, blue, alpha);

-}

-

-GL_APICALL void GL_APIENTRY glCompileShader(GLuint shader)

-{

-	return es2::CompileShader(shader);

-}

-

-GL_APICALL void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                                                   GLint border, GLsizei imageSize, const GLvoid* data)

-{

-	return es2::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);

-}

-

-GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                                                      GLenum format, GLsizei imageSize, const GLvoid* data)

-{

-	return es2::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);

-}

-

-GL_APICALL void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)

-{

-	return es2::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);

-}

-

-GL_APICALL void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es2::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);

-}

-

-GL_APICALL GLuint GL_APIENTRY glCreateProgram(void)

-{

-	return es2::CreateProgram();

-}

-

-GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type)

-{

-	return es2::CreateShader(type);

-}

-

-GL_APICALL void GL_APIENTRY glCullFace(GLenum mode)

-{

-	return es2::CullFace(mode);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)

-{

-	return es2::DeleteBuffers(n, buffers);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)

-{

-	return es2::DeleteFencesNV(n, fences);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)

-{

-	return es2::DeleteFramebuffers(n, framebuffers);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)

-{

-	return es2::DeleteFramebuffers(n, framebuffers);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program)

-{

-	return es2::DeleteProgram(program);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)

-{

-	return es2::DeleteQueriesEXT(n, ids);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)

-{

-	return es2::DeleteRenderbuffers(n, renderbuffers);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)

-{

-	return es2::DeleteRenderbuffers(n, renderbuffers);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader)

-{

-	return es2::DeleteShader(shader);

-}

-

-GL_APICALL void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)

-{

-	return es2::DeleteTextures(n, textures);

-}

-

-GL_APICALL void GL_APIENTRY glDepthFunc(GLenum func)

-{

-	return es2::DepthFunc(func);

-}

-

-GL_APICALL void GL_APIENTRY glDepthMask(GLboolean flag)

-{

-	return es2::DepthMask(flag);

-}

-

-GL_APICALL void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)

-{

-	return es2::DepthRangef(zNear, zFar);

-}

-

-GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)

-{

-	return es2::DetachShader(program, shader);

-}

-

-GL_APICALL void GL_APIENTRY glDisable(GLenum cap)

-{

-	return es2::Disable(cap);

-}

-

-GL_APICALL void GL_APIENTRY glDisableVertexAttribArray(GLuint index)

-{

-	return es2::DisableVertexAttribArray(index);

-}

-

-GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)

-{

-	return es2::DrawArrays(mode, first, count);

-}

-

-GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)

-{

-	return es2::DrawElements(mode, count, type, indices);

-}

-

-GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)

-{

-	return es2::DrawArraysInstancedEXT(mode, first, count, instanceCount);

-}

-

-GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)

-{

-	return es2::DrawElementsInstancedEXT(mode, count, type, indices, instanceCount);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)

-{

-	return es2::VertexAttribDivisorEXT(index, divisor);

-}

-

-GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)

-{

-	return es2::DrawArraysInstancedANGLE(mode, first, count, instanceCount);

-}

-

-GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)

-{

-	return es2::DrawElementsInstancedANGLE(mode, count, type, indices, instanceCount);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)

-{

-	return es2::VertexAttribDivisorANGLE(index, divisor);

-}

-

-GL_APICALL void GL_APIENTRY glEnable(GLenum cap)

-{

-	return es2::Enable(cap);

-}

-

-GL_APICALL void GL_APIENTRY glEnableVertexAttribArray(GLuint index)

-{

-	return es2::EnableVertexAttribArray(index);

-}

-

-GL_APICALL void GL_APIENTRY glEndQueryEXT(GLenum target)

-{

-	return es2::EndQueryEXT(target);

-}

-

-GL_APICALL void GL_APIENTRY glFinishFenceNV(GLuint fence)

-{

-	return es2::FinishFenceNV(fence);

-}

-

-GL_APICALL void GL_APIENTRY glFinish(void)

-{

-	return es2::Finish();

-}

-

-GL_APICALL void GL_APIENTRY glFlush(void)

-{

-	return es2::Flush();

-}

-

-GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);

-}

-

-GL_APICALL void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);

-}

-

-GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);

-}

-

-GL_APICALL void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);

-}

-

-GL_APICALL void GL_APIENTRY glFrontFace(GLenum mode)

-{

-	return es2::FrontFace(mode);

-}

-

-GL_APICALL void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)

-{

-	return es2::GenBuffers(n, buffers);

-}

-

-GL_APICALL void GL_APIENTRY glGenerateMipmap(GLenum target)

-{

-	return es2::GenerateMipmap(target);

-}

-

-GL_APICALL void GL_APIENTRY glGenerateMipmapOES(GLenum target)

-{

-	return es2::GenerateMipmap(target);

-}

-

-GL_APICALL void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)

-{

-	return es2::GenFencesNV(n, fences);

-}

-

-GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)

-{

-	return es2::GenFramebuffers(n, framebuffers);

-}

-

-GL_APICALL void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)

-{

-	return es2::GenFramebuffers(n, framebuffers);

-}

-

-GL_APICALL void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)

-{

-	return es2::GenQueriesEXT(n, ids);

-}

-

-GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)

-{

-	return es2::GenRenderbuffers(n, renderbuffers);

-}

-

-GL_APICALL void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)

-{

-	return es2::GenRenderbuffers(n, renderbuffers);

-}

-

-GL_APICALL void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)

-{

-	return es2::GenTextures(n, textures);

-}

-

-GL_APICALL void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)

-{

-	return es2::GetActiveAttrib(program, index, bufsize, length, size, type, name);

-}

-

-GL_APICALL void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)

-{

-	return es2::GetActiveUniform(program, index, bufsize, length, size, type, name);

-}

-

-GL_APICALL void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)

-{

-	return es2::GetAttachedShaders(program, maxcount, count, shaders);

-}

-

-GL_APICALL int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)

-{

-	return es2::GetAttribLocation(program, name);

-}

-

-GL_APICALL void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)

-{

-	return es2::GetBooleanv(pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

-	return es2::GetBufferParameteriv(target, pname, params);

-}

-

-GL_APICALL GLenum GL_APIENTRY glGetError(void)

-{

-	return es2::GetError();

-}

-

-GL_APICALL void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)

-{

-	return es2::GetFenceivNV(fence, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)

-{

-	return es2::GetFloatv(pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);

-}

-

-GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)

-{

-	return es2::GetGraphicsResetStatusEXT();

-}

-

-GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)

-{

-	return es2::GetIntegerv(pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)

-{

-	return es2::GetProgramiv(program, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)

-{

-	return es2::GetProgramInfoLog(program, bufsize, length, infolog);

-}

-

-GL_APICALL void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)

-{

-	return es2::GetQueryivEXT(target, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)

-{

-	return es2::GetQueryObjectuivEXT(name, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

-	return es2::GetRenderbufferParameteriv(target, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)

-{

-	return es2::GetRenderbufferParameteriv(target, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)

-{

-	return es2::GetShaderiv(shader, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)

-{

-	return es2::GetShaderInfoLog(shader, bufsize, length, infolog);

-}

-

-GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)

-{

-	return es2::GetShaderPrecisionFormat(shadertype, precisiontype, range, precision);

-}

-

-GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)

-{

-	return es2::GetShaderSource(shader, bufsize, length, source);

-}

-

-GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name)

-{

-	return es2::GetString(name);

-}

-

-GL_APICALL void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)

-{

-	return es2::GetTexParameterfv(target, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)

-{

-	return es2::GetTexParameteriv(target, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)

-{

-	return es2::GetnUniformfvEXT(program, location, bufSize, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)

-{

-	return es2::GetUniformfv(program, location, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)

-{

-	return es2::GetnUniformivEXT(program, location, bufSize, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)

-{

-	return es2::GetUniformiv(program, location, params);

-}

-

-GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)

-{

-	return es2::GetUniformLocation(program, name);

-}

-

-GL_APICALL void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)

-{

-	return es2::GetVertexAttribfv(index, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)

-{

-	return es2::GetVertexAttribiv(index, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)

-{

-	return es2::GetVertexAttribPointerv(index, pname, pointer);

-}

-

-GL_APICALL void GL_APIENTRY glHint(GLenum target, GLenum mode)

-{

-	return es2::Hint(target, mode);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)

-{

-	return es2::IsBuffer(buffer);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsEnabled(GLenum cap)

-{

-	return es2::IsEnabled(cap);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)

-{

-	return es2::IsFenceNV(fence);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)

-{

-	return es2::IsFramebuffer(framebuffer);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)

-{

-	return es2::IsFramebuffer(framebuffer);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsProgram(GLuint program)

-{

-	return es2::IsProgram(program);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)

-{

-	return es2::IsQueryEXT(name);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)

-{

-	return es2::IsRenderbuffer(renderbuffer);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)

-{

-	return es2::IsRenderbuffer(renderbuffer);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsShader(GLuint shader)

-{

-	return es2::IsShader(shader);

-}

-

-GL_APICALL GLboolean GL_APIENTRY glIsTexture(GLuint texture)

-{

-	return es2::IsTexture(texture);

-}

-

-GL_APICALL void GL_APIENTRY glLineWidth(GLfloat width)

-{

-	return es2::LineWidth(width);

-}

-

-GL_APICALL void GL_APIENTRY glLinkProgram(GLuint program)

-{

-	return es2::LinkProgram(program);

-}

-

-GL_APICALL void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)

-{

-	return es2::PixelStorei(pname, param);

-}

-

-GL_APICALL void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)

-{

-	return es2::PolygonOffset(factor, units);

-}

-

-GL_APICALL void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,

-                                             GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)

-{

-	return es2::ReadnPixelsEXT(x, y, width, height, format, type, bufSize, data);

-}

-

-GL_APICALL void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)

-{

-	return es2::ReadPixels(x, y, width, height, format, type, pixels);

-}

-

-GL_APICALL void GL_APIENTRY glReleaseShaderCompiler(void)

-{

-	return es2::ReleaseShaderCompiler();

-}

-

-GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	return es2::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);

-}

-

-GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	return es2::RenderbufferStorage(target, internalformat, width, height);

-}

-

-GL_APICALL void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	return es2::RenderbufferStorage(target, internalformat, width, height);

-}

-

-GL_APICALL void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)

-{

-	return es2::SampleCoverage(value, invert);

-}

-

-GL_APICALL void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)

-{

-	return es2::SetFenceNV(fence, condition);

-}

-

-GL_APICALL void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es2::Scissor(x, y, width, height);

-}

-

-GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)

-{

-	return es2::ShaderBinary(n, shaders, binaryformat, binary, length);

-}

-

-GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)

-{

-	return es2::ShaderSource(shader, count, string, length);

-}

-

-GL_APICALL void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)

-{

-	return es2::StencilFunc(func, ref, mask);

-}

-

-GL_APICALL void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)

-{

-	return es2::StencilFuncSeparate(face, func, ref, mask);

-}

-

-GL_APICALL void GL_APIENTRY glStencilMask(GLuint mask)

-{

-	return es2::StencilMask(mask);

-}

-

-GL_APICALL void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)

-{

-	return es2::StencilMaskSeparate(face, mask);

-}

-

-GL_APICALL void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)

-{

-	return es2::StencilOp(fail, zfail, zpass);

-}

-

-GL_APICALL void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)

-{

-	return es2::StencilOpSeparate(face, fail, zfail, zpass);

-}

-

-GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)

-{

-	return es2::TestFenceNV(fence);

-}

-

-GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                                         GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	return es2::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);

-}

-

-GL_APICALL void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)

-{

-	return es2::TexParameterf(target, pname, param);

-}

-

-GL_APICALL void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)

-{

-	return es2::TexParameterfv(target, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)

-{

-	return es2::TexParameteri(target, pname, param);

-}

-

-GL_APICALL void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)

-{

-	return es2::TexParameteriv(target, pname, params);

-}

-

-GL_APICALL void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                                            GLenum format, GLenum type, const GLvoid* pixels)

-{

-	return es2::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);

-}

-

-GL_APICALL void GL_APIENTRY glUniform1f(GLint location, GLfloat x)

-{

-	return es2::Uniform1f(location, x);

-}

-

-GL_APICALL void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	return es2::Uniform1fv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniform1i(GLint location, GLint x)

-{

-	return es2::Uniform1i(location, x);

-}

-

-GL_APICALL void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)

-{

-	return es2::Uniform1iv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)

-{

-	return es2::Uniform2f(location, x, y);

-}

-

-GL_APICALL void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	return es2::Uniform2fv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)

-{

-	return es2::Uniform2i(location, x, y);

-}

-

-GL_APICALL void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)

-{

-	return es2::Uniform2iv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)

-{

-	return es2::Uniform3f(location, x, y, z);

-}

-

-GL_APICALL void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	return es2::Uniform3fv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)

-{

-	return es2::Uniform3i(location, x, y, z);

-}

-

-GL_APICALL void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)

-{

-	return es2::Uniform3iv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	return es2::Uniform4f(location, x, y, z, w);

-}

-

-GL_APICALL void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)

-{

-	return es2::Uniform4fv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)

-{

-	return es2::Uniform4i(location, x, y, z, w);

-}

-

-GL_APICALL void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)

-{

-	return es2::Uniform4iv(location, count, v);

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	return es2::UniformMatrix2fv(location, count, transpose, value);

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	return es2::UniformMatrix3fv(location, count, transpose, value);

-}

-

-GL_APICALL void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

-{

-	return es2::UniformMatrix4fv(location, count, transpose, value);

-}

-

-GL_APICALL void GL_APIENTRY glUseProgram(GLuint program)

-{

-	return es2::UseProgram(program);

-}

-

-GL_APICALL void GL_APIENTRY glValidateProgram(GLuint program)

-{

-	return es2::ValidateProgram(program);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)

-{

-	return es2::VertexAttrib1f(index, x);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)

-{

-	return es2::VertexAttrib1fv(index, values);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)

-{

-	return es2::VertexAttrib2f(index, x, y);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)

-{

-	return es2::VertexAttrib2fv(index, values);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)

-{

-	return es2::VertexAttrib3f(index, x, y, z);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)

-{

-	return es2::VertexAttrib3fv(index, values);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-	return es2::VertexAttrib4f(index, x, y, z, w);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)

-{

-	return es2::VertexAttrib4fv(index, values);

-}

-

-GL_APICALL void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)

-{

-	return es2::VertexAttribPointer(index, size, type, normalized, stride, ptr);

-}

-

-GL_APICALL void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es2::Viewport(x, y, width, height);

-}

-

-GL_APICALL void GL_APIENTRY glBlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)

-{

-	return es2::BlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);

-}

-

-GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,

-                                                   GLbitfield mask, GLenum filter)

-{

-	return es2::BlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);

-}

-

-GL_APICALL void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,

-                                            GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	return es2::TexImage3DOES(target, level, internalformat, width, height, depth, border, format, type, pixels);

-}

-

-GL_APICALL void GL_APIENTRY glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)

-{

-	return es2::TexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);

-}

-

-GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es2::CopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);

-}

-

-GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)

-{

-	return es2::CompressedTexImage3DOES(target, level,internalformat, width, height, depth, border, imageSize, data);

-}

-

-GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)

-{

-	return es2::CompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);

-}

-

-GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)

-{

-	return es2::FramebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);

-}

-

-GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)

-{

-	return es2::EGLImageTargetTexture2DOES(target, image);

-}

-

-GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)

-{

-	return es2::EGLImageTargetRenderbufferStorageOES(target, image);

-}

-

-GL_APICALL void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)

-{

-	return es2::DrawBuffersEXT(n, bufs);

-}

-}

-

-egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion);

-extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname);

-egl::Image *createBackBuffer(int width, int height, const egl::Config *config);

-egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType window, int width, int height);

-

-LibGLESv2exports::LibGLESv2exports()

-{

-	this->glActiveTexture = es2::ActiveTexture;

-	this->glAttachShader = es2::AttachShader;

-	this->glBeginQueryEXT = es2::BeginQueryEXT;

-	this->glBindAttribLocation = es2::BindAttribLocation;

-	this->glBindBuffer = es2::BindBuffer;

-	this->glBindFramebuffer = es2::BindFramebuffer;

-	this->glBindRenderbuffer = es2::BindRenderbuffer;

-	this->glBindTexture = es2::BindTexture;

-	this->glBlendColor = es2::BlendColor;

-	this->glBlendEquation = es2::BlendEquation;

-	this->glBlendEquationSeparate = es2::BlendEquationSeparate;

-	this->glBlendFunc = es2::BlendFunc;

-	this->glBlendFuncSeparate = es2::BlendFuncSeparate;

-	this->glBufferData = es2::BufferData;

-	this->glBufferSubData = es2::BufferSubData;

-	this->glCheckFramebufferStatus = es2::CheckFramebufferStatus;

-	this->glClear = es2::Clear;

-	this->glClearColor = es2::ClearColor;

-	this->glClearDepthf = es2::ClearDepthf;

-	this->glClearStencil = es2::ClearStencil;

-	this->glColorMask = es2::ColorMask;

-	this->glCompileShader = es2::CompileShader;

-	this->glCompressedTexImage2D = es2::CompressedTexImage2D;

-	this->glCompressedTexSubImage2D = es2::CompressedTexSubImage2D;

-	this->glCopyTexImage2D = es2::CopyTexImage2D;

-	this->glCopyTexSubImage2D = es2::CopyTexSubImage2D;

-	this->glCreateProgram = es2::CreateProgram;

-	this->glCreateShader = es2::CreateShader;

-	this->glCullFace = es2::CullFace;

-	this->glDeleteBuffers = es2::DeleteBuffers;

-	this->glDeleteFencesNV = es2::DeleteFencesNV;

-	this->glDeleteFramebuffers = es2::DeleteFramebuffers;

-	this->glDeleteProgram = es2::DeleteProgram;

-	this->glDeleteQueriesEXT = es2::DeleteQueriesEXT;

-	this->glDeleteRenderbuffers = es2::DeleteRenderbuffers;

-	this->glDeleteShader = es2::DeleteShader;

-	this->glDeleteTextures = es2::DeleteTextures;

-	this->glDepthFunc = es2::DepthFunc;

-	this->glDepthMask = es2::DepthMask;

-	this->glDepthRangef = es2::DepthRangef;

-	this->glDetachShader = es2::DetachShader;

-	this->glDisable = es2::Disable;

-	this->glDisableVertexAttribArray = es2::DisableVertexAttribArray;

-	this->glDrawArrays = es2::DrawArrays;

-	this->glDrawElements = es2::DrawElements;

-	this->glDrawArraysInstancedEXT = es2::DrawArraysInstancedEXT;

-	this->glDrawElementsInstancedEXT = es2::DrawElementsInstancedEXT;

-	this->glVertexAttribDivisorEXT = es2::VertexAttribDivisorEXT;

-	this->glDrawArraysInstancedANGLE = es2::DrawArraysInstancedANGLE;

-	this->glDrawElementsInstancedANGLE = es2::DrawElementsInstancedANGLE;

-	this->glVertexAttribDivisorANGLE = es2::VertexAttribDivisorANGLE;

-	this->glEnable = es2::Enable;

-	this->glEnableVertexAttribArray = es2::EnableVertexAttribArray;

-	this->glEndQueryEXT = es2::EndQueryEXT;

-	this->glFinishFenceNV = es2::FinishFenceNV;

-	this->glFinish = es2::Finish;

-	this->glFlush = es2::Flush;

-	this->glFramebufferRenderbuffer = es2::FramebufferRenderbuffer;

-	this->glFramebufferTexture2D = es2::FramebufferTexture2D;

-	this->glFrontFace = es2::FrontFace;

-	this->glGenBuffers = es2::GenBuffers;

-	this->glGenerateMipmap = es2::GenerateMipmap;

-	this->glGenFencesNV = es2::GenFencesNV;

-	this->glGenFramebuffers = es2::GenFramebuffers;

-	this->glGenQueriesEXT = es2::GenQueriesEXT;

-	this->glGenRenderbuffers = es2::GenRenderbuffers;

-	this->glGenTextures = es2::GenTextures;

-	this->glGetActiveAttrib = es2::GetActiveAttrib;

-	this->glGetActiveUniform = es2::GetActiveUniform;

-	this->glGetAttachedShaders = es2::GetAttachedShaders;

-	this->glGetAttribLocation = es2::GetAttribLocation;

-	this->glGetBooleanv = es2::GetBooleanv;

-	this->glGetBufferParameteriv = es2::GetBufferParameteriv;

-	this->glGetError = es2::GetError;

-	this->glGetFenceivNV = es2::GetFenceivNV;

-	this->glGetFloatv = es2::GetFloatv;

-	this->glGetFramebufferAttachmentParameteriv = es2::GetFramebufferAttachmentParameteriv;

-	this->glGetGraphicsResetStatusEXT = es2::GetGraphicsResetStatusEXT;

-	this->glGetIntegerv = es2::GetIntegerv;

-	this->glGetProgramiv = es2::GetProgramiv;

-	this->glGetProgramInfoLog = es2::GetProgramInfoLog;

-	this->glGetQueryivEXT = es2::GetQueryivEXT;

-	this->glGetQueryObjectuivEXT = es2::GetQueryObjectuivEXT;

-	this->glGetRenderbufferParameteriv = es2::GetRenderbufferParameteriv;

-	this->glGetShaderiv = es2::GetShaderiv;

-	this->glGetShaderInfoLog = es2::GetShaderInfoLog;

-	this->glGetShaderPrecisionFormat = es2::GetShaderPrecisionFormat;

-	this->glGetShaderSource = es2::GetShaderSource;

-	this->glGetString = es2::GetString;

-	this->glGetTexParameterfv = es2::GetTexParameterfv;

-	this->glGetTexParameteriv = es2::GetTexParameteriv;

-	this->glGetnUniformfvEXT = es2::GetnUniformfvEXT;

-	this->glGetUniformfv = es2::GetUniformfv;

-	this->glGetnUniformivEXT = es2::GetnUniformivEXT;

-	this->glGetUniformiv = es2::GetUniformiv;

-	this->glGetUniformLocation = es2::GetUniformLocation;

-	this->glGetVertexAttribfv = es2::GetVertexAttribfv;

-	this->glGetVertexAttribiv = es2::GetVertexAttribiv;

-	this->glGetVertexAttribPointerv = es2::GetVertexAttribPointerv;

-	this->glHint = es2::Hint;

-	this->glIsBuffer = es2::IsBuffer;

-	this->glIsEnabled = es2::IsEnabled;

-	this->glIsFenceNV = es2::IsFenceNV;

-	this->glIsFramebuffer = es2::IsFramebuffer;

-	this->glIsProgram = es2::IsProgram;

-	this->glIsQueryEXT = es2::IsQueryEXT;

-	this->glIsRenderbuffer = es2::IsRenderbuffer;

-	this->glIsShader = es2::IsShader;

-	this->glIsTexture = es2::IsTexture;

-	this->glLineWidth = es2::LineWidth;

-	this->glLinkProgram = es2::LinkProgram;

-	this->glPixelStorei = es2::PixelStorei;

-	this->glPolygonOffset = es2::PolygonOffset;

-	this->glReadnPixelsEXT = es2::ReadnPixelsEXT;

-	this->glReadPixels = es2::ReadPixels;

-	this->glReleaseShaderCompiler = es2::ReleaseShaderCompiler;

-	this->glRenderbufferStorageMultisampleANGLE = es2::RenderbufferStorageMultisampleANGLE;

-	this->glRenderbufferStorage = es2::RenderbufferStorage;

-	this->glSampleCoverage = es2::SampleCoverage;

-	this->glSetFenceNV = es2::SetFenceNV;

-	this->glScissor = es2::Scissor;

-	this->glShaderBinary = es2::ShaderBinary;

-	this->glShaderSource = es2::ShaderSource;

-	this->glStencilFunc = es2::StencilFunc;

-	this->glStencilFuncSeparate = es2::StencilFuncSeparate;

-	this->glStencilMask = es2::StencilMask;

-	this->glStencilMaskSeparate = es2::StencilMaskSeparate;

-	this->glStencilOp = es2::StencilOp;

-	this->glStencilOpSeparate = es2::StencilOpSeparate;

-	this->glTestFenceNV = es2::TestFenceNV;

-	this->glTexImage2D = es2::TexImage2D;

-	this->glTexParameterf = es2::TexParameterf;

-	this->glTexParameterfv = es2::TexParameterfv;

-	this->glTexParameteri = es2::TexParameteri;

-	this->glTexParameteriv = es2::TexParameteriv;

-	this->glTexSubImage2D = es2::TexSubImage2D;

-	this->glUniform1f = es2::Uniform1f;

-	this->glUniform1fv = es2::Uniform1fv;

-	this->glUniform1i = es2::Uniform1i;

-	this->glUniform1iv = es2::Uniform1iv;

-	this->glUniform2f = es2::Uniform2f;

-	this->glUniform2fv = es2::Uniform2fv;

-	this->glUniform2i = es2::Uniform2i;

-	this->glUniform2iv = es2::Uniform2iv;

-	this->glUniform3f = es2::Uniform3f;

-	this->glUniform3fv = es2::Uniform3fv;

-	this->glUniform3i = es2::Uniform3i;

-	this->glUniform3iv = es2::Uniform3iv;

-	this->glUniform4f = es2::Uniform4f;

-	this->glUniform4fv = es2::Uniform4fv;

-	this->glUniform4i = es2::Uniform4i;

-	this->glUniform4iv = es2::Uniform4iv;

-	this->glUniformMatrix2fv = es2::UniformMatrix2fv;

-	this->glUniformMatrix3fv = es2::UniformMatrix3fv;

-	this->glUniformMatrix4fv = es2::UniformMatrix4fv;

-	this->glUseProgram = es2::UseProgram;

-	this->glValidateProgram = es2::ValidateProgram;

-	this->glVertexAttrib1f = es2::VertexAttrib1f;

-	this->glVertexAttrib1fv = es2::VertexAttrib1fv;

-	this->glVertexAttrib2f = es2::VertexAttrib2f;

-	this->glVertexAttrib2fv = es2::VertexAttrib2fv;

-	this->glVertexAttrib3f = es2::VertexAttrib3f;

-	this->glVertexAttrib3fv = es2::VertexAttrib3fv;

-	this->glVertexAttrib4f = es2::VertexAttrib4f;

-	this->glVertexAttrib4fv = es2::VertexAttrib4fv;

-	this->glVertexAttribPointer = es2::VertexAttribPointer;

-	this->glViewport = es2::Viewport;

-	this->glBlitFramebufferNV = es2::BlitFramebufferNV;

-	this->glBlitFramebufferANGLE = es2::BlitFramebufferANGLE;

-	this->glTexImage3DOES = es2::TexImage3DOES;

-	this->glTexSubImage3DOES = es2::TexSubImage3DOES;

-	this->glCopyTexSubImage3DOES = es2::CopyTexSubImage3DOES;

-	this->glCompressedTexImage3DOES = es2::CompressedTexImage3DOES;

-	this->glCompressedTexSubImage3DOES = es2::CompressedTexSubImage3DOES;

-	this->glFramebufferTexture3DOES = es2::FramebufferTexture3DOES;

-	this->glEGLImageTargetTexture2DOES = es2::EGLImageTargetTexture2DOES;

-	this->glEGLImageTargetRenderbufferStorageOES = es2::EGLImageTargetRenderbufferStorageOES;

-	this->glIsRenderbufferOES = es2::IsRenderbufferOES;

-	this->glBindRenderbufferOES = es2::BindRenderbufferOES;

-	this->glDeleteRenderbuffersOES = es2::DeleteRenderbuffersOES;

-	this->glGenRenderbuffersOES = es2::GenRenderbuffersOES;

-	this->glRenderbufferStorageOES = es2::RenderbufferStorageOES;

-	this->glGetRenderbufferParameterivOES = es2::GetRenderbufferParameterivOES;

-	this->glIsFramebufferOES = es2::IsFramebufferOES;

-	this->glBindFramebufferOES = es2::BindFramebufferOES;

-	this->glDeleteFramebuffersOES = es2::DeleteFramebuffersOES;

-	this->glGenFramebuffersOES = es2::GenFramebuffersOES;

-	this->glCheckFramebufferStatusOES = es2::CheckFramebufferStatusOES;

-	this->glFramebufferRenderbufferOES = es2::FramebufferRenderbufferOES;

-	this->glFramebufferTexture2DOES = es2::FramebufferTexture2DOES;

-	this->glGetFramebufferAttachmentParameterivOES = es2::GetFramebufferAttachmentParameterivOES;

-	this->glGenerateMipmapOES = es2::GenerateMipmapOES;

-	this->glDrawBuffersEXT = es2::DrawBuffersEXT;

-

-	this->es2CreateContext = ::es2CreateContext;

-	this->es2GetProcAddress = ::es2GetProcAddress;

-	this->createBackBuffer = ::createBackBuffer;

-	this->createDepthStencil = ::createDepthStencil;

-	this->createFrameBuffer = ::createFrameBuffer;

-}

-

-extern "C" GL_APICALL LibGLESv2exports *libGLESv2_swiftshader()

-{

-	static LibGLESv2exports libGLESv2;

-	return &libGLESv2;

-}

-

-LibEGL libEGL;

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// main.cpp: DLL entry point and management of thread-local data.
+
+#include "main.h"
+
+#include "libGLESv2.hpp"
+#include "Framebuffer.h"
+#include "libEGL/main.h"
+#include "libEGL/Surface.h"
+#include "Common/Thread.hpp"
+#include "Common/SharedLibrary.hpp"
+#include "common/debug.h"
+
+#if !defined(_MSC_VER)
+#define CONSTRUCTOR __attribute__((constructor))
+#define DESTRUCTOR __attribute__((destructor))
+#else
+#define CONSTRUCTOR
+#define DESTRUCTOR
+#endif
+
+static void glAttachThread()
+{
+	TRACE("()");
+}
+
+static void glDetachThread()
+{
+	TRACE("()");
+}
+
+CONSTRUCTOR static void glAttachProcess()
+{
+	TRACE("()");
+
+	glAttachThread();
+}
+
+DESTRUCTOR static void glDetachProcess()
+{
+	TRACE("()");
+
+	glDetachThread();
+}
+
+#if defined(_WIN32)
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+	switch(reason)
+	{
+	case DLL_PROCESS_ATTACH:
+		glAttachProcess();
+		break;
+	case DLL_THREAD_ATTACH:
+		glAttachThread();
+		break;
+	case DLL_THREAD_DETACH:
+		glDetachThread();
+		break;
+	case DLL_PROCESS_DETACH:
+		glDetachProcess();
+		break;
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+#endif
+
+namespace es2
+{
+es2::Context *getContext()
+{
+	egl::Context *context = libEGL->clientGetCurrentContext();
+
+	if(context && (context->getClientVersion() == 2 ||
+	               context->getClientVersion() == 3))
+	{
+		return static_cast<es2::Context*>(context);
+	}
+
+	return 0;
+}
+
+Device *getDevice()
+{
+	Context *context = getContext();
+
+	return context ? context->getDevice() : 0;
+}
+
+// Records an error code
+void error(GLenum errorCode)
+{
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		switch(errorCode)
+		{
+		case GL_INVALID_ENUM:
+			context->recordInvalidEnum();
+			TRACE("\t! Error generated: invalid enum\n");
+			break;
+		case GL_INVALID_VALUE:
+			context->recordInvalidValue();
+			TRACE("\t! Error generated: invalid value\n");
+			break;
+		case GL_INVALID_OPERATION:
+			context->recordInvalidOperation();
+			TRACE("\t! Error generated: invalid operation\n");
+			break;
+		case GL_OUT_OF_MEMORY:
+			context->recordOutOfMemory();
+			TRACE("\t! Error generated: out of memory\n");
+			break;
+		case GL_INVALID_FRAMEBUFFER_OPERATION:
+			context->recordInvalidFramebufferOperation();
+			TRACE("\t! Error generated: invalid framebuffer operation\n");
+			break;
+		default: UNREACHABLE(errorCode);
+		}
+	}
+}
+}
+
+namespace egl
+{
+GLint getClientVersion()
+{
+	Context *context = libEGL->clientGetCurrentContext();
+
+	return context ? context->getClientVersion() : 0;
+}
+}
+
+namespace es2
+{
+void ActiveTexture(GLenum texture);
+void AttachShader(GLuint program, GLuint shader);
+void BeginQueryEXT(GLenum target, GLuint name);
+void BindAttribLocation(GLuint program, GLuint index, const GLchar* name);
+void BindBuffer(GLenum target, GLuint buffer);
+void BindFramebuffer(GLenum target, GLuint framebuffer);
+void BindRenderbuffer(GLenum target, GLuint renderbuffer);
+void BindTexture(GLenum target, GLuint texture);
+void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void BlendEquation(GLenum mode);
+void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+void BlendFunc(GLenum sfactor, GLenum dfactor);
+void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+GLenum CheckFramebufferStatus(GLenum target);
+void Clear(GLbitfield mask);
+void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void ClearDepthf(GLclampf depth);
+void ClearStencil(GLint s);
+void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+void CompileShader(GLuint shader);
+void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                          GLint border, GLsizei imageSize, const GLvoid* data);
+void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                             GLenum format, GLsizei imageSize, const GLvoid* data);
+void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLuint CreateProgram(void);
+GLuint CreateShader(GLenum type);
+void CullFace(GLenum mode);
+void DeleteBuffers(GLsizei n, const GLuint* buffers);
+void DeleteFencesNV(GLsizei n, const GLuint* fences);
+void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
+void DeleteProgram(GLuint program);
+void DeleteQueriesEXT(GLsizei n, const GLuint *ids);
+void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
+void DeleteShader(GLuint shader);
+void DeleteTextures(GLsizei n, const GLuint* textures);
+void DepthFunc(GLenum func);
+void DepthMask(GLboolean flag);
+void DepthRangef(GLclampf zNear, GLclampf zFar);
+void DetachShader(GLuint program, GLuint shader);
+void Disable(GLenum cap);
+void DisableVertexAttribArray(GLuint index);
+void DrawArrays(GLenum mode, GLint first, GLsizei count);
+void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);
+void VertexAttribDivisorEXT(GLuint index, GLuint divisor);
+void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);
+void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+void Enable(GLenum cap);
+void EnableVertexAttribArray(GLuint index);
+void EndQueryEXT(GLenum target);
+void FinishFenceNV(GLuint fence);
+void Finish(void);
+void Flush(void);
+void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void FrontFace(GLenum mode);
+void GenBuffers(GLsizei n, GLuint* buffers);
+void GenerateMipmap(GLenum target);
+void GenFencesNV(GLsizei n, GLuint* fences);
+void GenFramebuffers(GLsizei n, GLuint* framebuffers);
+void GenQueriesEXT(GLsizei n, GLuint* ids);
+void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
+void GenTextures(GLsizei n, GLuint* textures);
+void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+int GetAttribLocation(GLuint program, const GLchar* name);
+void GetBooleanv(GLenum pname, GLboolean* params);
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+GLenum GetError(void);
+void GetFenceivNV(GLuint fence, GLenum pname, GLint *params);
+void GetFloatv(GLenum pname, GLfloat* params);
+void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GLenum GetGraphicsResetStatusEXT(void);
+void GetIntegerv(GLenum pname, GLint* params);
+void GetProgramiv(GLuint program, GLenum pname, GLint* params);
+void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void GetQueryivEXT(GLenum target, GLenum pname, GLint *params);
+void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params);
+void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetShaderiv(GLuint shader, GLenum pname, GLint* params);
+void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+const GLubyte* GetString(GLenum name);
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
+void GetUniformfv(GLuint program, GLint location, GLfloat* params);
+void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params);
+void GetUniformiv(GLuint program, GLint location, GLint* params);
+int GetUniformLocation(GLuint program, const GLchar* name);
+void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
+void Hint(GLenum target, GLenum mode);
+GLboolean IsBuffer(GLuint buffer);
+GLboolean IsEnabled(GLenum cap);
+GLboolean IsFenceNV(GLuint fence);
+GLboolean IsFramebuffer(GLuint framebuffer);
+GLboolean IsProgram(GLuint program);
+GLboolean IsQueryEXT(GLuint name);
+GLboolean IsRenderbuffer(GLuint renderbuffer);
+GLboolean IsShader(GLuint shader);
+GLboolean IsTexture(GLuint texture);
+void LineWidth(GLfloat width);
+void LinkProgram(GLuint program);
+void PixelStorei(GLenum pname, GLint param);
+void PolygonOffset(GLfloat factor, GLfloat units);
+void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+                    GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+void ReleaseShaderCompiler(void);
+void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+void SampleCoverage(GLclampf value, GLboolean invert);
+void SetFenceNV(GLuint fence, GLenum condition);
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length);
+void StencilFunc(GLenum func, GLint ref, GLuint mask);
+void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+void StencilMask(GLuint mask);
+void StencilMaskSeparate(GLenum face, GLuint mask);
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+GLboolean TestFenceNV(GLuint fence);
+void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+void TexParameterf(GLenum target, GLenum pname, GLfloat param);
+void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+void TexParameteri(GLenum target, GLenum pname, GLint param);
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params);
+void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                   GLenum format, GLenum type, const GLvoid* pixels);
+void Uniform1f(GLint location, GLfloat x);
+void Uniform1fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform1i(GLint location, GLint x);
+void Uniform1iv(GLint location, GLsizei count, const GLint* v);
+void Uniform2f(GLint location, GLfloat x, GLfloat y);
+void Uniform2fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform2i(GLint location, GLint x, GLint y);
+void Uniform2iv(GLint location, GLsizei count, const GLint* v);
+void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+void Uniform3fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform3i(GLint location, GLint x, GLint y, GLint z);
+void Uniform3iv(GLint location, GLsizei count, const GLint* v);
+void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void Uniform4fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+void Uniform4iv(GLint location, GLsizei count, const GLint* v);
+void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void UseProgram(GLuint program);
+void ValidateProgram(GLuint program);
+void VertexAttrib1f(GLuint index, GLfloat x);
+void VertexAttrib1fv(GLuint index, const GLfloat* values);
+void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+void VertexAttrib2fv(GLuint index, const GLfloat* values);
+void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+void VertexAttrib3fv(GLuint index, const GLfloat* values);
+void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void VertexAttrib4fv(GLuint index, const GLfloat* values);
+GL_APICALL void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+GL_APICALL void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                                     GLbitfield mask, GLenum filter);
+GL_APICALL void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+                              GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GL_APICALL void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+GL_APICALL void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+GL_APICALL GLboolean IsRenderbufferOES(GLuint renderbuffer);
+GL_APICALL void BindRenderbufferOES(GLenum target, GLuint renderbuffer);
+GL_APICALL void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);
+GL_APICALL void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);
+GL_APICALL void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);
+GL_APICALL GLboolean IsFramebufferOES(GLuint framebuffer);
+GL_APICALL void BindFramebufferOES(GLenum target, GLuint framebuffer);
+GL_APICALL void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);
+GL_APICALL void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);
+GL_APICALL GLenum CheckFramebufferStatusOES(GLenum target);
+GL_APICALL void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GL_APICALL void GenerateMipmapOES(GLenum target);
+GL_APICALL void DrawBuffersEXT(GLsizei n, const GLenum *bufs);
+}
+
+extern "C"
+{
+GL_APICALL void GL_APIENTRY glActiveTexture(GLenum texture)
+{
+	return es2::ActiveTexture(texture);
+}
+
+GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
+{
+	return es2::AttachShader(program, shader);
+}
+
+GL_APICALL void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
+{
+	return es2::BeginQueryEXT(target, name);
+}
+
+GL_APICALL void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+	return es2::BindAttribLocation(program, index, name);
+}
+
+GL_APICALL void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+	return es2::BindBuffer(target, buffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+	return es2::BindFramebuffer(target, framebuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+	return es2::BindFramebuffer(target, framebuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+	return es2::BindRenderbuffer(target, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+	return es2::BindRenderbuffer(target, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+	return es2::BindTexture(target, texture);
+}
+
+GL_APICALL void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	return es2::BlendColor(red, green, blue, alpha);
+}
+
+GL_APICALL void GL_APIENTRY glBlendEquation(GLenum mode)
+{
+	return es2::BlendEquation(mode);
+}
+
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+	return es2::BlendEquationSeparate(modeRGB, modeAlpha);
+}
+
+GL_APICALL void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	return es2::BlendFunc(sfactor, dfactor);
+}
+
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	return es2::BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+GL_APICALL void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	return es2::BufferData(target, size, data, usage);
+}
+
+GL_APICALL void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	return es2::BufferSubData(target, offset, size, data);
+}
+
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
+{
+	return es2::CheckFramebufferStatus(target);
+}
+
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)
+{
+	return es2::CheckFramebufferStatus(target);
+}
+
+GL_APICALL void GL_APIENTRY glClear(GLbitfield mask)
+{
+	return es2::Clear(mask);
+}
+
+GL_APICALL void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	return es2::ClearColor(red, green, blue, alpha);
+}
+
+GL_APICALL void GL_APIENTRY glClearDepthf(GLclampf depth)
+{
+	return es2::ClearDepthf(depth);
+}
+
+GL_APICALL void GL_APIENTRY glClearStencil(GLint s)
+{
+	return es2::ClearStencil(s);
+}
+
+GL_APICALL void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	return es2::ColorMask(red, green, blue, alpha);
+}
+
+GL_APICALL void GL_APIENTRY glCompileShader(GLuint shader)
+{
+	return es2::CompileShader(shader);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                                                   GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	return es2::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                                      GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	return es2::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	return es2::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es2::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+GL_APICALL GLuint GL_APIENTRY glCreateProgram(void)
+{
+	return es2::CreateProgram();
+}
+
+GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type)
+{
+	return es2::CreateShader(type);
+}
+
+GL_APICALL void GL_APIENTRY glCullFace(GLenum mode)
+{
+	return es2::CullFace(mode);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	return es2::DeleteBuffers(n, buffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+	return es2::DeleteFencesNV(n, fences);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+	return es2::DeleteFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+	return es2::DeleteFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program)
+{
+	return es2::DeleteProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+	return es2::DeleteQueriesEXT(n, ids);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+	return es2::DeleteRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+	return es2::DeleteRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader)
+{
+	return es2::DeleteShader(shader);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+	return es2::DeleteTextures(n, textures);
+}
+
+GL_APICALL void GL_APIENTRY glDepthFunc(GLenum func)
+{
+	return es2::DepthFunc(func);
+}
+
+GL_APICALL void GL_APIENTRY glDepthMask(GLboolean flag)
+{
+	return es2::DepthMask(flag);
+}
+
+GL_APICALL void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	return es2::DepthRangef(zNear, zFar);
+}
+
+GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
+{
+	return es2::DetachShader(program, shader);
+}
+
+GL_APICALL void GL_APIENTRY glDisable(GLenum cap)
+{
+	return es2::Disable(cap);
+}
+
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
+{
+	return es2::DisableVertexAttribArray(index);
+}
+
+GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	return es2::DrawArrays(mode, first, count);
+}
+
+GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	return es2::DrawElements(mode, count, type, indices);
+}
+
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+	return es2::DrawArraysInstancedEXT(mode, first, count, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+	return es2::DrawElementsInstancedEXT(mode, count, type, indices, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)
+{
+	return es2::VertexAttribDivisorEXT(index, divisor);
+}
+
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+	return es2::DrawArraysInstancedANGLE(mode, first, count, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+	return es2::DrawElementsInstancedANGLE(mode, count, type, indices, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+	return es2::VertexAttribDivisorANGLE(index, divisor);
+}
+
+GL_APICALL void GL_APIENTRY glEnable(GLenum cap)
+{
+	return es2::Enable(cap);
+}
+
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
+{
+	return es2::EnableVertexAttribArray(index);
+}
+
+GL_APICALL void GL_APIENTRY glEndQueryEXT(GLenum target)
+{
+	return es2::EndQueryEXT(target);
+}
+
+GL_APICALL void GL_APIENTRY glFinishFenceNV(GLuint fence)
+{
+	return es2::FinishFenceNV(fence);
+}
+
+GL_APICALL void GL_APIENTRY glFinish(void)
+{
+	return es2::Finish();
+}
+
+GL_APICALL void GL_APIENTRY glFlush(void)
+{
+	return es2::Flush();
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+GL_APICALL void GL_APIENTRY glFrontFace(GLenum mode)
+{
+	return es2::FrontFace(mode);
+}
+
+GL_APICALL void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
+{
+	return es2::GenBuffers(n, buffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenerateMipmap(GLenum target)
+{
+	return es2::GenerateMipmap(target);
+}
+
+GL_APICALL void GL_APIENTRY glGenerateMipmapOES(GLenum target)
+{
+	return es2::GenerateMipmap(target);
+}
+
+GL_APICALL void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
+{
+	return es2::GenFencesNV(n, fences);
+}
+
+GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+	return es2::GenFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+	return es2::GenFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
+{
+	return es2::GenQueriesEXT(n, ids);
+}
+
+GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+	return es2::GenRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+	return es2::GenRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
+{
+	return es2::GenTextures(n, textures);
+}
+
+GL_APICALL void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+	return es2::GetActiveAttrib(program, index, bufsize, length, size, type, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+	return es2::GetActiveUniform(program, index, bufsize, length, size, type, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+	return es2::GetAttachedShaders(program, maxcount, count, shaders);
+}
+
+GL_APICALL int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
+{
+	return es2::GetAttribLocation(program, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
+{
+	return es2::GetBooleanv(pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	return es2::GetBufferParameteriv(target, pname, params);
+}
+
+GL_APICALL GLenum GL_APIENTRY glGetError(void)
+{
+	return es2::GetError();
+}
+
+GL_APICALL void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+	return es2::GetFenceivNV(fence, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
+{
+	return es2::GetFloatv(pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
+{
+	return es2::GetGraphicsResetStatusEXT();
+}
+
+GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
+{
+	return es2::GetIntegerv(pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+	return es2::GetProgramiv(program, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	return es2::GetProgramInfoLog(program, bufsize, length, infolog);
+}
+
+GL_APICALL void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+	return es2::GetQueryivEXT(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
+{
+	return es2::GetQueryObjectuivEXT(name, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	return es2::GetRenderbufferParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+	return es2::GetRenderbufferParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+	return es2::GetShaderiv(shader, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	return es2::GetShaderInfoLog(shader, bufsize, length, infolog);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+	return es2::GetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+	return es2::GetShaderSource(shader, bufsize, length, source);
+}
+
+GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name)
+{
+	return es2::GetString(name);
+}
+
+GL_APICALL void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	return es2::GetTexParameterfv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	return es2::GetTexParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+{
+	return es2::GetnUniformfvEXT(program, location, bufSize, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+	return es2::GetUniformfv(program, location, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
+{
+	return es2::GetnUniformivEXT(program, location, bufSize, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+	return es2::GetUniformiv(program, location, params);
+}
+
+GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
+{
+	return es2::GetUniformLocation(program, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+	return es2::GetVertexAttribfv(index, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+	return es2::GetVertexAttribiv(index, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+	return es2::GetVertexAttribPointerv(index, pname, pointer);
+}
+
+GL_APICALL void GL_APIENTRY glHint(GLenum target, GLenum mode)
+{
+	return es2::Hint(target, mode);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
+{
+	return es2::IsBuffer(buffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
+{
+	return es2::IsEnabled(cap);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
+{
+	return es2::IsFenceNV(fence);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
+{
+	return es2::IsFramebuffer(framebuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)
+{
+	return es2::IsFramebuffer(framebuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsProgram(GLuint program)
+{
+	return es2::IsProgram(program);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)
+{
+	return es2::IsQueryEXT(name);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
+{
+	return es2::IsRenderbuffer(renderbuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)
+{
+	return es2::IsRenderbuffer(renderbuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsShader(GLuint shader)
+{
+	return es2::IsShader(shader);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsTexture(GLuint texture)
+{
+	return es2::IsTexture(texture);
+}
+
+GL_APICALL void GL_APIENTRY glLineWidth(GLfloat width)
+{
+	return es2::LineWidth(width);
+}
+
+GL_APICALL void GL_APIENTRY glLinkProgram(GLuint program)
+{
+	return es2::LinkProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+	return es2::PixelStorei(pname, param);
+}
+
+GL_APICALL void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+	return es2::PolygonOffset(factor, units);
+}
+
+GL_APICALL void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+                                             GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
+{
+	return es2::ReadnPixelsEXT(x, y, width, height, format, type, bufSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	return es2::ReadPixels(x, y, width, height, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler(void)
+{
+	return es2::ReleaseShaderCompiler();
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	return es2::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	return es2::RenderbufferStorage(target, internalformat, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	return es2::RenderbufferStorage(target, internalformat, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+{
+	return es2::SampleCoverage(value, invert);
+}
+
+GL_APICALL void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
+{
+	return es2::SetFenceNV(fence, condition);
+}
+
+GL_APICALL void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es2::Scissor(x, y, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+	return es2::ShaderBinary(n, shaders, binaryformat, binary, length);
+}
+
+GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
+{
+	return es2::ShaderSource(shader, count, string, length);
+}
+
+GL_APICALL void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	return es2::StencilFunc(func, ref, mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+	return es2::StencilFuncSeparate(face, func, ref, mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilMask(GLuint mask)
+{
+	return es2::StencilMask(mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+	return es2::StencilMaskSeparate(face, mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	return es2::StencilOp(fail, zfail, zpass);
+}
+
+GL_APICALL void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+	return es2::StencilOpSeparate(face, fail, zfail, zpass);
+}
+
+GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
+{
+	return es2::TestFenceNV(fence);
+}
+
+GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                                         GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	return es2::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	return es2::TexParameterf(target, pname, param);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	return es2::TexParameterfv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	return es2::TexParameteri(target, pname, param);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	return es2::TexParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                            GLenum format, GLenum type, const GLvoid* pixels)
+{
+	return es2::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
+{
+	return es2::Uniform1f(location, x);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	return es2::Uniform1fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1i(GLint location, GLint x)
+{
+	return es2::Uniform1i(location, x);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+	return es2::Uniform1iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+	return es2::Uniform2f(location, x, y);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	return es2::Uniform2fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
+{
+	return es2::Uniform2i(location, x, y);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+	return es2::Uniform2iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+	return es2::Uniform3f(location, x, y, z);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	return es2::Uniform3fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+	return es2::Uniform3i(location, x, y, z);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+	return es2::Uniform3iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	return es2::Uniform4f(location, x, y, z, w);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	return es2::Uniform4fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+	return es2::Uniform4i(location, x, y, z, w);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+	return es2::Uniform4iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	return es2::UniformMatrix2fv(location, count, transpose, value);
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	return es2::UniformMatrix3fv(location, count, transpose, value);
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	return es2::UniformMatrix4fv(location, count, transpose, value);
+}
+
+GL_APICALL void GL_APIENTRY glUseProgram(GLuint program)
+{
+	return es2::UseProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glValidateProgram(GLuint program)
+{
+	return es2::ValidateProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
+{
+	return es2::VertexAttrib1f(index, x);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
+{
+	return es2::VertexAttrib1fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+	return es2::VertexAttrib2f(index, x, y);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
+{
+	return es2::VertexAttrib2fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+	return es2::VertexAttrib3f(index, x, y, z);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
+{
+	return es2::VertexAttrib3fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	return es2::VertexAttrib4f(index, x, y, z, w);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
+{
+	return es2::VertexAttrib4fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+	return es2::VertexAttribPointer(index, size, type, normalized, stride, ptr);
+}
+
+GL_APICALL void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es2::Viewport(x, y, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glBlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+{
+	return es2::BlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                                                   GLbitfield mask, GLenum filter)
+{
+	return es2::BlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+GL_APICALL void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+                                            GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	return es2::TexImage3DOES(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
+{
+	return es2::TexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es2::CopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
+{
+	return es2::CompressedTexImage3DOES(target, level,internalformat, width, height, depth, border, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
+{
+	return es2::CompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+	return es2::FramebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);
+}
+
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	return es2::EGLImageTargetTexture2DOES(target, image);
+}
+
+GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	return es2::EGLImageTargetRenderbufferStorageOES(target, image);
+}
+
+GL_APICALL void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+	return es2::DrawBuffersEXT(n, bufs);
+}
+}
+
+egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion);
+extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname);
+egl::Image *createBackBuffer(int width, int height, const egl::Config *config);
+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType window, int width, int height);
+
+LibGLESv2exports::LibGLESv2exports()
+{
+	this->glActiveTexture = es2::ActiveTexture;
+	this->glAttachShader = es2::AttachShader;
+	this->glBeginQueryEXT = es2::BeginQueryEXT;
+	this->glBindAttribLocation = es2::BindAttribLocation;
+	this->glBindBuffer = es2::BindBuffer;
+	this->glBindFramebuffer = es2::BindFramebuffer;
+	this->glBindRenderbuffer = es2::BindRenderbuffer;
+	this->glBindTexture = es2::BindTexture;
+	this->glBlendColor = es2::BlendColor;
+	this->glBlendEquation = es2::BlendEquation;
+	this->glBlendEquationSeparate = es2::BlendEquationSeparate;
+	this->glBlendFunc = es2::BlendFunc;
+	this->glBlendFuncSeparate = es2::BlendFuncSeparate;
+	this->glBufferData = es2::BufferData;
+	this->glBufferSubData = es2::BufferSubData;
+	this->glCheckFramebufferStatus = es2::CheckFramebufferStatus;
+	this->glClear = es2::Clear;
+	this->glClearColor = es2::ClearColor;
+	this->glClearDepthf = es2::ClearDepthf;
+	this->glClearStencil = es2::ClearStencil;
+	this->glColorMask = es2::ColorMask;
+	this->glCompileShader = es2::CompileShader;
+	this->glCompressedTexImage2D = es2::CompressedTexImage2D;
+	this->glCompressedTexSubImage2D = es2::CompressedTexSubImage2D;
+	this->glCopyTexImage2D = es2::CopyTexImage2D;
+	this->glCopyTexSubImage2D = es2::CopyTexSubImage2D;
+	this->glCreateProgram = es2::CreateProgram;
+	this->glCreateShader = es2::CreateShader;
+	this->glCullFace = es2::CullFace;
+	this->glDeleteBuffers = es2::DeleteBuffers;
+	this->glDeleteFencesNV = es2::DeleteFencesNV;
+	this->glDeleteFramebuffers = es2::DeleteFramebuffers;
+	this->glDeleteProgram = es2::DeleteProgram;
+	this->glDeleteQueriesEXT = es2::DeleteQueriesEXT;
+	this->glDeleteRenderbuffers = es2::DeleteRenderbuffers;
+	this->glDeleteShader = es2::DeleteShader;
+	this->glDeleteTextures = es2::DeleteTextures;
+	this->glDepthFunc = es2::DepthFunc;
+	this->glDepthMask = es2::DepthMask;
+	this->glDepthRangef = es2::DepthRangef;
+	this->glDetachShader = es2::DetachShader;
+	this->glDisable = es2::Disable;
+	this->glDisableVertexAttribArray = es2::DisableVertexAttribArray;
+	this->glDrawArrays = es2::DrawArrays;
+	this->glDrawElements = es2::DrawElements;
+	this->glDrawArraysInstancedEXT = es2::DrawArraysInstancedEXT;
+	this->glDrawElementsInstancedEXT = es2::DrawElementsInstancedEXT;
+	this->glVertexAttribDivisorEXT = es2::VertexAttribDivisorEXT;
+	this->glDrawArraysInstancedANGLE = es2::DrawArraysInstancedANGLE;
+	this->glDrawElementsInstancedANGLE = es2::DrawElementsInstancedANGLE;
+	this->glVertexAttribDivisorANGLE = es2::VertexAttribDivisorANGLE;
+	this->glEnable = es2::Enable;
+	this->glEnableVertexAttribArray = es2::EnableVertexAttribArray;
+	this->glEndQueryEXT = es2::EndQueryEXT;
+	this->glFinishFenceNV = es2::FinishFenceNV;
+	this->glFinish = es2::Finish;
+	this->glFlush = es2::Flush;
+	this->glFramebufferRenderbuffer = es2::FramebufferRenderbuffer;
+	this->glFramebufferTexture2D = es2::FramebufferTexture2D;
+	this->glFrontFace = es2::FrontFace;
+	this->glGenBuffers = es2::GenBuffers;
+	this->glGenerateMipmap = es2::GenerateMipmap;
+	this->glGenFencesNV = es2::GenFencesNV;
+	this->glGenFramebuffers = es2::GenFramebuffers;
+	this->glGenQueriesEXT = es2::GenQueriesEXT;
+	this->glGenRenderbuffers = es2::GenRenderbuffers;
+	this->glGenTextures = es2::GenTextures;
+	this->glGetActiveAttrib = es2::GetActiveAttrib;
+	this->glGetActiveUniform = es2::GetActiveUniform;
+	this->glGetAttachedShaders = es2::GetAttachedShaders;
+	this->glGetAttribLocation = es2::GetAttribLocation;
+	this->glGetBooleanv = es2::GetBooleanv;
+	this->glGetBufferParameteriv = es2::GetBufferParameteriv;
+	this->glGetError = es2::GetError;
+	this->glGetFenceivNV = es2::GetFenceivNV;
+	this->glGetFloatv = es2::GetFloatv;
+	this->glGetFramebufferAttachmentParameteriv = es2::GetFramebufferAttachmentParameteriv;
+	this->glGetGraphicsResetStatusEXT = es2::GetGraphicsResetStatusEXT;
+	this->glGetIntegerv = es2::GetIntegerv;
+	this->glGetProgramiv = es2::GetProgramiv;
+	this->glGetProgramInfoLog = es2::GetProgramInfoLog;
+	this->glGetQueryivEXT = es2::GetQueryivEXT;
+	this->glGetQueryObjectuivEXT = es2::GetQueryObjectuivEXT;
+	this->glGetRenderbufferParameteriv = es2::GetRenderbufferParameteriv;
+	this->glGetShaderiv = es2::GetShaderiv;
+	this->glGetShaderInfoLog = es2::GetShaderInfoLog;
+	this->glGetShaderPrecisionFormat = es2::GetShaderPrecisionFormat;
+	this->glGetShaderSource = es2::GetShaderSource;
+	this->glGetString = es2::GetString;
+	this->glGetTexParameterfv = es2::GetTexParameterfv;
+	this->glGetTexParameteriv = es2::GetTexParameteriv;
+	this->glGetnUniformfvEXT = es2::GetnUniformfvEXT;
+	this->glGetUniformfv = es2::GetUniformfv;
+	this->glGetnUniformivEXT = es2::GetnUniformivEXT;
+	this->glGetUniformiv = es2::GetUniformiv;
+	this->glGetUniformLocation = es2::GetUniformLocation;
+	this->glGetVertexAttribfv = es2::GetVertexAttribfv;
+	this->glGetVertexAttribiv = es2::GetVertexAttribiv;
+	this->glGetVertexAttribPointerv = es2::GetVertexAttribPointerv;
+	this->glHint = es2::Hint;
+	this->glIsBuffer = es2::IsBuffer;
+	this->glIsEnabled = es2::IsEnabled;
+	this->glIsFenceNV = es2::IsFenceNV;
+	this->glIsFramebuffer = es2::IsFramebuffer;
+	this->glIsProgram = es2::IsProgram;
+	this->glIsQueryEXT = es2::IsQueryEXT;
+	this->glIsRenderbuffer = es2::IsRenderbuffer;
+	this->glIsShader = es2::IsShader;
+	this->glIsTexture = es2::IsTexture;
+	this->glLineWidth = es2::LineWidth;
+	this->glLinkProgram = es2::LinkProgram;
+	this->glPixelStorei = es2::PixelStorei;
+	this->glPolygonOffset = es2::PolygonOffset;
+	this->glReadnPixelsEXT = es2::ReadnPixelsEXT;
+	this->glReadPixels = es2::ReadPixels;
+	this->glReleaseShaderCompiler = es2::ReleaseShaderCompiler;
+	this->glRenderbufferStorageMultisampleANGLE = es2::RenderbufferStorageMultisampleANGLE;
+	this->glRenderbufferStorage = es2::RenderbufferStorage;
+	this->glSampleCoverage = es2::SampleCoverage;
+	this->glSetFenceNV = es2::SetFenceNV;
+	this->glScissor = es2::Scissor;
+	this->glShaderBinary = es2::ShaderBinary;
+	this->glShaderSource = es2::ShaderSource;
+	this->glStencilFunc = es2::StencilFunc;
+	this->glStencilFuncSeparate = es2::StencilFuncSeparate;
+	this->glStencilMask = es2::StencilMask;
+	this->glStencilMaskSeparate = es2::StencilMaskSeparate;
+	this->glStencilOp = es2::StencilOp;
+	this->glStencilOpSeparate = es2::StencilOpSeparate;
+	this->glTestFenceNV = es2::TestFenceNV;
+	this->glTexImage2D = es2::TexImage2D;
+	this->glTexParameterf = es2::TexParameterf;
+	this->glTexParameterfv = es2::TexParameterfv;
+	this->glTexParameteri = es2::TexParameteri;
+	this->glTexParameteriv = es2::TexParameteriv;
+	this->glTexSubImage2D = es2::TexSubImage2D;
+	this->glUniform1f = es2::Uniform1f;
+	this->glUniform1fv = es2::Uniform1fv;
+	this->glUniform1i = es2::Uniform1i;
+	this->glUniform1iv = es2::Uniform1iv;
+	this->glUniform2f = es2::Uniform2f;
+	this->glUniform2fv = es2::Uniform2fv;
+	this->glUniform2i = es2::Uniform2i;
+	this->glUniform2iv = es2::Uniform2iv;
+	this->glUniform3f = es2::Uniform3f;
+	this->glUniform3fv = es2::Uniform3fv;
+	this->glUniform3i = es2::Uniform3i;
+	this->glUniform3iv = es2::Uniform3iv;
+	this->glUniform4f = es2::Uniform4f;
+	this->glUniform4fv = es2::Uniform4fv;
+	this->glUniform4i = es2::Uniform4i;
+	this->glUniform4iv = es2::Uniform4iv;
+	this->glUniformMatrix2fv = es2::UniformMatrix2fv;
+	this->glUniformMatrix3fv = es2::UniformMatrix3fv;
+	this->glUniformMatrix4fv = es2::UniformMatrix4fv;
+	this->glUseProgram = es2::UseProgram;
+	this->glValidateProgram = es2::ValidateProgram;
+	this->glVertexAttrib1f = es2::VertexAttrib1f;
+	this->glVertexAttrib1fv = es2::VertexAttrib1fv;
+	this->glVertexAttrib2f = es2::VertexAttrib2f;
+	this->glVertexAttrib2fv = es2::VertexAttrib2fv;
+	this->glVertexAttrib3f = es2::VertexAttrib3f;
+	this->glVertexAttrib3fv = es2::VertexAttrib3fv;
+	this->glVertexAttrib4f = es2::VertexAttrib4f;
+	this->glVertexAttrib4fv = es2::VertexAttrib4fv;
+	this->glVertexAttribPointer = es2::VertexAttribPointer;
+	this->glViewport = es2::Viewport;
+	this->glBlitFramebufferNV = es2::BlitFramebufferNV;
+	this->glBlitFramebufferANGLE = es2::BlitFramebufferANGLE;
+	this->glTexImage3DOES = es2::TexImage3DOES;
+	this->glTexSubImage3DOES = es2::TexSubImage3DOES;
+	this->glCopyTexSubImage3DOES = es2::CopyTexSubImage3DOES;
+	this->glCompressedTexImage3DOES = es2::CompressedTexImage3DOES;
+	this->glCompressedTexSubImage3DOES = es2::CompressedTexSubImage3DOES;
+	this->glFramebufferTexture3DOES = es2::FramebufferTexture3DOES;
+	this->glEGLImageTargetTexture2DOES = es2::EGLImageTargetTexture2DOES;
+	this->glEGLImageTargetRenderbufferStorageOES = es2::EGLImageTargetRenderbufferStorageOES;
+	this->glIsRenderbufferOES = es2::IsRenderbufferOES;
+	this->glBindRenderbufferOES = es2::BindRenderbufferOES;
+	this->glDeleteRenderbuffersOES = es2::DeleteRenderbuffersOES;
+	this->glGenRenderbuffersOES = es2::GenRenderbuffersOES;
+	this->glRenderbufferStorageOES = es2::RenderbufferStorageOES;
+	this->glGetRenderbufferParameterivOES = es2::GetRenderbufferParameterivOES;
+	this->glIsFramebufferOES = es2::IsFramebufferOES;
+	this->glBindFramebufferOES = es2::BindFramebufferOES;
+	this->glDeleteFramebuffersOES = es2::DeleteFramebuffersOES;
+	this->glGenFramebuffersOES = es2::GenFramebuffersOES;
+	this->glCheckFramebufferStatusOES = es2::CheckFramebufferStatusOES;
+	this->glFramebufferRenderbufferOES = es2::FramebufferRenderbufferOES;
+	this->glFramebufferTexture2DOES = es2::FramebufferTexture2DOES;
+	this->glGetFramebufferAttachmentParameterivOES = es2::GetFramebufferAttachmentParameterivOES;
+	this->glGenerateMipmapOES = es2::GenerateMipmapOES;
+	this->glDrawBuffersEXT = es2::DrawBuffersEXT;
+
+	this->es2CreateContext = ::es2CreateContext;
+	this->es2GetProcAddress = ::es2GetProcAddress;
+	this->createBackBuffer = ::createBackBuffer;
+	this->createDepthStencil = ::createDepthStencil;
+	this->createFrameBuffer = ::createFrameBuffer;
+}
+
+extern "C" GL_APICALL LibGLESv2exports *libGLESv2_swiftshader()
+{
+	static LibGLESv2exports libGLESv2;
+	return &libGLESv2;
+}
+
+LibEGL libEGL;
 LibGLES_CM libGLES_CM;
\ No newline at end of file
diff --git a/src/OpenGL/libGLESv2/main.h b/src/OpenGL/libGLESv2/main.h
index 447365d..3f2fa78 100644
--- a/src/OpenGL/libGLESv2/main.h
+++ b/src/OpenGL/libGLESv2/main.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // main.h: Management of thread-local data.
 
diff --git a/src/OpenGL/libGLESv2/mathutil.h b/src/OpenGL/libGLESv2/mathutil.h
index 6e5ddab..0fbd709 100644
--- a/src/OpenGL/libGLESv2/mathutil.h
+++ b/src/OpenGL/libGLESv2/mathutil.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 // mathutil.h: Math and bit manipulation functions.
 
@@ -21,27 +24,27 @@
 {
 inline bool isPow2(int x)
 {
-    return (x & (x - 1)) == 0 && (x != 0);
+	return (x & (x - 1)) == 0 && (x != 0);
 }
 
 inline int log2(int x)
 {
-    int r = 0;
-    while((x >> r) > 1) r++;
-    return r;
+	int r = 0;
+	while((x >> r) > 1) r++;
+	return r;
 }
 
 inline unsigned int ceilPow2(unsigned int x)
 {
-    if(x != 0) x--;
-    x |= x >> 1;
-    x |= x >> 2;
-    x |= x >> 4;
-    x |= x >> 8;
-    x |= x >> 16;
-    x++;
+	if(x != 0) x--;
+	x |= x >> 1;
+	x |= x >> 2;
+	x |= x >> 4;
+	x |= x >> 8;
+	x |= x >> 16;
+	x++;
 
-    return x;
+	return x;
 }
 
 using sw::swap;
@@ -51,20 +54,20 @@
 template<const int n>
 inline unsigned int unorm(float x)
 {
-    const unsigned int max = 0xFFFFFFFF >> (32 - n);
+	const unsigned int max = 0xFFFFFFFF >> (32 - n);
 
-    if(x > 1)
-    {
-        return max;
-    }
-    else if(x < 0)
-    {
-        return 0;
-    }
-    else
-    {
-        return (unsigned int)(max * x + 0.5f);
-    }
+	if(x > 1)
+	{
+		return max;
+	}
+	else if(x < 0)
+	{
+		return 0;
+	}
+	else
+	{
+		return (unsigned int)(max * x + 0.5f);
+	}
 }
 }
 
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index ffcad31..09e5975 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -1,1931 +1,1934 @@
-// 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 "main.h"

-#include "mathutil.h"

-#include "Context.h"

-#include "common/debug.h"

-

-#include <limits>

-#include <stdio.h>

-#include <stdlib.h>

-

-namespace es2

-{

-	// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation

-	// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid

-	// format and type combinations.

-

-	typedef std::pair<GLenum, GLenum> FormatTypePair;

-	typedef std::pair<FormatTypePair, GLenum> FormatPair;

-	typedef std::map<FormatTypePair, GLenum> FormatMap;

-

-	// A helper function to insert data into the format map with fewer characters.

-	static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)

-	{

-		map->insert(FormatPair(FormatTypePair(format, type), internalFormat));

-	}

-

-	FormatMap BuildFormatMap()

-	{

-		static const GLenum GL_BGRA4_ANGLEX = 0x6ABC;

-		static const GLenum GL_BGR5_A1_ANGLEX = 0x6ABD;

-

-		FormatMap map;

-

-		//                       | Format | Type | Internal format |

-		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);

-		InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);

-		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);

-		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);

-		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);

-		InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);

-		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);

-		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);

-

-		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);

-		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);

-		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);

-		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);

-		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);

-		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);

-		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);

-

-		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);

-		InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);

-		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);

-		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);

-		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);

-		InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);

-		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);

-		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);

-

-		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);

-		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);

-		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);

-		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);

-		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);

-		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);

-

-		InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);

-		InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);

-		InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);

-		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);

-		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);

-

-		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);

-		InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);

-		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);

-		InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);

-		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);

-		InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);

-

-		InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);

-		InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);

-		InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);

-		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);

-		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);

-

-		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);

-		InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);

-		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);

-		InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);

-		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);

-		InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);

-

-		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);

-		InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);

-		InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);

-		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);

-		InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);

-		InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);

-		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);

-		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);

-		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);

-		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);

-		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);

-		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);

-

-		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);

-		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);

-		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);

-

-		InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);

-		InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);

-

-		InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);

-		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);

-		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);

-		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);

-

-		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);

-		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);

-		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);

-

-		InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);

-

-		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);

-		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);

-

-		return map;

-	}

-

-	GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)

-	{

-		switch(internalFormat)

-		{

-		case GL_ALPHA:

-		case GL_LUMINANCE:

-		case GL_LUMINANCE_ALPHA:

-		case GL_RED:

-		case GL_RG:

-		case GL_RGB:

-		case GL_RGBA:

-		case GL_RED_INTEGER:

-		case GL_RG_INTEGER:

-		case GL_RGB_INTEGER:

-		case GL_RGBA_INTEGER:

-		case GL_BGRA_EXT:

-		case GL_DEPTH_COMPONENT:

-		case GL_DEPTH_STENCIL:

-		case GL_SRGB_EXT:

-		case GL_SRGB_ALPHA_EXT:

-			{

-				static const FormatMap formatMap = BuildFormatMap();

-				FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));

-				return (iter != formatMap.end()) ? iter->second : GL_NONE;

-			}

-		default:

-			return internalFormat;

-		}

-	}

-

-	unsigned int UniformComponentCount(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_BOOL:

-		case GL_FLOAT:

-		case GL_INT:

-		case GL_UNSIGNED_INT:

-		case GL_SAMPLER_2D:

-		case GL_SAMPLER_CUBE:

-        case GL_SAMPLER_EXTERNAL_OES:

-		case GL_SAMPLER_3D_OES:

-		case GL_SAMPLER_2D_ARRAY:

-		case GL_SAMPLER_2D_SHADOW:

-		case GL_SAMPLER_CUBE_SHADOW:

-		case GL_SAMPLER_2D_ARRAY_SHADOW:

-		case GL_INT_SAMPLER_2D:

-		case GL_UNSIGNED_INT_SAMPLER_2D:

-		case GL_INT_SAMPLER_CUBE:

-		case GL_UNSIGNED_INT_SAMPLER_CUBE:

-		case GL_INT_SAMPLER_3D:

-		case GL_UNSIGNED_INT_SAMPLER_3D:

-		case GL_INT_SAMPLER_2D_ARRAY:

-		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:

-			return 1;

-		case GL_BOOL_VEC2:

-		case GL_FLOAT_VEC2:

-		case GL_INT_VEC2:

-		case GL_UNSIGNED_INT_VEC2:

-			return 2;

-		case GL_INT_VEC3:

-		case GL_UNSIGNED_INT_VEC3:

-		case GL_FLOAT_VEC3:

-		case GL_BOOL_VEC3:

-			return 3;

-		case GL_BOOL_VEC4:

-		case GL_FLOAT_VEC4:

-		case GL_INT_VEC4:

-		case GL_UNSIGNED_INT_VEC4:

-		case GL_FLOAT_MAT2:

-			return 4;

-		case GL_FLOAT_MAT2x3:

-		case GL_FLOAT_MAT3x2:

-			return 6;

-		case GL_FLOAT_MAT2x4:

-		case GL_FLOAT_MAT4x2:

-			return 8;

-		case GL_FLOAT_MAT3:

-			return 9;

-		case GL_FLOAT_MAT3x4:

-		case GL_FLOAT_MAT4x3:

-			return 12;

-		case GL_FLOAT_MAT4:

-			return 16;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return 0;

-	}

-

-	GLenum UniformComponentType(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_BOOL:

-		case GL_BOOL_VEC2:

-		case GL_BOOL_VEC3:

-		case GL_BOOL_VEC4:

-			return GL_BOOL;

-		case GL_FLOAT:

-		case GL_FLOAT_VEC2:

-		case GL_FLOAT_VEC3:

-		case GL_FLOAT_VEC4:

-		case GL_FLOAT_MAT2:

-		case GL_FLOAT_MAT2x3:

-		case GL_FLOAT_MAT2x4:

-		case GL_FLOAT_MAT3:

-		case GL_FLOAT_MAT3x2:

-		case GL_FLOAT_MAT3x4:

-		case GL_FLOAT_MAT4:

-		case GL_FLOAT_MAT4x2:

-		case GL_FLOAT_MAT4x3:

-			return GL_FLOAT;

-		case GL_INT:

-		case GL_SAMPLER_2D:

-		case GL_SAMPLER_CUBE:

-		case GL_SAMPLER_EXTERNAL_OES:

-		case GL_SAMPLER_3D_OES:

-		case GL_SAMPLER_2D_ARRAY:

-		case GL_SAMPLER_2D_SHADOW:

-		case GL_SAMPLER_CUBE_SHADOW:

-		case GL_SAMPLER_2D_ARRAY_SHADOW:

-		case GL_INT_SAMPLER_2D:

-		case GL_UNSIGNED_INT_SAMPLER_2D:

-		case GL_INT_SAMPLER_CUBE:

-		case GL_UNSIGNED_INT_SAMPLER_CUBE:

-		case GL_INT_SAMPLER_3D:

-		case GL_UNSIGNED_INT_SAMPLER_3D:

-		case GL_INT_SAMPLER_2D_ARRAY:

-		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:

-		case GL_INT_VEC2:

-		case GL_INT_VEC3:

-		case GL_INT_VEC4:

-			return GL_INT;

-		case GL_UNSIGNED_INT:

-		case GL_UNSIGNED_INT_VEC2:

-		case GL_UNSIGNED_INT_VEC3:

-		case GL_UNSIGNED_INT_VEC4:

-			return GL_UNSIGNED_INT;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return GL_NONE;

-	}

-

-	size_t UniformTypeSize(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_BOOL:  return sizeof(GLboolean);

-		case GL_FLOAT: return sizeof(GLfloat);

-		case GL_INT:   return sizeof(GLint);

-		case GL_UNSIGNED_INT: return sizeof(GLuint);

-		}

-

-		return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);

-	}

-

-	bool IsSamplerUniform(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_SAMPLER_2D:

-		case GL_SAMPLER_CUBE:

-		case GL_SAMPLER_EXTERNAL_OES:

-		case GL_SAMPLER_3D_OES:

-		case GL_SAMPLER_2D_ARRAY:

-		case GL_SAMPLER_2D_SHADOW:

-		case GL_SAMPLER_CUBE_SHADOW:

-		case GL_SAMPLER_2D_ARRAY_SHADOW:

-		case GL_INT_SAMPLER_2D:

-		case GL_UNSIGNED_INT_SAMPLER_2D:

-		case GL_INT_SAMPLER_CUBE:

-		case GL_UNSIGNED_INT_SAMPLER_CUBE:

-		case GL_INT_SAMPLER_3D:

-		case GL_UNSIGNED_INT_SAMPLER_3D:

-		case GL_INT_SAMPLER_2D_ARRAY:

-		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:

-			return true;

-		default:

-			return false;

-		}

-	}

-

-	int VariableRowCount(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_NONE:

-			return 0;

-		case GL_BOOL:

-		case GL_FLOAT:

-		case GL_INT:

-		case GL_UNSIGNED_INT:

-		case GL_BOOL_VEC2:

-		case GL_FLOAT_VEC2:

-		case GL_INT_VEC2:

-		case GL_UNSIGNED_INT_VEC2:

-		case GL_INT_VEC3:

-		case GL_UNSIGNED_INT_VEC3:

-		case GL_FLOAT_VEC3:

-		case GL_BOOL_VEC3:

-		case GL_BOOL_VEC4:

-		case GL_FLOAT_VEC4:

-		case GL_INT_VEC4:

-		case GL_UNSIGNED_INT_VEC4:

-		case GL_SAMPLER_2D:

-		case GL_SAMPLER_CUBE:

-        case GL_SAMPLER_EXTERNAL_OES:

-		case GL_SAMPLER_3D_OES:

-		case GL_SAMPLER_2D_ARRAY:

-		case GL_SAMPLER_2D_SHADOW:

-		case GL_SAMPLER_CUBE_SHADOW:

-		case GL_SAMPLER_2D_ARRAY_SHADOW:

-		case GL_INT_SAMPLER_2D:

-		case GL_UNSIGNED_INT_SAMPLER_2D:

-		case GL_INT_SAMPLER_CUBE:

-		case GL_UNSIGNED_INT_SAMPLER_CUBE:

-		case GL_INT_SAMPLER_3D:

-		case GL_UNSIGNED_INT_SAMPLER_3D:

-		case GL_INT_SAMPLER_2D_ARRAY:

-		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:

-			return 1;

-		case GL_FLOAT_MAT2:

-		case GL_FLOAT_MAT3x2:

-		case GL_FLOAT_MAT4x2:

-			return 2;

-		case GL_FLOAT_MAT3:

-		case GL_FLOAT_MAT2x3:

-		case GL_FLOAT_MAT4x3:

-			return 3;

-		case GL_FLOAT_MAT4:

-		case GL_FLOAT_MAT2x4:

-		case GL_FLOAT_MAT3x4:

-			return 4;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return 0;

-	}

-

-	int VariableColumnCount(GLenum type)

-	{

-		switch(type)

-		{

-		case GL_NONE:

-			return 0;

-		case GL_BOOL:

-		case GL_FLOAT:

-		case GL_INT:

-		case GL_UNSIGNED_INT:

-			return 1;

-		case GL_BOOL_VEC2:

-		case GL_FLOAT_VEC2:

-		case GL_INT_VEC2:

-		case GL_UNSIGNED_INT_VEC2:

-		case GL_FLOAT_MAT2:

-		case GL_FLOAT_MAT2x3:

-		case GL_FLOAT_MAT2x4:

-			return 2;

-		case GL_INT_VEC3:

-		case GL_UNSIGNED_INT_VEC3:

-		case GL_FLOAT_VEC3:

-		case GL_BOOL_VEC3:

-		case GL_FLOAT_MAT3:

-		case GL_FLOAT_MAT3x2:

-		case GL_FLOAT_MAT3x4:

-			return 3;

-		case GL_BOOL_VEC4:

-		case GL_FLOAT_VEC4:

-		case GL_INT_VEC4:

-		case GL_UNSIGNED_INT_VEC4:

-		case GL_FLOAT_MAT4:

-		case GL_FLOAT_MAT4x2:

-		case GL_FLOAT_MAT4x3:

-			return 4;

-		default:

-			UNREACHABLE(type);

-		}

-

-		return 0;

-	}

-

-	int VariableRegisterCount(GLenum type)

-	{

-		// Number of registers used is the number of columns for matrices or 1 for scalars and vectors

-		return (VariableRowCount(type) > 1) ? VariableColumnCount(type) : 1;

-	}

-

-	int VariableRegisterSize(GLenum type)

-	{

-		// Number of components per register is the number of rows for matrices or columns for scalars and vectors

-		int nbRows = VariableRowCount(type);

-		return (nbRows > 1) ? nbRows : VariableColumnCount(type);

-	}

-

-	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)

-	{

-		ASSERT(allocationSize <= bitsSize);

-

-		unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);

-

-		for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)

-		{

-			if((*bits & mask) == 0)

-			{

-				*bits |= mask;

-				return i;

-			}

-

-			mask <<= 1;

-		}

-

-		return -1;

-	}

-

-	GLint floatToInt(GLfloat value)

-	{

-		return static_cast<GLint>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) * 0.5f);

-	}

-

-	bool IsCompressed(GLenum format, GLint clientVersion)

-	{

-		return ValidateCompressedFormat(format, clientVersion, true) == GL_NONE;

-	}

-

-	GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats)

-	{

-		switch(format)

-		{

-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

-		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

-			return S3TC_SUPPORT ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;

-		case GL_ETC1_RGB8_OES:

-			return expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION;

-		case GL_COMPRESSED_R11_EAC:

-		case GL_COMPRESSED_SIGNED_R11_EAC:

-		case GL_COMPRESSED_RG11_EAC:

-		case GL_COMPRESSED_SIGNED_RG11_EAC:

-		case GL_COMPRESSED_RGB8_ETC2:

-		case GL_COMPRESSED_SRGB8_ETC2:

-		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:

-		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:

-		case GL_COMPRESSED_RGBA8_ETC2_EAC:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:

-		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:

-		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:

-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:

-			return (clientVersion >= 3) ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;

-		default:

-			return expectCompressedFormats ? GL_INVALID_ENUM : GL_NONE; // Not compressed format

-		}

-	}

-

-	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)

-	{

-		if(!texture)

-		{

-			return GL_INVALID_OPERATION;

-		}

-

-		if(compressed != texture->isCompressed(target, level))

-		{

-			return GL_INVALID_OPERATION;

-		}

-

-		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))

-		{

-			return GL_INVALID_OPERATION;

-		}

-

-		if(compressed)

-		{

-			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-			   (height % 4 != 0 && height != texture->getHeight(target, 0)))

-			{

-				return GL_INVALID_OPERATION;

-			}

-		}

-

-		if(xoffset + width > texture->getWidth(target, level) ||

-		   yoffset + height > texture->getHeight(target, level))

-		{

-			return GL_INVALID_VALUE;

-		}

-

-		return GL_NONE;

-	}

-

-	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)

-	{

-		if(!texture)

-		{

-			return GL_INVALID_OPERATION;

-		}

-

-		if(compressed != texture->isCompressed(target, level))

-		{

-			return GL_INVALID_OPERATION;

-		}

-

-		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))

-		{

-			return GL_INVALID_OPERATION;

-		}

-

-		if(compressed)

-		{

-			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-			   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||

-			   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))

-			{

-				return GL_INVALID_OPERATION;

-			}

-		}

-

-		if(xoffset + width > texture->getWidth(target, level) ||

-		   yoffset + height > texture->getHeight(target, level) ||

-		   zoffset + depth > texture->getDepth(target, level))

-		{

-			return GL_INVALID_VALUE;

-		}

-

-		return GL_NONE;

-	}

-

-	bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, GLint clientVersion)

-	{

-		switch(format)

-		{

-		case GL_RGBA:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:

-				break;

-			case GL_UNSIGNED_INT_2_10_10_10_REV:

-				return (clientVersion >= 3) && (internalFormat == GL_RGB10_A2);

-			case GL_FLOAT:

-				return (clientVersion >= 3) && (internalType == GL_FLOAT);

-			default:

-				return false;

-			}

-			break;

-		case GL_RGBA_INTEGER:

-			if(clientVersion < 3)

-			{

-				return false;

-			}

-			switch(type)

-			{

-			case GL_INT:

-				if(internalType != GL_INT)

-				{

-					return false;

-				}

-				break;

-			case GL_UNSIGNED_INT:

-				if(internalType != GL_UNSIGNED_INT)

-				{

-					return false;

-				}

-				break;

-			default:

-				return false;

-			}

-			break;

-		case GL_BGRA_EXT:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:

-			case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:

-			case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:

-				break;

-			default:

-				return false;

-			}

-			break;

-		case GL_RG_EXT:

-		case GL_RED_EXT:

-			return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE);

-		case GL_DEPTH_COMPONENT:

-			if (internalFormat != format)

-			{

-				return false;

-			}

-			switch(type)

-			{

-			case GL_UNSIGNED_SHORT:

-			case GL_FLOAT:

-				if (internalType != type)

-				{

-					return false;

-				}

-				break;

-			default:

-				return false;

-			}

-			break;

-		default:

-			return false;

-		}

-		return true;

-	}

-

-	bool IsDepthTexture(GLenum format)

-	{

-		return format == GL_DEPTH_COMPONENT ||

-		       format == GL_DEPTH_STENCIL_OES ||

-		       format == GL_DEPTH_COMPONENT16 ||

-		       format == GL_DEPTH_COMPONENT24 ||

-		       format == GL_DEPTH_COMPONENT32_OES ||

-		       format == GL_DEPTH_COMPONENT32F ||

-		       format == GL_DEPTH24_STENCIL8 ||

-		       format == GL_DEPTH32F_STENCIL8;

-	}

-

-	bool IsStencilTexture(GLenum format)

-	{

-		return format == GL_STENCIL_INDEX_OES ||

-		       format == GL_DEPTH_STENCIL_OES ||

-		       format == GL_DEPTH24_STENCIL8 ||

-		       format == GL_DEPTH32F_STENCIL8;

-	}

-

-	bool IsCubemapTextureTarget(GLenum target)

-	{

-		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);

-	}

-

-	int CubeFaceIndex(GLenum cubeFace)

-	{

-		switch(cubeFace)

-		{

-		case GL_TEXTURE_CUBE_MAP:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;

-		default: UNREACHABLE(cubeFace); return 0;

-		}

-	}

-

-	bool IsTextureTarget(GLenum target)

-	{

-		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;

-	}

-

-	bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)

-	{

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		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_FLOAT:               // GL_OES_texture_float

-		case GL_HALF_FLOAT_OES:      // GL_OES_texture_half_float

-		case GL_UNSIGNED_INT_24_8:   // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT)

-		case GL_UNSIGNED_SHORT:      // GL_OES_depth_texture

-		case GL_UNSIGNED_INT:        // GL_OES_depth_texture

-			break;

-		case GL_BYTE:

-		case GL_SHORT:

-		case GL_INT:

-		case GL_HALF_FLOAT:

-		case GL_UNSIGNED_INT_2_10_10_10_REV:

-		case GL_UNSIGNED_INT_10F_11F_11F_REV:

-		case GL_UNSIGNED_INT_5_9_9_9_REV:

-		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM, false);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-

-		switch(format)

-		{

-		case GL_ALPHA:

-		case GL_RGB:

-		case GL_RGBA:

-		case GL_LUMINANCE:

-		case GL_LUMINANCE_ALPHA:

-		case GL_BGRA_EXT:          // GL_EXT_texture_format_BGRA8888

-		case GL_DEPTH_STENCIL:     // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)

-		case GL_DEPTH_COMPONENT:   // GL_OES_depth_texture

-			break;

-		case GL_RED:

-		case GL_RED_INTEGER:

-		case GL_RG:

-		case GL_RG_INTEGER:

-		case GL_RGB_INTEGER:

-		case GL_RGBA_INTEGER:

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_ENUM, false);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM, false);

-		}

-

-		if(internalformat != format)

-		{

-			if(clientVersion < 3)

-			{

-				return error(GL_INVALID_OPERATION, false);

-			}

-

-			switch(internalformat)

-			{

-			case GL_R8:

-			case GL_R8UI:

-			case GL_R8I:

-			case GL_R16UI:

-			case GL_R16I:

-			case GL_R32UI:

-			case GL_R32I:

-			case GL_RG8:

-			case GL_RG8UI:

-			case GL_RG8I:

-			case GL_RG16UI:

-			case GL_RG16I:

-			case GL_RG32UI:

-			case GL_RG32I:

-			case GL_SRGB8_ALPHA8:

-			case GL_RGB8UI:

-			case GL_RGB8I:

-			case GL_RGB16UI:

-			case GL_RGB16I:

-			case GL_RGB32UI:

-			case GL_RGB32I:

-			case GL_RG8_SNORM:

-			case GL_R8_SNORM:

-			case GL_RGB10_A2:

-			case GL_RGBA8UI:

-			case GL_RGBA8I:

-			case GL_RGB10_A2UI:

-			case GL_RGBA16UI:

-			case GL_RGBA16I:

-			case GL_RGBA32I:

-			case GL_RGBA32UI:

-			case GL_RGBA4:

-			case GL_RGB5_A1:

-			case GL_RGB565:

-			case GL_RGB8_OES:

-			case GL_RGBA8_OES:

-			case GL_R16F:

-			case GL_RG16F:

-			case GL_R11F_G11F_B10F:

-			case GL_RGB16F:

-			case GL_RGBA16F:

-			case GL_R32F:

-			case GL_RG32F:

-			case GL_RGB32F:

-			case GL_RGBA32F:

-			case GL_DEPTH_COMPONENT24:

-			case GL_DEPTH_COMPONENT32_OES:

-			case GL_DEPTH_COMPONENT32F:

-			case GL_DEPTH32F_STENCIL8:

-			case GL_DEPTH_COMPONENT16:

-			case GL_STENCIL_INDEX8:

-			case GL_DEPTH24_STENCIL8_OES:

-			case GL_RGBA8_SNORM:

-			case GL_SRGB8:

-			case GL_RGB8_SNORM:

-			case GL_RGB9_E5:

-				break;

-			default:

-				return error(GL_INVALID_ENUM, false);

-			}

-		}

-

-		// Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]

-		bool validSizedInternalformat = false;

-		#define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;

-

-		switch(format)

-		{

-		case GL_RGBA:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)

-			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)

-			case GL_HALF_FLOAT_OES:              break;

-			case GL_UNSIGNED_SHORT_4_4_4_4:      VALIDATE_INTERNALFORMAT(GL_RGBA4)

-			case GL_UNSIGNED_SHORT_5_5_5_1:      VALIDATE_INTERNALFORMAT(GL_RGB5_A1)

-			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)

-			case GL_HALF_FLOAT:                  VALIDATE_INTERNALFORMAT(GL_RGBA16F)

-			case GL_FLOAT:                       VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)

-			default:                             return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_RGBA_INTEGER:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8UI)

-			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8I)

-			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGBA16UI)

-			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGBA16I)

-			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGBA32UI)

-			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGBA32I)

-			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)

-			default:                             return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_RGB:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:                VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)

-			case GL_BYTE:                         VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)

-			case GL_HALF_FLOAT_OES:               break;

-			case GL_UNSIGNED_SHORT_5_6_5:         VALIDATE_INTERNALFORMAT(GL_RGB565)

-			case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)

-			case GL_UNSIGNED_INT_5_9_9_9_REV:     VALIDATE_INTERNALFORMAT(GL_RGB9_E5)

-			case GL_HALF_FLOAT:                   VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)

-			case GL_FLOAT:                        VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)

-			default:                              return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_RGB_INTEGER:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGB8UI)

-			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGB8I)

-			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGB16UI)

-			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGB16I)

-			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGB32UI)

-			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGB32I)

-			default:                             return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_RG:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)

-			case GL_BYTE:          VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)

-			case GL_HALF_FLOAT:    VALIDATE_INTERNALFORMAT(GL_RG16F)

-			case GL_FLOAT:         VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)

-			default:               return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_RG_INTEGER:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RG8UI)

-			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RG8I)

-			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)

-			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_RG16I)

-			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_RG32UI)

-			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_RG32I)

-			default:                return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_RED:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8)

-			case GL_BYTE:          VALIDATE_INTERNALFORMAT(GL_R8_SNORM)

-			case GL_HALF_FLOAT:    VALIDATE_INTERNALFORMAT(GL_R16F)

-			case GL_FLOAT:         VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)

-			default:               return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_RED_INTEGER:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_R8UI)

-			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_R8I)

-			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)

-			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_R16I)

-			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_R32UI)

-			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_R32I)

-			default:                return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_DEPTH_COMPONENT:

-			switch(type)

-			{

-			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)

-			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)

-			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)

-			default:                return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_DEPTH_STENCIL:

-			switch(type)

-			{

-			case GL_UNSIGNED_INT_24_8:              VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)

-			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)

-			default:                                return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_LUMINANCE_ALPHA:

-		case GL_LUMINANCE:

-		case GL_ALPHA:

-			switch(type)

-			{

-			case GL_UNSIGNED_BYTE:

-			case GL_HALF_FLOAT_OES:

-			case GL_FLOAT:

-				break;

-			default:

-				return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		case GL_BGRA_EXT:

-			if(type != GL_UNSIGNED_BYTE)

-			{

-				return error(GL_INVALID_OPERATION, false);

-			}

-			break;

-		default:

-			UNREACHABLE(format);

-			return error(GL_INVALID_ENUM, false);

-		}

-

-		#undef VALIDATE_INTERNALFORMAT

-

-		if(internalformat != format && !validSizedInternalformat)

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-

-		return true;

-	}

-

-	bool IsColorRenderable(GLenum internalformat, GLint clientVersion)

-	{

-		switch(internalformat)

-		{

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-		case GL_R16F:

-		case GL_RG16F:

-		case GL_RGB16F:

-		case GL_RGBA16F:

-		case GL_BGRA8_EXT:

-			return true;

-		case GL_R8:

-		case GL_R8UI:

-		case GL_R8I:

-		case GL_R16UI:

-		case GL_R16I:

-		case GL_R32UI:

-		case GL_R32I:

-		case GL_RG8:

-		case GL_RG8UI:

-		case GL_RG8I:

-		case GL_RG16UI:

-		case GL_RG16I:

-		case GL_RG32UI:

-		case GL_RG32I:

-		case GL_SRGB8_ALPHA8:

-		case GL_RGB10_A2:

-		case GL_RGBA8UI:

-		case GL_RGBA8I:

-		case GL_RGB10_A2UI:

-		case GL_RGBA16UI:

-		case GL_RGBA16I:

-		case GL_RGBA32I:

-		case GL_RGBA32UI:

-		case GL_R11F_G11F_B10F:

-		case GL_R32F:

-		case GL_RG32F:

-		case GL_RGB32F:

-		case GL_RGBA32F:

-			return clientVersion >= 3;

-		case GL_DEPTH_COMPONENT24:

-		case GL_DEPTH_COMPONENT32_OES:

-		case GL_DEPTH_COMPONENT32F:

-		case GL_DEPTH32F_STENCIL8:

-		case GL_DEPTH_COMPONENT16:

-		case GL_STENCIL_INDEX8:

-		case GL_DEPTH24_STENCIL8_OES:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsDepthRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT24:

-		case GL_DEPTH_COMPONENT32_OES:

-		case GL_DEPTH_COMPONENT32F:

-		case GL_DEPTH32F_STENCIL8:

-		case GL_DEPTH_COMPONENT16:

-		case GL_DEPTH24_STENCIL8_OES:

-			return true;

-		case GL_STENCIL_INDEX8:

-		case GL_R8:

-		case GL_R8UI:

-		case GL_R8I:

-		case GL_R16UI:

-		case GL_R16I:

-		case GL_R32UI:

-		case GL_R32I:

-		case GL_RG8:

-		case GL_RG8UI:

-		case GL_RG8I:

-		case GL_RG16UI:

-		case GL_RG16I:

-		case GL_RG32UI:

-		case GL_RG32I:

-		case GL_SRGB8_ALPHA8:

-		case GL_RGB10_A2:

-		case GL_RGBA8UI:

-		case GL_RGBA8I:

-		case GL_RGB10_A2UI:

-		case GL_RGBA16UI:

-		case GL_RGBA16I:

-		case GL_RGBA32I:

-		case GL_RGBA32UI:

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-		case GL_RGB:

-		case GL_RGBA:

-		case GL_R16F:

-		case GL_RG16F:

-		case GL_R11F_G11F_B10F:

-		case GL_RGB16F:

-		case GL_RGBA16F:

-		case GL_R32F:

-		case GL_RG32F:

-		case GL_RGB32F:

-		case GL_RGBA32F:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsStencilRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_DEPTH32F_STENCIL8:

-		case GL_STENCIL_INDEX8:

-		case GL_DEPTH24_STENCIL8_OES:

-			return true;

-		case GL_R8:

-		case GL_R8UI:

-		case GL_R8I:

-		case GL_R16UI:

-		case GL_R16I:

-		case GL_R32UI:

-		case GL_R32I:

-		case GL_RG8:

-		case GL_RG8UI:

-		case GL_RG8I:

-		case GL_RG16UI:

-		case GL_RG16I:

-		case GL_RG32UI:

-		case GL_RG32I:

-		case GL_SRGB8_ALPHA8:

-		case GL_RGB10_A2:

-		case GL_RGBA8UI:

-		case GL_RGBA8I:

-		case GL_RGB10_A2UI:

-		case GL_RGBA16UI:

-		case GL_RGBA16I:

-		case GL_RGBA32I:

-		case GL_RGBA32UI:

-		case GL_RGBA4:

-		case GL_RGB5_A1:

-		case GL_RGB565:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-		case GL_RGB:

-		case GL_RGBA:

-		case GL_R16F:

-		case GL_RG16F:

-		case GL_R11F_G11F_B10F:

-		case GL_RGB16F:

-		case GL_RGBA16F:

-		case GL_R32F:

-		case GL_RG32F:

-		case GL_RGB32F:

-		case GL_RGBA32F:

-		case GL_DEPTH_COMPONENT16:

-		case GL_DEPTH_COMPONENT24:

-		case GL_DEPTH_COMPONENT32_OES:

-		case GL_DEPTH_COMPONENT32F:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	std::string ParseUniformName(const std::string &name, size_t *outSubscript)

-	{

-		// Strip any trailing array operator and retrieve the subscript

-		size_t open = name.find_last_of('[');

-		size_t close = name.find_last_of(']');

-		bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);

-		if(!hasIndex)

-		{

-			if(outSubscript)

-			{

-				*outSubscript = GL_INVALID_INDEX;

-			}

-			return name;

-		}

-

-		if(outSubscript)

-		{

-			int index = atoi(name.substr(open + 1).c_str());

-			if(index >= 0)

-			{

-				*outSubscript = index;

-			}

-			else

-			{

-				*outSubscript = GL_INVALID_INDEX;

-			}

-		}

-

-		return name.substr(0, open);

-	}

-}

-

-namespace es2sw

-{

-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::DEPTH_NEVER;

-		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;

-		case GL_LESS:     return sw::DEPTH_LESS;

-		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;

-		case GL_EQUAL:    return sw::DEPTH_EQUAL;

-		case GL_GREATER:  return sw::DEPTH_GREATER;

-		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::DEPTH_ALWAYS;

-	}

-

-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::STENCIL_NEVER;

-		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;

-		case GL_LESS:     return sw::STENCIL_LESS;

-		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;

-		case GL_EQUAL:    return sw::STENCIL_EQUAL;

-		case GL_GREATER:  return sw::STENCIL_GREATER;

-		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::STENCIL_ALWAYS;

-	}

-

-	sw::Color<float> ConvertColor(es2::Color color)

-	{

-		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);

-	}

-

-	sw::BlendFactor ConvertBlendFunc(GLenum blend)

-	{

-		switch(blend)

-		{

-		case GL_ZERO:                     return sw::BLEND_ZERO;

-		case GL_ONE:                      return sw::BLEND_ONE;

-		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;

-		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;

-		case GL_DST_COLOR:                return sw::BLEND_DEST;

-		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;

-		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;

-		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;

-		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;

-		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;

-		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;

-		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;

-		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;

-		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;

-		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;

-		default: UNREACHABLE(blend);

-		}

-

-		return sw::BLEND_ZERO;

-	}

-

-	sw::BlendOperation ConvertBlendOp(GLenum blendOp)

-	{

-		switch(blendOp)

-		{

-		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;

-		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;

-		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;

-		case GL_MIN_EXT:               return sw::BLENDOP_MIN;

-		case GL_MAX_EXT:               return sw::BLENDOP_MAX;

-		default: UNREACHABLE(blendOp);

-		}

-

-		return sw::BLENDOP_ADD;

-	}

-

-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)

-	{

-		switch(stencilOp)

-		{

-		case GL_ZERO:      return sw::OPERATION_ZERO;

-		case GL_KEEP:      return sw::OPERATION_KEEP;

-		case GL_REPLACE:   return sw::OPERATION_REPLACE;

-		case GL_INCR:      return sw::OPERATION_INCRSAT;

-		case GL_DECR:      return sw::OPERATION_DECRSAT;

-		case GL_INVERT:    return sw::OPERATION_INVERT;

-		case GL_INCR_WRAP: return sw::OPERATION_INCR;

-		case GL_DECR_WRAP: return sw::OPERATION_DECR;

-		default: UNREACHABLE(stencilOp);

-		}

-

-		return sw::OPERATION_KEEP;

-	}

-

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap)

-	{

-		switch(wrap)

-		{

-		case GL_REPEAT:            return sw::ADDRESSING_WRAP;

-		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;

-		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;

-		default: UNREACHABLE(wrap);

-		}

-

-		return sw::ADDRESSING_WRAP;

-	}

-

-	sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)

-	{

-		switch(swizzleType)

-		{

-		case GL_RED:   return sw::SWIZZLE_RED;

-		case GL_GREEN: return sw::SWIZZLE_GREEN;

-		case GL_BLUE:  return sw::SWIZZLE_BLUE;

-		case GL_ALPHA: return sw::SWIZZLE_ALPHA;

-		case GL_ZERO:  return sw::SWIZZLE_ZERO;

-		case GL_ONE:   return sw::SWIZZLE_ONE;

-		default: UNREACHABLE(swizzleType);

-		}

-

-		return sw::SWIZZLE_RED;

-	};

-

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

-		case GL_RGB5_A1:

-		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;

-		case GL_RGB565:               return sw::FORMAT_R5G6B5;

-		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;

-		case GL_DEPTH_COMPONENT16:

-		case GL_STENCIL_INDEX8:

-		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;

-		case GL_DEPTH_COMPONENT32_OES:return sw::FORMAT_D32;

-		case GL_R8:                   return sw::FORMAT_R8;

-		case GL_RG8:                  return sw::FORMAT_G8R8;

-		case GL_R8I:                  return sw::FORMAT_R8I;

-		case GL_RG8I:                 return sw::FORMAT_G8R8I;

-		case GL_RGB8I:                return sw::FORMAT_X8B8G8R8I;

-		case GL_RGBA8I:               return sw::FORMAT_A8B8G8R8I;

-		case GL_R8UI:                 return sw::FORMAT_R8UI;

-		case GL_RG8UI:                return sw::FORMAT_G8R8UI;

-		case GL_RGB8UI:               return sw::FORMAT_X8B8G8R8UI;

-		case GL_RGBA8UI:              return sw::FORMAT_A8B8G8R8UI;

-		case GL_R16I:                 return sw::FORMAT_R16I;

-		case GL_RG16I:                return sw::FORMAT_G16R16I;

-		case GL_RGB16I:               return sw::FORMAT_X16B16G16R16I;

-		case GL_RGBA16I:              return sw::FORMAT_A16B16G16R16I;

-		case GL_R16UI:                return sw::FORMAT_R16UI;

-		case GL_RG16UI:               return sw::FORMAT_G16R16UI;

-		case GL_RGB16UI:              return sw::FORMAT_X16B16G16R16UI;

-		case GL_RGB10_A2UI:

-		case GL_RGBA16UI:             return sw::FORMAT_A16B16G16R16UI;

-		case GL_R32I:                 return sw::FORMAT_R32I;

-		case GL_RG32I:                return sw::FORMAT_G32R32I;

-		case GL_RGB32I:               return sw::FORMAT_X32B32G32R32I;

-		case GL_RGBA32I:              return sw::FORMAT_A32B32G32R32I;

-		case GL_R32UI:                return sw::FORMAT_R32UI;

-		case GL_RG32UI:               return sw::FORMAT_G32R32UI;

-		case GL_RGB32UI:              return sw::FORMAT_X32B32G32R32UI;

-		case GL_RGBA32UI:             return sw::FORMAT_A32B32G32R32UI;

-		case GL_R16F:                 return sw::FORMAT_R16F;

-		case GL_RG16F:                return sw::FORMAT_G16R16F;

-		case GL_R11F_G11F_B10F:

-		case GL_RGB16F:               return sw::FORMAT_B16G16R16F;

-		case GL_RGBA16F:              return sw::FORMAT_A16B16G16R16F;

-		case GL_R32F:                 return sw::FORMAT_R32F;

-		case GL_RG32F:                return sw::FORMAT_G32R32F;

-		case GL_RGB32F:               return sw::FORMAT_B32G32R32F;

-		case GL_RGBA32F:              return sw::FORMAT_A32B32G32R32F;

-		case GL_RGB10_A2:             return sw::FORMAT_A2B10G10R10;

-		case GL_SRGB8:                return sw::FORMAT_SRGB8_X8;

-		case GL_SRGB8_ALPHA8:         return sw::FORMAT_SRGB8_A8;

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

-		}

-	}

-}

-

-namespace sw2es

-{

-	unsigned int GetStencilSize(sw::Format stencilFormat)

-	{

-		switch(stencilFormat)

-		{

-		case sw::FORMAT_D24FS8:

-		case sw::FORMAT_D24S8:

-		case sw::FORMAT_D32FS8_TEXTURE:

-		case sw::FORMAT_D32FS8_SHADOW:

-		case sw::FORMAT_S8:

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

-		case sw::FORMAT_A16B16G16R16I:

-		case sw::FORMAT_A16B16G16R16UI:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-		case sw::FORMAT_A32B32G32R32I:

-		case sw::FORMAT_A32B32G32R32UI:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 2;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-		case sw::FORMAT_SRGB8_A8:

-		case sw::FORMAT_A8B8G8R8I:

-		case sw::FORMAT_A8B8G8R8UI:

-		case sw::FORMAT_A8B8G8R8I_SNORM:

-			return 8;

-		case sw::FORMAT_A2B10G10R10:

-			return 2;

-		case sw::FORMAT_A1R5G5B5:

-			return 1;

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-		case sw::FORMAT_SRGB8_X8:

-		case sw::FORMAT_R5G6B5:

-			return 0;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetRedSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_R16F:

-		case sw::FORMAT_G16R16F:

-		case sw::FORMAT_B16G16R16F:

-		case sw::FORMAT_A16B16G16R16F:

-		case sw::FORMAT_R16I:

-		case sw::FORMAT_G16R16I:

-		case sw::FORMAT_X16B16G16R16I:

-		case sw::FORMAT_A16B16G16R16I:

-		case sw::FORMAT_R16UI:

-		case sw::FORMAT_G16R16UI:

-		case sw::FORMAT_X16B16G16R16UI:

-		case sw::FORMAT_A16B16G16R16UI:

-			return 16;

-		case sw::FORMAT_R32F:

-		case sw::FORMAT_G32R32F:

-		case sw::FORMAT_B32G32R32F:

-		case sw::FORMAT_X32B32G32R32F:

-		case sw::FORMAT_A32B32G32R32F:

-		case sw::FORMAT_R32I:

-		case sw::FORMAT_G32R32I:

-		case sw::FORMAT_X32B32G32R32I:

-		case sw::FORMAT_A32B32G32R32I:

-		case sw::FORMAT_R32UI:

-		case sw::FORMAT_G32R32UI:

-		case sw::FORMAT_X32B32G32R32UI:

-		case sw::FORMAT_A32B32G32R32UI:

-			return 32;

-		case sw::FORMAT_A2B10G10R10:

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-		case sw::FORMAT_SRGB8_A8:

-		case sw::FORMAT_SRGB8_X8:

-		case sw::FORMAT_R8:

-		case sw::FORMAT_G8R8:

-		case sw::FORMAT_R8I:

-		case sw::FORMAT_G8R8I:

-		case sw::FORMAT_X8B8G8R8I:

-		case sw::FORMAT_A8B8G8R8I:

-		case sw::FORMAT_R8UI:

-		case sw::FORMAT_G8R8UI:

-		case sw::FORMAT_X8B8G8R8UI:

-		case sw::FORMAT_A8B8G8R8UI:

-		case sw::FORMAT_R8I_SNORM:

-		case sw::FORMAT_G8R8I_SNORM:

-		case sw::FORMAT_X8B8G8R8I_SNORM:

-		case sw::FORMAT_A8B8G8R8I_SNORM:

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

-		case sw::FORMAT_B16G16R16F:

-		case sw::FORMAT_A16B16G16R16F:

-		case sw::FORMAT_G16R16I:

-		case sw::FORMAT_X16B16G16R16I:

-		case sw::FORMAT_A16B16G16R16I:

-		case sw::FORMAT_G16R16UI:

-		case sw::FORMAT_X16B16G16R16UI:

-		case sw::FORMAT_A16B16G16R16UI:

-			return 16;

-		case sw::FORMAT_G32R32F:

-		case sw::FORMAT_B32G32R32F:

-		case sw::FORMAT_X32B32G32R32F:

-		case sw::FORMAT_A32B32G32R32F:

-		case sw::FORMAT_G32R32I:

-		case sw::FORMAT_X32B32G32R32I:

-		case sw::FORMAT_A32B32G32R32I:

-		case sw::FORMAT_G32R32UI:

-		case sw::FORMAT_X32B32G32R32UI:

-		case sw::FORMAT_A32B32G32R32UI:

-			return 32;

-		case sw::FORMAT_A2B10G10R10:

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-		case sw::FORMAT_SRGB8_A8:

-		case sw::FORMAT_SRGB8_X8:

-		case sw::FORMAT_G8R8:

-		case sw::FORMAT_G8R8I:

-		case sw::FORMAT_X8B8G8R8I:

-		case sw::FORMAT_A8B8G8R8I:

-		case sw::FORMAT_G8R8UI:

-		case sw::FORMAT_X8B8G8R8UI:

-		case sw::FORMAT_A8B8G8R8UI:

-		case sw::FORMAT_G8R8I_SNORM:

-		case sw::FORMAT_X8B8G8R8I_SNORM:

-		case sw::FORMAT_A8B8G8R8I_SNORM:

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

-		case sw::FORMAT_A16B16G16R16F:

-		case sw::FORMAT_X16B16G16R16I:

-		case sw::FORMAT_A16B16G16R16I:

-		case sw::FORMAT_X16B16G16R16UI:

-		case sw::FORMAT_A16B16G16R16UI:

-			return 16;

-		case sw::FORMAT_B32G32R32F:

-		case sw::FORMAT_X32B32G32R32F:

-		case sw::FORMAT_A32B32G32R32F:

-		case sw::FORMAT_X32B32G32R32I:

-		case sw::FORMAT_A32B32G32R32I:

-		case sw::FORMAT_X32B32G32R32UI:

-		case sw::FORMAT_A32B32G32R32UI:

-			return 32;

-		case sw::FORMAT_A2B10G10R10:

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-		case sw::FORMAT_SRGB8_A8:

-		case sw::FORMAT_SRGB8_X8:

-		case sw::FORMAT_X8B8G8R8I:

-		case sw::FORMAT_A8B8G8R8I:

-		case sw::FORMAT_X8B8G8R8UI:

-		case sw::FORMAT_A8B8G8R8UI:

-		case sw::FORMAT_X8B8G8R8I_SNORM:

-		case sw::FORMAT_A8B8G8R8I_SNORM:

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

-		case sw::FORMAT_D16:            return 16;

-		case sw::FORMAT_D32F:

-		case sw::FORMAT_D32F_COMPLEMENTARY:

-		case sw::FORMAT_D32F_LOCKABLE:  return 32;

-		case sw::FORMAT_DF24S8:

-		case sw::FORMAT_D24FS8:         return 24;

-	//	case sw::FORMAT_D32_LOCKABLE:   return 32;

-	//	case sw::FORMAT_S8_LOCKABLE:    return 0;

-		case sw::FORMAT_D32FS8_SHADOW:

-		case sw::FORMAT_D32FS8_TEXTURE: return 32;

-		default:                        return 0;

-		}

-	}

-

-	GLenum GetComponentType(sw::Format format, GLenum attachment)

-	{

-		// Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0:

-		case GL_COLOR_ATTACHMENT1:

-		case GL_COLOR_ATTACHMENT2:

-		case GL_COLOR_ATTACHMENT3:

-		case GL_COLOR_ATTACHMENT4:

-		case GL_COLOR_ATTACHMENT5:

-		case GL_COLOR_ATTACHMENT6:

-		case GL_COLOR_ATTACHMENT7:

-		case GL_COLOR_ATTACHMENT8:

-		case GL_COLOR_ATTACHMENT9:

-		case GL_COLOR_ATTACHMENT10:

-		case GL_COLOR_ATTACHMENT11:

-		case GL_COLOR_ATTACHMENT12:

-		case GL_COLOR_ATTACHMENT13:

-		case GL_COLOR_ATTACHMENT14:

-		case GL_COLOR_ATTACHMENT15:

-		case GL_COLOR_ATTACHMENT16:

-		case GL_COLOR_ATTACHMENT17:

-		case GL_COLOR_ATTACHMENT18:

-		case GL_COLOR_ATTACHMENT19:

-		case GL_COLOR_ATTACHMENT20:

-		case GL_COLOR_ATTACHMENT21:

-		case GL_COLOR_ATTACHMENT22:

-		case GL_COLOR_ATTACHMENT23:

-		case GL_COLOR_ATTACHMENT24:

-		case GL_COLOR_ATTACHMENT25:

-		case GL_COLOR_ATTACHMENT26:

-		case GL_COLOR_ATTACHMENT27:

-		case GL_COLOR_ATTACHMENT28:

-		case GL_COLOR_ATTACHMENT29:

-		case GL_COLOR_ATTACHMENT30:

-		case GL_COLOR_ATTACHMENT31:

-			switch(format)

-			{

-			case sw::FORMAT_R8I:

-			case sw::FORMAT_G8R8I:

-			case sw::FORMAT_X8B8G8R8I:

-			case sw::FORMAT_A8B8G8R8I:

-			case sw::FORMAT_R16I:

-			case sw::FORMAT_G16R16I:

-			case sw::FORMAT_X16B16G16R16I:

-			case sw::FORMAT_A16B16G16R16I:

-			case sw::FORMAT_R32I:

-			case sw::FORMAT_G32R32I:

-			case sw::FORMAT_X32B32G32R32I:

-			case sw::FORMAT_A32B32G32R32I:

-				return GL_INT;

-			case sw::FORMAT_R8UI:

-			case sw::FORMAT_G8R8UI:

-			case sw::FORMAT_X8B8G8R8UI:

-			case sw::FORMAT_A8B8G8R8UI:

-			case sw::FORMAT_R16UI:

-			case sw::FORMAT_G16R16UI:

-			case sw::FORMAT_X16B16G16R16UI:

-			case sw::FORMAT_A16B16G16R16UI:

-			case sw::FORMAT_R32UI:

-			case sw::FORMAT_G32R32UI:

-			case sw::FORMAT_X32B32G32R32UI:

-			case sw::FORMAT_A32B32G32R32UI:

-				return GL_UNSIGNED_INT;

-			case sw::FORMAT_R16F:

-			case sw::FORMAT_G16R16F:

-			case sw::FORMAT_B16G16R16F:

-			case sw::FORMAT_A16B16G16R16F:

-			case sw::FORMAT_R32F:

-			case sw::FORMAT_G32R32F:

-			case sw::FORMAT_B32G32R32F:

-			case sw::FORMAT_X32B32G32R32F:

-			case sw::FORMAT_A32B32G32R32F:

-				return GL_FLOAT;

-			case sw::FORMAT_R8:

-			case sw::FORMAT_G8R8:

-			case sw::FORMAT_A2B10G10R10:

-			case sw::FORMAT_A2R10G10B10:

-			case sw::FORMAT_A8R8G8B8:

-			case sw::FORMAT_A8B8G8R8:

-			case sw::FORMAT_X8R8G8B8:

-			case sw::FORMAT_X8B8G8R8:

-			case sw::FORMAT_SRGB8_A8:

-			case sw::FORMAT_SRGB8_X8:

-			case sw::FORMAT_A1R5G5B5:

-			case sw::FORMAT_R5G6B5:

-				return GL_UNSIGNED_NORMALIZED;

-			case sw::FORMAT_R8I_SNORM:

-			case sw::FORMAT_X8B8G8R8I_SNORM:

-			case sw::FORMAT_A8B8G8R8I_SNORM:

-			case sw::FORMAT_G8R8I_SNORM:

-				return GL_SIGNED_NORMALIZED;

-			default:

-				UNREACHABLE(format);

-				return 0;

-			}

-		case GL_DEPTH_ATTACHMENT:

-		case GL_STENCIL_ATTACHMENT:

-			// Only color buffers may have integer components.

-			return GL_FLOAT;

-		default:

-			UNREACHABLE(attachment);

-			return 0;

-		}

-	}

-

-	GLenum ConvertBackBufferFormat(sw::Format format)

-	{

-		switch(format)

-		{

-		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;

-		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;

-		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;

-		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;

-		case sw::FORMAT_R5G6B5:   return GL_RGB565;

-		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;

-		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;

-		case sw::FORMAT_SRGB8_A8: return GL_RGBA8_OES;

-		case sw::FORMAT_SRGB8_X8: return GL_RGB8_OES;

-		default:

-			UNREACHABLE(format);

-		}

-

-		return GL_RGBA4;

-	}

-

-	GLenum ConvertDepthStencilFormat(sw::Format format)

-	{

-		switch(format)

-		{

-		case sw::FORMAT_D16:

-		case sw::FORMAT_D24X8:

-		case sw::FORMAT_D32:

-			return GL_DEPTH_COMPONENT16;

-		case sw::FORMAT_D24S8:

-			return GL_DEPTH24_STENCIL8_OES;

-		case sw::FORMAT_D32F:

-		case sw::FORMAT_D32F_COMPLEMENTARY:

-		case sw::FORMAT_D32F_LOCKABLE:

-			return GL_DEPTH_COMPONENT32F;

-		case sw::FORMAT_D32FS8_TEXTURE:

-		case sw::FORMAT_D32FS8_SHADOW:

-			return GL_DEPTH32F_STENCIL8;

-		case sw::FORMAT_S8:

-			return GL_STENCIL_INDEX8;

-		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 "main.h"
+#include "mathutil.h"
+#include "Context.h"
+#include "common/debug.h"
+
+#include <limits>
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace es2
+{
+	// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
+	// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
+	// format and type combinations.
+
+	typedef std::pair<GLenum, GLenum> FormatTypePair;
+	typedef std::pair<FormatTypePair, GLenum> FormatPair;
+	typedef std::map<FormatTypePair, GLenum> FormatMap;
+
+	// A helper function to insert data into the format map with fewer characters.
+	static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)
+	{
+		map->insert(FormatPair(FormatTypePair(format, type), internalFormat));
+	}
+
+	FormatMap BuildFormatMap()
+	{
+		static const GLenum GL_BGRA4_ANGLEX = 0x6ABC;
+		static const GLenum GL_BGR5_A1_ANGLEX = 0x6ABD;
+
+		FormatMap map;
+
+		//                       | Format | Type | Internal format |
+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
+		InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);
+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);
+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);
+		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);
+		InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);
+		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);
+		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);
+
+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);
+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);
+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);
+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);
+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);
+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);
+		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);
+
+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);
+		InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);
+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);
+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);
+		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);
+		InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);
+		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);
+		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);
+
+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);
+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);
+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);
+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);
+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);
+		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);
+
+		InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);
+		InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);
+		InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);
+		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);
+		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);
+
+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);
+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);
+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);
+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);
+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);
+		InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);
+
+		InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);
+		InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);
+		InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);
+		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);
+		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);
+
+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);
+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);
+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);
+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);
+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);
+		InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);
+
+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);
+		InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);
+		InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);
+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);
+		InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);
+		InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);
+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);
+		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);
+		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);
+		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);
+		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);
+		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);
+
+		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);
+		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);
+		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);
+
+		InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);
+		InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);
+
+		InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
+		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+
+		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);
+		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);
+		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);
+
+		InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);
+
+		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);
+		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);
+
+		return map;
+	}
+
+	GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
+	{
+		switch(internalFormat)
+		{
+		case GL_ALPHA:
+		case GL_LUMINANCE:
+		case GL_LUMINANCE_ALPHA:
+		case GL_RED:
+		case GL_RG:
+		case GL_RGB:
+		case GL_RGBA:
+		case GL_RED_INTEGER:
+		case GL_RG_INTEGER:
+		case GL_RGB_INTEGER:
+		case GL_RGBA_INTEGER:
+		case GL_BGRA_EXT:
+		case GL_DEPTH_COMPONENT:
+		case GL_DEPTH_STENCIL:
+		case GL_SRGB_EXT:
+		case GL_SRGB_ALPHA_EXT:
+			{
+				static const FormatMap formatMap = BuildFormatMap();
+				FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));
+				return (iter != formatMap.end()) ? iter->second : GL_NONE;
+			}
+		default:
+			return internalFormat;
+		}
+	}
+
+	unsigned int UniformComponentCount(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_BOOL:
+		case GL_FLOAT:
+		case GL_INT:
+		case GL_UNSIGNED_INT:
+		case GL_SAMPLER_2D:
+		case GL_SAMPLER_CUBE:
+		case GL_SAMPLER_EXTERNAL_OES:
+		case GL_SAMPLER_3D_OES:
+		case GL_SAMPLER_2D_ARRAY:
+		case GL_SAMPLER_2D_SHADOW:
+		case GL_SAMPLER_CUBE_SHADOW:
+		case GL_SAMPLER_2D_ARRAY_SHADOW:
+		case GL_INT_SAMPLER_2D:
+		case GL_UNSIGNED_INT_SAMPLER_2D:
+		case GL_INT_SAMPLER_CUBE:
+		case GL_UNSIGNED_INT_SAMPLER_CUBE:
+		case GL_INT_SAMPLER_3D:
+		case GL_UNSIGNED_INT_SAMPLER_3D:
+		case GL_INT_SAMPLER_2D_ARRAY:
+		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+			return 1;
+		case GL_BOOL_VEC2:
+		case GL_FLOAT_VEC2:
+		case GL_INT_VEC2:
+		case GL_UNSIGNED_INT_VEC2:
+			return 2;
+		case GL_INT_VEC3:
+		case GL_UNSIGNED_INT_VEC3:
+		case GL_FLOAT_VEC3:
+		case GL_BOOL_VEC3:
+			return 3;
+		case GL_BOOL_VEC4:
+		case GL_FLOAT_VEC4:
+		case GL_INT_VEC4:
+		case GL_UNSIGNED_INT_VEC4:
+		case GL_FLOAT_MAT2:
+			return 4;
+		case GL_FLOAT_MAT2x3:
+		case GL_FLOAT_MAT3x2:
+			return 6;
+		case GL_FLOAT_MAT2x4:
+		case GL_FLOAT_MAT4x2:
+			return 8;
+		case GL_FLOAT_MAT3:
+			return 9;
+		case GL_FLOAT_MAT3x4:
+		case GL_FLOAT_MAT4x3:
+			return 12;
+		case GL_FLOAT_MAT4:
+			return 16;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return 0;
+	}
+
+	GLenum UniformComponentType(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_BOOL:
+		case GL_BOOL_VEC2:
+		case GL_BOOL_VEC3:
+		case GL_BOOL_VEC4:
+			return GL_BOOL;
+		case GL_FLOAT:
+		case GL_FLOAT_VEC2:
+		case GL_FLOAT_VEC3:
+		case GL_FLOAT_VEC4:
+		case GL_FLOAT_MAT2:
+		case GL_FLOAT_MAT2x3:
+		case GL_FLOAT_MAT2x4:
+		case GL_FLOAT_MAT3:
+		case GL_FLOAT_MAT3x2:
+		case GL_FLOAT_MAT3x4:
+		case GL_FLOAT_MAT4:
+		case GL_FLOAT_MAT4x2:
+		case GL_FLOAT_MAT4x3:
+			return GL_FLOAT;
+		case GL_INT:
+		case GL_SAMPLER_2D:
+		case GL_SAMPLER_CUBE:
+		case GL_SAMPLER_EXTERNAL_OES:
+		case GL_SAMPLER_3D_OES:
+		case GL_SAMPLER_2D_ARRAY:
+		case GL_SAMPLER_2D_SHADOW:
+		case GL_SAMPLER_CUBE_SHADOW:
+		case GL_SAMPLER_2D_ARRAY_SHADOW:
+		case GL_INT_SAMPLER_2D:
+		case GL_UNSIGNED_INT_SAMPLER_2D:
+		case GL_INT_SAMPLER_CUBE:
+		case GL_UNSIGNED_INT_SAMPLER_CUBE:
+		case GL_INT_SAMPLER_3D:
+		case GL_UNSIGNED_INT_SAMPLER_3D:
+		case GL_INT_SAMPLER_2D_ARRAY:
+		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+		case GL_INT_VEC2:
+		case GL_INT_VEC3:
+		case GL_INT_VEC4:
+			return GL_INT;
+		case GL_UNSIGNED_INT:
+		case GL_UNSIGNED_INT_VEC2:
+		case GL_UNSIGNED_INT_VEC3:
+		case GL_UNSIGNED_INT_VEC4:
+			return GL_UNSIGNED_INT;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return GL_NONE;
+	}
+
+	size_t UniformTypeSize(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_BOOL:  return sizeof(GLboolean);
+		case GL_FLOAT: return sizeof(GLfloat);
+		case GL_INT:   return sizeof(GLint);
+		case GL_UNSIGNED_INT: return sizeof(GLuint);
+		}
+
+		return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
+	}
+
+	bool IsSamplerUniform(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_SAMPLER_2D:
+		case GL_SAMPLER_CUBE:
+		case GL_SAMPLER_EXTERNAL_OES:
+		case GL_SAMPLER_3D_OES:
+		case GL_SAMPLER_2D_ARRAY:
+		case GL_SAMPLER_2D_SHADOW:
+		case GL_SAMPLER_CUBE_SHADOW:
+		case GL_SAMPLER_2D_ARRAY_SHADOW:
+		case GL_INT_SAMPLER_2D:
+		case GL_UNSIGNED_INT_SAMPLER_2D:
+		case GL_INT_SAMPLER_CUBE:
+		case GL_UNSIGNED_INT_SAMPLER_CUBE:
+		case GL_INT_SAMPLER_3D:
+		case GL_UNSIGNED_INT_SAMPLER_3D:
+		case GL_INT_SAMPLER_2D_ARRAY:
+		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	int VariableRowCount(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_NONE:
+			return 0;
+		case GL_BOOL:
+		case GL_FLOAT:
+		case GL_INT:
+		case GL_UNSIGNED_INT:
+		case GL_BOOL_VEC2:
+		case GL_FLOAT_VEC2:
+		case GL_INT_VEC2:
+		case GL_UNSIGNED_INT_VEC2:
+		case GL_INT_VEC3:
+		case GL_UNSIGNED_INT_VEC3:
+		case GL_FLOAT_VEC3:
+		case GL_BOOL_VEC3:
+		case GL_BOOL_VEC4:
+		case GL_FLOAT_VEC4:
+		case GL_INT_VEC4:
+		case GL_UNSIGNED_INT_VEC4:
+		case GL_SAMPLER_2D:
+		case GL_SAMPLER_CUBE:
+		case GL_SAMPLER_EXTERNAL_OES:
+		case GL_SAMPLER_3D_OES:
+		case GL_SAMPLER_2D_ARRAY:
+		case GL_SAMPLER_2D_SHADOW:
+		case GL_SAMPLER_CUBE_SHADOW:
+		case GL_SAMPLER_2D_ARRAY_SHADOW:
+		case GL_INT_SAMPLER_2D:
+		case GL_UNSIGNED_INT_SAMPLER_2D:
+		case GL_INT_SAMPLER_CUBE:
+		case GL_UNSIGNED_INT_SAMPLER_CUBE:
+		case GL_INT_SAMPLER_3D:
+		case GL_UNSIGNED_INT_SAMPLER_3D:
+		case GL_INT_SAMPLER_2D_ARRAY:
+		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+			return 1;
+		case GL_FLOAT_MAT2:
+		case GL_FLOAT_MAT3x2:
+		case GL_FLOAT_MAT4x2:
+			return 2;
+		case GL_FLOAT_MAT3:
+		case GL_FLOAT_MAT2x3:
+		case GL_FLOAT_MAT4x3:
+			return 3;
+		case GL_FLOAT_MAT4:
+		case GL_FLOAT_MAT2x4:
+		case GL_FLOAT_MAT3x4:
+			return 4;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return 0;
+	}
+
+	int VariableColumnCount(GLenum type)
+	{
+		switch(type)
+		{
+		case GL_NONE:
+			return 0;
+		case GL_BOOL:
+		case GL_FLOAT:
+		case GL_INT:
+		case GL_UNSIGNED_INT:
+			return 1;
+		case GL_BOOL_VEC2:
+		case GL_FLOAT_VEC2:
+		case GL_INT_VEC2:
+		case GL_UNSIGNED_INT_VEC2:
+		case GL_FLOAT_MAT2:
+		case GL_FLOAT_MAT2x3:
+		case GL_FLOAT_MAT2x4:
+			return 2;
+		case GL_INT_VEC3:
+		case GL_UNSIGNED_INT_VEC3:
+		case GL_FLOAT_VEC3:
+		case GL_BOOL_VEC3:
+		case GL_FLOAT_MAT3:
+		case GL_FLOAT_MAT3x2:
+		case GL_FLOAT_MAT3x4:
+			return 3;
+		case GL_BOOL_VEC4:
+		case GL_FLOAT_VEC4:
+		case GL_INT_VEC4:
+		case GL_UNSIGNED_INT_VEC4:
+		case GL_FLOAT_MAT4:
+		case GL_FLOAT_MAT4x2:
+		case GL_FLOAT_MAT4x3:
+			return 4;
+		default:
+			UNREACHABLE(type);
+		}
+
+		return 0;
+	}
+
+	int VariableRegisterCount(GLenum type)
+	{
+		// Number of registers used is the number of columns for matrices or 1 for scalars and vectors
+		return (VariableRowCount(type) > 1) ? VariableColumnCount(type) : 1;
+	}
+
+	int VariableRegisterSize(GLenum type)
+	{
+		// Number of components per register is the number of rows for matrices or columns for scalars and vectors
+		int nbRows = VariableRowCount(type);
+		return (nbRows > 1) ? nbRows : VariableColumnCount(type);
+	}
+
+	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
+	{
+		ASSERT(allocationSize <= bitsSize);
+
+		unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
+
+		for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
+		{
+			if((*bits & mask) == 0)
+			{
+				*bits |= mask;
+				return i;
+			}
+
+			mask <<= 1;
+		}
+
+		return -1;
+	}
+
+	GLint floatToInt(GLfloat value)
+	{
+		return static_cast<GLint>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) * 0.5f);
+	}
+
+	bool IsCompressed(GLenum format, GLint clientVersion)
+	{
+		return ValidateCompressedFormat(format, clientVersion, true) == GL_NONE;
+	}
+
+	GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats)
+	{
+		switch(format)
+		{
+		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+			return S3TC_SUPPORT ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
+		case GL_ETC1_RGB8_OES:
+			return expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION;
+		case GL_COMPRESSED_R11_EAC:
+		case GL_COMPRESSED_SIGNED_R11_EAC:
+		case GL_COMPRESSED_RG11_EAC:
+		case GL_COMPRESSED_SIGNED_RG11_EAC:
+		case GL_COMPRESSED_RGB8_ETC2:
+		case GL_COMPRESSED_SRGB8_ETC2:
+		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+		case GL_COMPRESSED_RGBA8_ETC2_EAC:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+			return (clientVersion >= 3) ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
+		default:
+			return expectCompressedFormats ? GL_INVALID_ENUM : GL_NONE; // Not compressed format
+		}
+	}
+
+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
+	{
+		if(!texture)
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		if(compressed != texture->isCompressed(target, level))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		if(compressed)
+		{
+			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
+			   (height % 4 != 0 && height != texture->getHeight(target, 0)))
+			{
+				return GL_INVALID_OPERATION;
+			}
+		}
+
+		if(xoffset + width > texture->getWidth(target, level) ||
+		   yoffset + height > texture->getHeight(target, level))
+		{
+			return GL_INVALID_VALUE;
+		}
+
+		return GL_NONE;
+	}
+
+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
+	{
+		if(!texture)
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		if(compressed != texture->isCompressed(target, level))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		if(compressed)
+		{
+			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
+			   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
+			   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
+			{
+				return GL_INVALID_OPERATION;
+			}
+		}
+
+		if(xoffset + width > texture->getWidth(target, level) ||
+		   yoffset + height > texture->getHeight(target, level) ||
+		   zoffset + depth > texture->getDepth(target, level))
+		{
+			return GL_INVALID_VALUE;
+		}
+
+		return GL_NONE;
+	}
+
+	bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, GLint clientVersion)
+	{
+		switch(format)
+		{
+		case GL_RGBA:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:
+				break;
+			case GL_UNSIGNED_INT_2_10_10_10_REV:
+				return (clientVersion >= 3) && (internalFormat == GL_RGB10_A2);
+			case GL_FLOAT:
+				return (clientVersion >= 3) && (internalType == GL_FLOAT);
+			default:
+				return false;
+			}
+			break;
+		case GL_RGBA_INTEGER:
+			if(clientVersion < 3)
+			{
+				return false;
+			}
+			switch(type)
+			{
+			case GL_INT:
+				if(internalType != GL_INT)
+				{
+					return false;
+				}
+				break;
+			case GL_UNSIGNED_INT:
+				if(internalType != GL_UNSIGNED_INT)
+				{
+					return false;
+				}
+				break;
+			default:
+				return false;
+			}
+			break;
+		case GL_BGRA_EXT:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:
+			case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+			case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+				break;
+			default:
+				return false;
+			}
+			break;
+		case GL_RG_EXT:
+		case GL_RED_EXT:
+			return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE);
+		case GL_DEPTH_COMPONENT:
+			if(internalFormat != format)
+			{
+				return false;
+			}
+			switch(type)
+			{
+			case GL_UNSIGNED_SHORT:
+			case GL_FLOAT:
+				if(internalType != type)
+				{
+					return false;
+				}
+				break;
+			default:
+				return false;
+			}
+			break;
+		default:
+			return false;
+		}
+		return true;
+	}
+
+	bool IsDepthTexture(GLenum format)
+	{
+		return format == GL_DEPTH_COMPONENT ||
+		       format == GL_DEPTH_STENCIL_OES ||
+		       format == GL_DEPTH_COMPONENT16 ||
+		       format == GL_DEPTH_COMPONENT24 ||
+		       format == GL_DEPTH_COMPONENT32_OES ||
+		       format == GL_DEPTH_COMPONENT32F ||
+		       format == GL_DEPTH24_STENCIL8 ||
+		       format == GL_DEPTH32F_STENCIL8;
+	}
+
+	bool IsStencilTexture(GLenum format)
+	{
+		return format == GL_STENCIL_INDEX_OES ||
+		       format == GL_DEPTH_STENCIL_OES ||
+		       format == GL_DEPTH24_STENCIL8 ||
+		       format == GL_DEPTH32F_STENCIL8;
+	}
+
+	bool IsCubemapTextureTarget(GLenum target)
+	{
+		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+	}
+
+	int CubeFaceIndex(GLenum cubeFace)
+	{
+		switch(cubeFace)
+		{
+		case GL_TEXTURE_CUBE_MAP:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
+		default: UNREACHABLE(cubeFace); return 0;
+		}
+	}
+
+	bool IsTextureTarget(GLenum target)
+	{
+		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
+	}
+
+	bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)
+	{
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		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_FLOAT:               // GL_OES_texture_float
+		case GL_HALF_FLOAT_OES:      // GL_OES_texture_half_float
+		case GL_UNSIGNED_INT_24_8:   // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT)
+		case GL_UNSIGNED_SHORT:      // GL_OES_depth_texture
+		case GL_UNSIGNED_INT:        // GL_OES_depth_texture
+			break;
+		case GL_BYTE:
+		case GL_SHORT:
+		case GL_INT:
+		case GL_HALF_FLOAT:
+		case GL_UNSIGNED_INT_2_10_10_10_REV:
+		case GL_UNSIGNED_INT_10F_11F_11F_REV:
+		case GL_UNSIGNED_INT_5_9_9_9_REV:
+		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM, false);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+
+		switch(format)
+		{
+		case GL_ALPHA:
+		case GL_RGB:
+		case GL_RGBA:
+		case GL_LUMINANCE:
+		case GL_LUMINANCE_ALPHA:
+		case GL_BGRA_EXT:          // GL_EXT_texture_format_BGRA8888
+		case GL_DEPTH_STENCIL:     // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
+		case GL_DEPTH_COMPONENT:   // GL_OES_depth_texture
+			break;
+		case GL_RED:
+		case GL_RED_INTEGER:
+		case GL_RG:
+		case GL_RG_INTEGER:
+		case GL_RGB_INTEGER:
+		case GL_RGBA_INTEGER:
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_ENUM, false);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM, false);
+		}
+
+		if(internalformat != format)
+		{
+			if(clientVersion < 3)
+			{
+				return error(GL_INVALID_OPERATION, false);
+			}
+
+			switch(internalformat)
+			{
+			case GL_R8:
+			case GL_R8UI:
+			case GL_R8I:
+			case GL_R16UI:
+			case GL_R16I:
+			case GL_R32UI:
+			case GL_R32I:
+			case GL_RG8:
+			case GL_RG8UI:
+			case GL_RG8I:
+			case GL_RG16UI:
+			case GL_RG16I:
+			case GL_RG32UI:
+			case GL_RG32I:
+			case GL_SRGB8_ALPHA8:
+			case GL_RGB8UI:
+			case GL_RGB8I:
+			case GL_RGB16UI:
+			case GL_RGB16I:
+			case GL_RGB32UI:
+			case GL_RGB32I:
+			case GL_RG8_SNORM:
+			case GL_R8_SNORM:
+			case GL_RGB10_A2:
+			case GL_RGBA8UI:
+			case GL_RGBA8I:
+			case GL_RGB10_A2UI:
+			case GL_RGBA16UI:
+			case GL_RGBA16I:
+			case GL_RGBA32I:
+			case GL_RGBA32UI:
+			case GL_RGBA4:
+			case GL_RGB5_A1:
+			case GL_RGB565:
+			case GL_RGB8_OES:
+			case GL_RGBA8_OES:
+			case GL_R16F:
+			case GL_RG16F:
+			case GL_R11F_G11F_B10F:
+			case GL_RGB16F:
+			case GL_RGBA16F:
+			case GL_R32F:
+			case GL_RG32F:
+			case GL_RGB32F:
+			case GL_RGBA32F:
+			case GL_DEPTH_COMPONENT24:
+			case GL_DEPTH_COMPONENT32_OES:
+			case GL_DEPTH_COMPONENT32F:
+			case GL_DEPTH32F_STENCIL8:
+			case GL_DEPTH_COMPONENT16:
+			case GL_STENCIL_INDEX8:
+			case GL_DEPTH24_STENCIL8_OES:
+			case GL_RGBA8_SNORM:
+			case GL_SRGB8:
+			case GL_RGB8_SNORM:
+			case GL_RGB9_E5:
+				break;
+			default:
+				return error(GL_INVALID_ENUM, false);
+			}
+		}
+
+		// Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
+		bool validSizedInternalformat = false;
+		#define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
+
+		switch(format)
+		{
+		case GL_RGBA:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
+			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
+			case GL_HALF_FLOAT_OES:              break;
+			case GL_UNSIGNED_SHORT_4_4_4_4:      VALIDATE_INTERNALFORMAT(GL_RGBA4)
+			case GL_UNSIGNED_SHORT_5_5_5_1:      VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
+			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
+			case GL_HALF_FLOAT:                  VALIDATE_INTERNALFORMAT(GL_RGBA16F)
+			case GL_FLOAT:                       VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
+			default:                             return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_RGBA_INTEGER:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
+			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8I)
+			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
+			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGBA16I)
+			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
+			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGBA32I)
+			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
+			default:                             return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_RGB:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:                VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
+			case GL_BYTE:                         VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
+			case GL_HALF_FLOAT_OES:               break;
+			case GL_UNSIGNED_SHORT_5_6_5:         VALIDATE_INTERNALFORMAT(GL_RGB565)
+			case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
+			case GL_UNSIGNED_INT_5_9_9_9_REV:     VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
+			case GL_HALF_FLOAT:                   VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
+			case GL_FLOAT:                        VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
+			default:                              return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_RGB_INTEGER:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGB8UI)
+			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGB8I)
+			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGB16UI)
+			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGB16I)
+			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGB32UI)
+			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGB32I)
+			default:                             return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_RG:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)
+			case GL_BYTE:          VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
+			case GL_HALF_FLOAT:    VALIDATE_INTERNALFORMAT(GL_RG16F)
+			case GL_FLOAT:         VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
+			default:               return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_RG_INTEGER:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RG8UI)
+			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RG8I)
+			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)
+			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_RG16I)
+			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_RG32UI)
+			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_RG32I)
+			default:                return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_RED:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8)
+			case GL_BYTE:          VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
+			case GL_HALF_FLOAT:    VALIDATE_INTERNALFORMAT(GL_R16F)
+			case GL_FLOAT:         VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
+			default:               return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_RED_INTEGER:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_R8UI)
+			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_R8I)
+			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
+			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_R16I)
+			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_R32UI)
+			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_R32I)
+			default:                return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_DEPTH_COMPONENT:
+			switch(type)
+			{
+			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
+			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
+			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
+			default:                return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_DEPTH_STENCIL:
+			switch(type)
+			{
+			case GL_UNSIGNED_INT_24_8:              VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
+			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
+			default:                                return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_LUMINANCE_ALPHA:
+		case GL_LUMINANCE:
+		case GL_ALPHA:
+			switch(type)
+			{
+			case GL_UNSIGNED_BYTE:
+			case GL_HALF_FLOAT_OES:
+			case GL_FLOAT:
+				break;
+			default:
+				return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		case GL_BGRA_EXT:
+			if(type != GL_UNSIGNED_BYTE)
+			{
+				return error(GL_INVALID_OPERATION, false);
+			}
+			break;
+		default:
+			UNREACHABLE(format);
+			return error(GL_INVALID_ENUM, false);
+		}
+
+		#undef VALIDATE_INTERNALFORMAT
+
+		if(internalformat != format && !validSizedInternalformat)
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+
+		return true;
+	}
+
+	bool IsColorRenderable(GLenum internalformat, GLint clientVersion)
+	{
+		switch(internalformat)
+		{
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+		case GL_R16F:
+		case GL_RG16F:
+		case GL_RGB16F:
+		case GL_RGBA16F:
+		case GL_BGRA8_EXT:
+			return true;
+		case GL_R8:
+		case GL_R8UI:
+		case GL_R8I:
+		case GL_R16UI:
+		case GL_R16I:
+		case GL_R32UI:
+		case GL_R32I:
+		case GL_RG8:
+		case GL_RG8UI:
+		case GL_RG8I:
+		case GL_RG16UI:
+		case GL_RG16I:
+		case GL_RG32UI:
+		case GL_RG32I:
+		case GL_SRGB8_ALPHA8:
+		case GL_RGB10_A2:
+		case GL_RGBA8UI:
+		case GL_RGBA8I:
+		case GL_RGB10_A2UI:
+		case GL_RGBA16UI:
+		case GL_RGBA16I:
+		case GL_RGBA32I:
+		case GL_RGBA32UI:
+		case GL_R11F_G11F_B10F:
+		case GL_R32F:
+		case GL_RG32F:
+		case GL_RGB32F:
+		case GL_RGBA32F:
+			return clientVersion >= 3;
+		case GL_DEPTH_COMPONENT24:
+		case GL_DEPTH_COMPONENT32_OES:
+		case GL_DEPTH_COMPONENT32F:
+		case GL_DEPTH32F_STENCIL8:
+		case GL_DEPTH_COMPONENT16:
+		case GL_STENCIL_INDEX8:
+		case GL_DEPTH24_STENCIL8_OES:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsDepthRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT24:
+		case GL_DEPTH_COMPONENT32_OES:
+		case GL_DEPTH_COMPONENT32F:
+		case GL_DEPTH32F_STENCIL8:
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH24_STENCIL8_OES:
+			return true;
+		case GL_STENCIL_INDEX8:
+		case GL_R8:
+		case GL_R8UI:
+		case GL_R8I:
+		case GL_R16UI:
+		case GL_R16I:
+		case GL_R32UI:
+		case GL_R32I:
+		case GL_RG8:
+		case GL_RG8UI:
+		case GL_RG8I:
+		case GL_RG16UI:
+		case GL_RG16I:
+		case GL_RG32UI:
+		case GL_RG32I:
+		case GL_SRGB8_ALPHA8:
+		case GL_RGB10_A2:
+		case GL_RGBA8UI:
+		case GL_RGBA8I:
+		case GL_RGB10_A2UI:
+		case GL_RGBA16UI:
+		case GL_RGBA16I:
+		case GL_RGBA32I:
+		case GL_RGBA32UI:
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+		case GL_RGB:
+		case GL_RGBA:
+		case GL_R16F:
+		case GL_RG16F:
+		case GL_R11F_G11F_B10F:
+		case GL_RGB16F:
+		case GL_RGBA16F:
+		case GL_R32F:
+		case GL_RG32F:
+		case GL_RGB32F:
+		case GL_RGBA32F:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsStencilRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_DEPTH32F_STENCIL8:
+		case GL_STENCIL_INDEX8:
+		case GL_DEPTH24_STENCIL8_OES:
+			return true;
+		case GL_R8:
+		case GL_R8UI:
+		case GL_R8I:
+		case GL_R16UI:
+		case GL_R16I:
+		case GL_R32UI:
+		case GL_R32I:
+		case GL_RG8:
+		case GL_RG8UI:
+		case GL_RG8I:
+		case GL_RG16UI:
+		case GL_RG16I:
+		case GL_RG32UI:
+		case GL_RG32I:
+		case GL_SRGB8_ALPHA8:
+		case GL_RGB10_A2:
+		case GL_RGBA8UI:
+		case GL_RGBA8I:
+		case GL_RGB10_A2UI:
+		case GL_RGBA16UI:
+		case GL_RGBA16I:
+		case GL_RGBA32I:
+		case GL_RGBA32UI:
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB565:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+		case GL_RGB:
+		case GL_RGBA:
+		case GL_R16F:
+		case GL_RG16F:
+		case GL_R11F_G11F_B10F:
+		case GL_RGB16F:
+		case GL_RGBA16F:
+		case GL_R32F:
+		case GL_RG32F:
+		case GL_RGB32F:
+		case GL_RGBA32F:
+		case GL_DEPTH_COMPONENT16:
+		case GL_DEPTH_COMPONENT24:
+		case GL_DEPTH_COMPONENT32_OES:
+		case GL_DEPTH_COMPONENT32F:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	std::string ParseUniformName(const std::string &name, size_t *outSubscript)
+	{
+		// Strip any trailing array operator and retrieve the subscript
+		size_t open = name.find_last_of('[');
+		size_t close = name.find_last_of(']');
+		bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
+		if(!hasIndex)
+		{
+			if(outSubscript)
+			{
+				*outSubscript = GL_INVALID_INDEX;
+			}
+			return name;
+		}
+
+		if(outSubscript)
+		{
+			int index = atoi(name.substr(open + 1).c_str());
+			if(index >= 0)
+			{
+				*outSubscript = index;
+			}
+			else
+			{
+				*outSubscript = GL_INVALID_INDEX;
+			}
+		}
+
+		return name.substr(0, open);
+	}
+}
+
+namespace es2sw
+{
+	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::DEPTH_NEVER;
+		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
+		case GL_LESS:     return sw::DEPTH_LESS;
+		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
+		case GL_EQUAL:    return sw::DEPTH_EQUAL;
+		case GL_GREATER:  return sw::DEPTH_GREATER;
+		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::DEPTH_ALWAYS;
+	}
+
+	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::STENCIL_NEVER;
+		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
+		case GL_LESS:     return sw::STENCIL_LESS;
+		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
+		case GL_EQUAL:    return sw::STENCIL_EQUAL;
+		case GL_GREATER:  return sw::STENCIL_GREATER;
+		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::STENCIL_ALWAYS;
+	}
+
+	sw::Color<float> ConvertColor(es2::Color color)
+	{
+		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
+	}
+
+	sw::BlendFactor ConvertBlendFunc(GLenum blend)
+	{
+		switch(blend)
+		{
+		case GL_ZERO:                     return sw::BLEND_ZERO;
+		case GL_ONE:                      return sw::BLEND_ONE;
+		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
+		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
+		case GL_DST_COLOR:                return sw::BLEND_DEST;
+		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
+		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
+		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
+		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
+		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
+		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;
+		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
+		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;
+		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
+		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
+		default: UNREACHABLE(blend);
+		}
+
+		return sw::BLEND_ZERO;
+	}
+
+	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
+	{
+		switch(blendOp)
+		{
+		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;
+		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;
+		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
+		case GL_MIN_EXT:               return sw::BLENDOP_MIN;
+		case GL_MAX_EXT:               return sw::BLENDOP_MAX;
+		default: UNREACHABLE(blendOp);
+		}
+
+		return sw::BLENDOP_ADD;
+	}
+
+	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
+	{
+		switch(stencilOp)
+		{
+		case GL_ZERO:      return sw::OPERATION_ZERO;
+		case GL_KEEP:      return sw::OPERATION_KEEP;
+		case GL_REPLACE:   return sw::OPERATION_REPLACE;
+		case GL_INCR:      return sw::OPERATION_INCRSAT;
+		case GL_DECR:      return sw::OPERATION_DECRSAT;
+		case GL_INVERT:    return sw::OPERATION_INVERT;
+		case GL_INCR_WRAP: return sw::OPERATION_INCR;
+		case GL_DECR_WRAP: return sw::OPERATION_DECR;
+		default: UNREACHABLE(stencilOp);
+		}
+
+		return sw::OPERATION_KEEP;
+	}
+
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
+	{
+		switch(wrap)
+		{
+		case GL_REPEAT:            return sw::ADDRESSING_WRAP;
+		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;
+		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;
+		default: UNREACHABLE(wrap);
+		}
+
+		return sw::ADDRESSING_WRAP;
+	}
+
+	sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)
+	{
+		switch(swizzleType)
+		{
+		case GL_RED:   return sw::SWIZZLE_RED;
+		case GL_GREEN: return sw::SWIZZLE_GREEN;
+		case GL_BLUE:  return sw::SWIZZLE_BLUE;
+		case GL_ALPHA: return sw::SWIZZLE_ALPHA;
+		case GL_ZERO:  return sw::SWIZZLE_ZERO;
+		case GL_ONE:   return sw::SWIZZLE_ONE;
+		default: UNREACHABLE(swizzleType);
+		}
+
+		return sw::SWIZZLE_RED;
+	};
+
+	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:
+		case GL_RGB5_A1:
+		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;
+		case GL_RGB565:               return sw::FORMAT_R5G6B5;
+		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;
+		case GL_DEPTH_COMPONENT16:
+		case GL_STENCIL_INDEX8:
+		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
+		case GL_DEPTH_COMPONENT32_OES:return sw::FORMAT_D32;
+		case GL_R8:                   return sw::FORMAT_R8;
+		case GL_RG8:                  return sw::FORMAT_G8R8;
+		case GL_R8I:                  return sw::FORMAT_R8I;
+		case GL_RG8I:                 return sw::FORMAT_G8R8I;
+		case GL_RGB8I:                return sw::FORMAT_X8B8G8R8I;
+		case GL_RGBA8I:               return sw::FORMAT_A8B8G8R8I;
+		case GL_R8UI:                 return sw::FORMAT_R8UI;
+		case GL_RG8UI:                return sw::FORMAT_G8R8UI;
+		case GL_RGB8UI:               return sw::FORMAT_X8B8G8R8UI;
+		case GL_RGBA8UI:              return sw::FORMAT_A8B8G8R8UI;
+		case GL_R16I:                 return sw::FORMAT_R16I;
+		case GL_RG16I:                return sw::FORMAT_G16R16I;
+		case GL_RGB16I:               return sw::FORMAT_X16B16G16R16I;
+		case GL_RGBA16I:              return sw::FORMAT_A16B16G16R16I;
+		case GL_R16UI:                return sw::FORMAT_R16UI;
+		case GL_RG16UI:               return sw::FORMAT_G16R16UI;
+		case GL_RGB16UI:              return sw::FORMAT_X16B16G16R16UI;
+		case GL_RGB10_A2UI:
+		case GL_RGBA16UI:             return sw::FORMAT_A16B16G16R16UI;
+		case GL_R32I:                 return sw::FORMAT_R32I;
+		case GL_RG32I:                return sw::FORMAT_G32R32I;
+		case GL_RGB32I:               return sw::FORMAT_X32B32G32R32I;
+		case GL_RGBA32I:              return sw::FORMAT_A32B32G32R32I;
+		case GL_R32UI:                return sw::FORMAT_R32UI;
+		case GL_RG32UI:               return sw::FORMAT_G32R32UI;
+		case GL_RGB32UI:              return sw::FORMAT_X32B32G32R32UI;
+		case GL_RGBA32UI:             return sw::FORMAT_A32B32G32R32UI;
+		case GL_R16F:                 return sw::FORMAT_R16F;
+		case GL_RG16F:                return sw::FORMAT_G16R16F;
+		case GL_R11F_G11F_B10F:
+		case GL_RGB16F:               return sw::FORMAT_B16G16R16F;
+		case GL_RGBA16F:              return sw::FORMAT_A16B16G16R16F;
+		case GL_R32F:                 return sw::FORMAT_R32F;
+		case GL_RG32F:                return sw::FORMAT_G32R32F;
+		case GL_RGB32F:               return sw::FORMAT_B32G32R32F;
+		case GL_RGBA32F:              return sw::FORMAT_A32B32G32R32F;
+		case GL_RGB10_A2:             return sw::FORMAT_A2B10G10R10;
+		case GL_SRGB8:                return sw::FORMAT_SRGB8_X8;
+		case GL_SRGB8_ALPHA8:         return sw::FORMAT_SRGB8_A8;
+		default: UNREACHABLE(format); return sw::FORMAT_NULL;
+		}
+	}
+}
+
+namespace sw2es
+{
+	unsigned int GetStencilSize(sw::Format stencilFormat)
+	{
+		switch(stencilFormat)
+		{
+		case sw::FORMAT_D24FS8:
+		case sw::FORMAT_D24S8:
+		case sw::FORMAT_D32FS8_TEXTURE:
+		case sw::FORMAT_D32FS8_SHADOW:
+		case sw::FORMAT_S8:
+			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:
+		case sw::FORMAT_A16B16G16R16I:
+		case sw::FORMAT_A16B16G16R16UI:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+		case sw::FORMAT_A32B32G32R32I:
+		case sw::FORMAT_A32B32G32R32UI:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 2;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+		case sw::FORMAT_SRGB8_A8:
+		case sw::FORMAT_A8B8G8R8I:
+		case sw::FORMAT_A8B8G8R8UI:
+		case sw::FORMAT_A8B8G8R8I_SNORM:
+			return 8;
+		case sw::FORMAT_A2B10G10R10:
+			return 2;
+		case sw::FORMAT_A1R5G5B5:
+			return 1;
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+		case sw::FORMAT_SRGB8_X8:
+		case sw::FORMAT_R5G6B5:
+			return 0;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetRedSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_R16F:
+		case sw::FORMAT_G16R16F:
+		case sw::FORMAT_B16G16R16F:
+		case sw::FORMAT_A16B16G16R16F:
+		case sw::FORMAT_R16I:
+		case sw::FORMAT_G16R16I:
+		case sw::FORMAT_X16B16G16R16I:
+		case sw::FORMAT_A16B16G16R16I:
+		case sw::FORMAT_R16UI:
+		case sw::FORMAT_G16R16UI:
+		case sw::FORMAT_X16B16G16R16UI:
+		case sw::FORMAT_A16B16G16R16UI:
+			return 16;
+		case sw::FORMAT_R32F:
+		case sw::FORMAT_G32R32F:
+		case sw::FORMAT_B32G32R32F:
+		case sw::FORMAT_X32B32G32R32F:
+		case sw::FORMAT_A32B32G32R32F:
+		case sw::FORMAT_R32I:
+		case sw::FORMAT_G32R32I:
+		case sw::FORMAT_X32B32G32R32I:
+		case sw::FORMAT_A32B32G32R32I:
+		case sw::FORMAT_R32UI:
+		case sw::FORMAT_G32R32UI:
+		case sw::FORMAT_X32B32G32R32UI:
+		case sw::FORMAT_A32B32G32R32UI:
+			return 32;
+		case sw::FORMAT_A2B10G10R10:
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+		case sw::FORMAT_SRGB8_A8:
+		case sw::FORMAT_SRGB8_X8:
+		case sw::FORMAT_R8:
+		case sw::FORMAT_G8R8:
+		case sw::FORMAT_R8I:
+		case sw::FORMAT_G8R8I:
+		case sw::FORMAT_X8B8G8R8I:
+		case sw::FORMAT_A8B8G8R8I:
+		case sw::FORMAT_R8UI:
+		case sw::FORMAT_G8R8UI:
+		case sw::FORMAT_X8B8G8R8UI:
+		case sw::FORMAT_A8B8G8R8UI:
+		case sw::FORMAT_R8I_SNORM:
+		case sw::FORMAT_G8R8I_SNORM:
+		case sw::FORMAT_X8B8G8R8I_SNORM:
+		case sw::FORMAT_A8B8G8R8I_SNORM:
+			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_G16R16F:
+		case sw::FORMAT_B16G16R16F:
+		case sw::FORMAT_A16B16G16R16F:
+		case sw::FORMAT_G16R16I:
+		case sw::FORMAT_X16B16G16R16I:
+		case sw::FORMAT_A16B16G16R16I:
+		case sw::FORMAT_G16R16UI:
+		case sw::FORMAT_X16B16G16R16UI:
+		case sw::FORMAT_A16B16G16R16UI:
+			return 16;
+		case sw::FORMAT_G32R32F:
+		case sw::FORMAT_B32G32R32F:
+		case sw::FORMAT_X32B32G32R32F:
+		case sw::FORMAT_A32B32G32R32F:
+		case sw::FORMAT_G32R32I:
+		case sw::FORMAT_X32B32G32R32I:
+		case sw::FORMAT_A32B32G32R32I:
+		case sw::FORMAT_G32R32UI:
+		case sw::FORMAT_X32B32G32R32UI:
+		case sw::FORMAT_A32B32G32R32UI:
+			return 32;
+		case sw::FORMAT_A2B10G10R10:
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+		case sw::FORMAT_SRGB8_A8:
+		case sw::FORMAT_SRGB8_X8:
+		case sw::FORMAT_G8R8:
+		case sw::FORMAT_G8R8I:
+		case sw::FORMAT_X8B8G8R8I:
+		case sw::FORMAT_A8B8G8R8I:
+		case sw::FORMAT_G8R8UI:
+		case sw::FORMAT_X8B8G8R8UI:
+		case sw::FORMAT_A8B8G8R8UI:
+		case sw::FORMAT_G8R8I_SNORM:
+		case sw::FORMAT_X8B8G8R8I_SNORM:
+		case sw::FORMAT_A8B8G8R8I_SNORM:
+			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_B16G16R16F:
+		case sw::FORMAT_A16B16G16R16F:
+		case sw::FORMAT_X16B16G16R16I:
+		case sw::FORMAT_A16B16G16R16I:
+		case sw::FORMAT_X16B16G16R16UI:
+		case sw::FORMAT_A16B16G16R16UI:
+			return 16;
+		case sw::FORMAT_B32G32R32F:
+		case sw::FORMAT_X32B32G32R32F:
+		case sw::FORMAT_A32B32G32R32F:
+		case sw::FORMAT_X32B32G32R32I:
+		case sw::FORMAT_A32B32G32R32I:
+		case sw::FORMAT_X32B32G32R32UI:
+		case sw::FORMAT_A32B32G32R32UI:
+			return 32;
+		case sw::FORMAT_A2B10G10R10:
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+		case sw::FORMAT_SRGB8_A8:
+		case sw::FORMAT_SRGB8_X8:
+		case sw::FORMAT_X8B8G8R8I:
+		case sw::FORMAT_A8B8G8R8I:
+		case sw::FORMAT_X8B8G8R8UI:
+		case sw::FORMAT_A8B8G8R8UI:
+		case sw::FORMAT_X8B8G8R8I_SNORM:
+		case sw::FORMAT_A8B8G8R8I_SNORM:
+			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_DF16S8:
+		case sw::FORMAT_D16:            return 16;
+		case sw::FORMAT_D32F:
+		case sw::FORMAT_D32F_COMPLEMENTARY:
+		case sw::FORMAT_D32F_LOCKABLE:  return 32;
+		case sw::FORMAT_DF24S8:
+		case sw::FORMAT_D24FS8:         return 24;
+	//	case sw::FORMAT_D32_LOCKABLE:   return 32;
+	//	case sw::FORMAT_S8_LOCKABLE:    return 0;
+		case sw::FORMAT_D32FS8_SHADOW:
+		case sw::FORMAT_D32FS8_TEXTURE: return 32;
+		default:                        return 0;
+		}
+	}
+
+	GLenum GetComponentType(sw::Format format, GLenum attachment)
+	{
+		// Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0:
+		case GL_COLOR_ATTACHMENT1:
+		case GL_COLOR_ATTACHMENT2:
+		case GL_COLOR_ATTACHMENT3:
+		case GL_COLOR_ATTACHMENT4:
+		case GL_COLOR_ATTACHMENT5:
+		case GL_COLOR_ATTACHMENT6:
+		case GL_COLOR_ATTACHMENT7:
+		case GL_COLOR_ATTACHMENT8:
+		case GL_COLOR_ATTACHMENT9:
+		case GL_COLOR_ATTACHMENT10:
+		case GL_COLOR_ATTACHMENT11:
+		case GL_COLOR_ATTACHMENT12:
+		case GL_COLOR_ATTACHMENT13:
+		case GL_COLOR_ATTACHMENT14:
+		case GL_COLOR_ATTACHMENT15:
+		case GL_COLOR_ATTACHMENT16:
+		case GL_COLOR_ATTACHMENT17:
+		case GL_COLOR_ATTACHMENT18:
+		case GL_COLOR_ATTACHMENT19:
+		case GL_COLOR_ATTACHMENT20:
+		case GL_COLOR_ATTACHMENT21:
+		case GL_COLOR_ATTACHMENT22:
+		case GL_COLOR_ATTACHMENT23:
+		case GL_COLOR_ATTACHMENT24:
+		case GL_COLOR_ATTACHMENT25:
+		case GL_COLOR_ATTACHMENT26:
+		case GL_COLOR_ATTACHMENT27:
+		case GL_COLOR_ATTACHMENT28:
+		case GL_COLOR_ATTACHMENT29:
+		case GL_COLOR_ATTACHMENT30:
+		case GL_COLOR_ATTACHMENT31:
+			switch(format)
+			{
+			case sw::FORMAT_R8I:
+			case sw::FORMAT_G8R8I:
+			case sw::FORMAT_X8B8G8R8I:
+			case sw::FORMAT_A8B8G8R8I:
+			case sw::FORMAT_R16I:
+			case sw::FORMAT_G16R16I:
+			case sw::FORMAT_X16B16G16R16I:
+			case sw::FORMAT_A16B16G16R16I:
+			case sw::FORMAT_R32I:
+			case sw::FORMAT_G32R32I:
+			case sw::FORMAT_X32B32G32R32I:
+			case sw::FORMAT_A32B32G32R32I:
+				return GL_INT;
+			case sw::FORMAT_R8UI:
+			case sw::FORMAT_G8R8UI:
+			case sw::FORMAT_X8B8G8R8UI:
+			case sw::FORMAT_A8B8G8R8UI:
+			case sw::FORMAT_R16UI:
+			case sw::FORMAT_G16R16UI:
+			case sw::FORMAT_X16B16G16R16UI:
+			case sw::FORMAT_A16B16G16R16UI:
+			case sw::FORMAT_R32UI:
+			case sw::FORMAT_G32R32UI:
+			case sw::FORMAT_X32B32G32R32UI:
+			case sw::FORMAT_A32B32G32R32UI:
+				return GL_UNSIGNED_INT;
+			case sw::FORMAT_R16F:
+			case sw::FORMAT_G16R16F:
+			case sw::FORMAT_B16G16R16F:
+			case sw::FORMAT_A16B16G16R16F:
+			case sw::FORMAT_R32F:
+			case sw::FORMAT_G32R32F:
+			case sw::FORMAT_B32G32R32F:
+			case sw::FORMAT_X32B32G32R32F:
+			case sw::FORMAT_A32B32G32R32F:
+				return GL_FLOAT;
+			case sw::FORMAT_R8:
+			case sw::FORMAT_G8R8:
+			case sw::FORMAT_A2B10G10R10:
+			case sw::FORMAT_A2R10G10B10:
+			case sw::FORMAT_A8R8G8B8:
+			case sw::FORMAT_A8B8G8R8:
+			case sw::FORMAT_X8R8G8B8:
+			case sw::FORMAT_X8B8G8R8:
+			case sw::FORMAT_SRGB8_A8:
+			case sw::FORMAT_SRGB8_X8:
+			case sw::FORMAT_A1R5G5B5:
+			case sw::FORMAT_R5G6B5:
+				return GL_UNSIGNED_NORMALIZED;
+			case sw::FORMAT_R8I_SNORM:
+			case sw::FORMAT_X8B8G8R8I_SNORM:
+			case sw::FORMAT_A8B8G8R8I_SNORM:
+			case sw::FORMAT_G8R8I_SNORM:
+				return GL_SIGNED_NORMALIZED;
+			default:
+				UNREACHABLE(format);
+				return 0;
+			}
+		case GL_DEPTH_ATTACHMENT:
+		case GL_STENCIL_ATTACHMENT:
+			// Only color buffers may have integer components.
+			return GL_FLOAT;
+		default:
+			UNREACHABLE(attachment);
+			return 0;
+		}
+	}
+
+	GLenum ConvertBackBufferFormat(sw::Format format)
+	{
+		switch(format)
+		{
+		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
+		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;
+		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;
+		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
+		case sw::FORMAT_R5G6B5:   return GL_RGB565;
+		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;
+		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;
+		case sw::FORMAT_SRGB8_A8: return GL_RGBA8_OES;
+		case sw::FORMAT_SRGB8_X8: return GL_RGB8_OES;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_RGBA4;
+	}
+
+	GLenum ConvertDepthStencilFormat(sw::Format format)
+	{
+		switch(format)
+		{
+		case sw::FORMAT_D16:
+		case sw::FORMAT_D24X8:
+		case sw::FORMAT_D32:
+			return GL_DEPTH_COMPONENT16;
+		case sw::FORMAT_D24S8:
+			return GL_DEPTH24_STENCIL8_OES;
+		case sw::FORMAT_D32F:
+		case sw::FORMAT_D32F_COMPLEMENTARY:
+		case sw::FORMAT_D32F_LOCKABLE:
+			return GL_DEPTH_COMPONENT32F;
+		case sw::FORMAT_D32FS8_TEXTURE:
+		case sw::FORMAT_D32FS8_SHADOW:
+			return GL_DEPTH32F_STENCIL8;
+		case sw::FORMAT_S8:
+			return GL_STENCIL_INDEX8;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_DEPTH24_STENCIL8_OES;
+	}
+}
diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h
index 1d797ee..2aa983c 100644
--- a/src/OpenGL/libGLESv2/utilities.h
+++ b/src/OpenGL/libGLESv2/utilities.h
@@ -1,98 +1,101 @@
-// 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.h: Conversion functions and other utility routines.

-

-#ifndef LIBGLESV2_UTILITIES_H

-#define LIBGLESV2_UTILITIES_H

-

-#include "Device.hpp"

-#include "common/Image.hpp"

-#include "Texture.h"

-

-#include <GLES2/gl2.h>

-#include <GLES2/gl2ext.h>

-

-#include <string>

-

-namespace es2

-{

-	struct Color;

-

-	unsigned int UniformComponentCount(GLenum type);

-	GLenum UniformComponentType(GLenum type);

-	size_t UniformTypeSize(GLenum type);

-	bool IsSamplerUniform(GLenum type);

-	int VariableRowCount(GLenum type);

-	int VariableColumnCount(GLenum type);

-	int VariableRegisterCount(GLenum type);

-	int VariableRegisterSize(GLenum type);

-

-	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);

-

-	GLint floatToInt(GLfloat value);

-

-	bool IsCompressed(GLenum format, GLint clientVersion);

-	GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);

-	GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats);

-	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);

-	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);

-	bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, GLint clientVersion);

-	bool IsDepthTexture(GLenum format);

-	bool IsStencilTexture(GLenum format);

-	bool IsCubemapTextureTarget(GLenum target);

-	int CubeFaceIndex(GLenum cubeTarget);

-	bool IsTextureTarget(GLenum target);

-	bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion);

-

-	bool IsColorRenderable(GLenum internalformat, GLint clientVersion);

-	bool IsDepthRenderable(GLenum internalformat);

-	bool IsStencilRenderable(GLenum internalformat);

-

-	// Parse the base uniform name and array index.  Returns the base name of the uniform. outSubscript is

-	// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid.

-	std::string ParseUniformName(const std::string &name, size_t *outSubscript);

-}

-

-namespace es2sw

-{

-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);

-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);

-	sw::Color<float> ConvertColor(es2::Color color);

-	sw::BlendFactor ConvertBlendFunc(GLenum blend);

-	sw::BlendOperation ConvertBlendOp(GLenum blendOp);

-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);

-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap);

-	sw::SwizzleType ConvertSwizzleType(GLenum swizzleType);

-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);

-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);

-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);

-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);

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

-	sw::Format ConvertRenderbufferFormat(GLenum format);

-}

-

-namespace sw2es

-{

-	GLuint GetAlphaSize(sw::Format colorFormat);

-	GLuint GetRedSize(sw::Format colorFormat);

-	GLuint GetGreenSize(sw::Format colorFormat);

-	GLuint GetBlueSize(sw::Format colorFormat);

-	GLuint GetDepthSize(sw::Format depthFormat);

-	GLuint GetStencilSize(sw::Format stencilFormat);

-	GLenum GetComponentType(sw::Format format, GLenum attachment);

-

-	GLenum ConvertBackBufferFormat(sw::Format format);

-	GLenum ConvertDepthStencilFormat(sw::Format format);

-}

-

-#endif  // LIBGLESV2_UTILITIES_H

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// utilities.h: Conversion functions and other utility routines.
+
+#ifndef LIBGLESV2_UTILITIES_H
+#define LIBGLESV2_UTILITIES_H
+
+#include "Device.hpp"
+#include "common/Image.hpp"
+#include "Texture.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <string>
+
+namespace es2
+{
+	struct Color;
+
+	unsigned int UniformComponentCount(GLenum type);
+	GLenum UniformComponentType(GLenum type);
+	size_t UniformTypeSize(GLenum type);
+	bool IsSamplerUniform(GLenum type);
+	int VariableRowCount(GLenum type);
+	int VariableColumnCount(GLenum type);
+	int VariableRegisterCount(GLenum type);
+	int VariableRegisterSize(GLenum type);
+
+	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
+
+	GLint floatToInt(GLfloat value);
+
+	bool IsCompressed(GLenum format, GLint clientVersion);
+	GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
+	GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats);
+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);
+	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);
+	bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, GLint clientVersion);
+	bool IsDepthTexture(GLenum format);
+	bool IsStencilTexture(GLenum format);
+	bool IsCubemapTextureTarget(GLenum target);
+	int CubeFaceIndex(GLenum cubeTarget);
+	bool IsTextureTarget(GLenum target);
+	bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion);
+
+	bool IsColorRenderable(GLenum internalformat, GLint clientVersion);
+	bool IsDepthRenderable(GLenum internalformat);
+	bool IsStencilRenderable(GLenum internalformat);
+
+	// Parse the base uniform name and array index.  Returns the base name of the uniform. outSubscript is
+	// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid.
+	std::string ParseUniformName(const std::string &name, size_t *outSubscript);
+}
+
+namespace es2sw
+{
+	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);
+	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);
+	sw::Color<float> ConvertColor(es2::Color color);
+	sw::BlendFactor ConvertBlendFunc(GLenum blend);
+	sw::BlendOperation ConvertBlendOp(GLenum blendOp);
+	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
+	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap);
+	sw::SwizzleType ConvertSwizzleType(GLenum swizzleType);
+	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
+	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);
+	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
+	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
+	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount);
+	sw::Format ConvertRenderbufferFormat(GLenum format);
+}
+
+namespace sw2es
+{
+	GLuint GetAlphaSize(sw::Format colorFormat);
+	GLuint GetRedSize(sw::Format colorFormat);
+	GLuint GetGreenSize(sw::Format colorFormat);
+	GLuint GetBlueSize(sw::Format colorFormat);
+	GLuint GetDepthSize(sw::Format depthFormat);
+	GLuint GetStencilSize(sw::Format stencilFormat);
+	GLenum GetComponentType(sw::Format format, GLenum attachment);
+
+	GLenum ConvertBackBufferFormat(sw::Format format);
+	GLenum ConvertDepthStencilFormat(sw::Format format);
+}
+
+#endif  // LIBGLESV2_UTILITIES_H
diff --git a/src/Reactor/DLL.cpp b/src/Reactor/DLL.cpp
index 8856d72..da3af6b 100644
--- a/src/Reactor/DLL.cpp
+++ b/src/Reactor/DLL.cpp
@@ -1,378 +1,381 @@
-// 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 "Dll.hpp"

-

-#include <time.h>

-

-#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE

-#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040

-#endif

-

-#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT

-#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100

-#endif

-

-namespace sw

-{

-	#ifdef _M_AMD64

-		const bool AMD64 = true;

-	#else

-		const bool AMD64 = false;

-	#endif

-

-	DLL::DLL(const char *name, const void *constants, int constSize) : constants(constants), constSize(constSize)

-	{

-		dllName = new char[strlen(name) + 1];

-		strcpy(dllName, name);

-

-		codeSize = 0;

-	}

-

-	DLL::~DLL()

-	{

-		delete[] dllName;

-

-		for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)

-		{

-			delete i->second;

-		}

-	}

-

-	void DLL::addFunction(const void *function, const void *entry, int size)

-	{

-		functionOrder.push_back(function);

-		functionList[function] = new Function(codeSize, function, entry, size);

-

-		codeSize += size;

-	}

-

-	void DLL::addRelocation(const void *function, const void *address, bool ripRelative)

-	{

-		globalRelocations[function].push_back(Relocation((unsigned int)((unsigned char*)address - (unsigned char*)function), ripRelative));

-	}

-

-	void DLL::emit()

-	{

-		if(codeSize == 0)

-		{

-			return;

-		}

-

-		for(GlobalRelocations::iterator i = globalRelocations.begin(); i != globalRelocations.end(); i++)

-		{

-			const unsigned char *function = (const unsigned char*)i->first;

-			const std::vector<Relocation> &functionRelocations = i->second;

-			unsigned int location = functionList[function]->location;

-

-			for(unsigned int j = 0; j < functionRelocations.size(); j++)

-			{

-				unsigned int address = location + functionRelocations[j].offset;

-				unsigned int page = address / 0x1000;

-				unsigned short reloc = address - page * 0x1000;

-

-				unsigned int relocType = AMD64 ? IMAGE_REL_BASED_DIR64 : IMAGE_REL_BASED_HIGHLOW;

-				pageRelocations[page].push_back((relocType << 12) | reloc);

-			}

-		}

-

-		if(pageRelocations.empty())

-		{

-			pageRelocations[0];   // Initialize an emtpy list

-		}

-

-		int relocSize = 0;

-

-		for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)

-		{

-			if(i->second.size() % 2)   // Pad to align to DWORD

-			{

-				i->second.push_back(0);

-			}

-

-			relocSize += (int)sizeof(IMAGE_BASE_RELOCATION) + (int)i->second.size() * (int)sizeof(unsigned short);

-		}

-

-		unsigned long timeDateStamp = (unsigned long)time(0);

-

-		memset(&DOSheader, 0, sizeof(DOSheader));

-		DOSheader.e_magic = IMAGE_DOS_SIGNATURE;   // "MZ"

-		DOSheader.e_lfanew = sizeof(DOSheader);

-

-		int base = 0x10000000;

-		int codePage = pageAlign(sizeof(DOSheader) + (AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32)));

-		int exportsPage = codePage + pageAlign(codeSize);

-		int exportsSize = (int)(sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*) + (strlen(dllName) + 1));

-		int relocPage = exportsPage + pageAlign(exportsSize);

-		int constPage = relocPage + pageAlign(relocSize);

-

-		if(!AMD64)

-		{

-			memset(&COFFheader32, 0, sizeof(COFFheader32));

-			COFFheader32.Signature = IMAGE_NT_SIGNATURE;   // "PE"

-			COFFheader32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386;

-			COFFheader32.FileHeader.NumberOfSections = 4;

-			COFFheader32.FileHeader.TimeDateStamp = timeDateStamp;

-			COFFheader32.FileHeader.PointerToSymbolTable = 0;   // Deprecated COFF symbol table

-			COFFheader32.FileHeader.NumberOfSymbols = 0;

-			COFFheader32.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32);

-			COFFheader32.FileHeader.Characteristics =	IMAGE_FILE_EXECUTABLE_IMAGE |

-														IMAGE_FILE_32BIT_MACHINE |

-														IMAGE_FILE_DLL;

-

-			COFFheader32.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;

-			COFFheader32.OptionalHeader.MajorLinkerVersion = 8;

-			COFFheader32.OptionalHeader.MinorLinkerVersion = 0;

-			COFFheader32.OptionalHeader.SizeOfCode = fileAlign(codeSize);

-			COFFheader32.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);

-			COFFheader32.OptionalHeader.SizeOfUninitializedData = 0;

-			COFFheader32.OptionalHeader.AddressOfEntryPoint = 0;

-			COFFheader32.OptionalHeader.BaseOfCode = codePage;

-			COFFheader32.OptionalHeader.BaseOfData = exportsPage;

-

-			COFFheader32.OptionalHeader.ImageBase = base;

-			COFFheader32.OptionalHeader.SectionAlignment = 0x1000;

-			COFFheader32.OptionalHeader.FileAlignment = 0x200;

-			COFFheader32.OptionalHeader.MajorOperatingSystemVersion = 4;

-			COFFheader32.OptionalHeader.MinorOperatingSystemVersion = 0;

-			COFFheader32.OptionalHeader.MajorImageVersion = 0;

-			COFFheader32.OptionalHeader.MinorImageVersion = 0;

-			COFFheader32.OptionalHeader.MajorSubsystemVersion = 4;

-			COFFheader32.OptionalHeader.MinorSubsystemVersion = 0;

-			COFFheader32.OptionalHeader.Win32VersionValue = 0;

-			COFFheader32.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);

-			COFFheader32.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader32));

-			COFFheader32.OptionalHeader.CheckSum = 0;

-			COFFheader32.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;

-			COFFheader32.OptionalHeader.DllCharacteristics =	IMAGE_DLLCHARACTERISTICS_NO_SEH |

-															IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |   // Base address randomization

-															IMAGE_DLLCHARACTERISTICS_NX_COMPAT;       // Data Execution Prevention compatible

-			COFFheader32.OptionalHeader.SizeOfStackReserve = 1024 * 1024;

-			COFFheader32.OptionalHeader.SizeOfStackCommit = 4 * 1024;

-			COFFheader32.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;

-			COFFheader32.OptionalHeader.SizeOfHeapCommit = 4 * 1024;

-			COFFheader32.OptionalHeader.LoaderFlags = 0;

-			COFFheader32.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;

-

-			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;

-			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;

-

-			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;

-			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;

-		}

-		else

-		{

-			memset(&COFFheader64, 0, sizeof(COFFheader64));

-			COFFheader64.Signature = IMAGE_NT_SIGNATURE;   // "PE"

-			COFFheader64.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;

-			COFFheader64.FileHeader.NumberOfSections = 4;

-			COFFheader64.FileHeader.TimeDateStamp = timeDateStamp;

-			COFFheader64.FileHeader.PointerToSymbolTable = 0;   // Deprecated COFF symbol table

-			COFFheader64.FileHeader.NumberOfSymbols = 0;

-			COFFheader64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);

-			COFFheader64.FileHeader.Characteristics =	IMAGE_FILE_EXECUTABLE_IMAGE |

-														IMAGE_FILE_LARGE_ADDRESS_AWARE |

-														IMAGE_FILE_DLL;

-

-			COFFheader64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;

-			COFFheader64.OptionalHeader.MajorLinkerVersion = 8;

-			COFFheader64.OptionalHeader.MinorLinkerVersion = 0;

-			COFFheader64.OptionalHeader.SizeOfCode = fileAlign(codeSize);

-			COFFheader64.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);

-			COFFheader64.OptionalHeader.SizeOfUninitializedData = 0;

-			COFFheader64.OptionalHeader.AddressOfEntryPoint = 0;

-			COFFheader64.OptionalHeader.BaseOfCode = codePage;

-

-			COFFheader64.OptionalHeader.ImageBase = base;

-			COFFheader64.OptionalHeader.SectionAlignment = 0x1000;

-			COFFheader64.OptionalHeader.FileAlignment = 0x200;

-			COFFheader64.OptionalHeader.MajorOperatingSystemVersion = 4;

-			COFFheader64.OptionalHeader.MinorOperatingSystemVersion = 0;

-			COFFheader64.OptionalHeader.MajorImageVersion = 0;

-			COFFheader64.OptionalHeader.MinorImageVersion = 0;

-			COFFheader64.OptionalHeader.MajorSubsystemVersion = 4;

-			COFFheader64.OptionalHeader.MinorSubsystemVersion = 0;

-			COFFheader64.OptionalHeader.Win32VersionValue = 0;

-			COFFheader64.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);

-			COFFheader64.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader64));

-			COFFheader64.OptionalHeader.CheckSum = 0;

-			COFFheader64.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;

-			COFFheader64.OptionalHeader.DllCharacteristics =	IMAGE_DLLCHARACTERISTICS_NO_SEH |

-															IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |   // Base address randomization

-															IMAGE_DLLCHARACTERISTICS_NX_COMPAT;       // Data Execution Prevention compatible

-			COFFheader64.OptionalHeader.SizeOfStackReserve = 1024 * 1024;

-			COFFheader64.OptionalHeader.SizeOfStackCommit = 4 * 1024;

-			COFFheader64.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;

-			COFFheader64.OptionalHeader.SizeOfHeapCommit = 4 * 1024;

-			COFFheader64.OptionalHeader.LoaderFlags = 0;

-			COFFheader64.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;

-

-			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;

-			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;

-

-			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;

-			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;

-		}

-

-		memset(&textSection, 0, sizeof(textSection));

-		strcpy((char*)&textSection.Name, ".text");

-		textSection.Misc.VirtualSize = pageAlign(codeSize);

-		textSection.VirtualAddress = codePage;

-		textSection.SizeOfRawData = fileAlign(codeSize);

-		textSection.PointerToRawData = fileAlign(sizeof(DOSheader) + (AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32)));

-		textSection.PointerToRelocations = 0;

-		textSection.PointerToLinenumbers = 0;

-		textSection.NumberOfRelocations = 0;

-		textSection.NumberOfLinenumbers = 0;

-		textSection.Characteristics = IMAGE_SCN_CNT_CODE |

-		                              IMAGE_SCN_MEM_EXECUTE |

-		                              IMAGE_SCN_MEM_READ;

-

-		memset(&exportsSection, 0, sizeof(exportsSection));

-		strcpy((char*)&exportsSection.Name, ".edata");

-		exportsSection.Misc.VirtualSize = pageAlign(exportsSize);

-		exportsSection.VirtualAddress = exportsPage;

-		exportsSection.SizeOfRawData = fileAlign(exportsSize);

-		exportsSection.PointerToRawData = textSection.PointerToRawData + fileAlign(codeSize);

-		exportsSection.PointerToRelocations = 0;

-		exportsSection.PointerToLinenumbers = 0;

-		exportsSection.NumberOfRelocations = 0;

-		exportsSection.NumberOfLinenumbers = 0;

-		exportsSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |

-		                                 IMAGE_SCN_MEM_READ;

-

-		memset(&relocSection, 0, sizeof(relocSection));

-		strcpy((char*)&relocSection.Name, ".reloc");

-		relocSection.Misc.VirtualSize = pageAlign(relocSize);

-		relocSection.VirtualAddress = relocPage;

-		relocSection.SizeOfRawData = fileAlign(relocSize);

-		relocSection.PointerToRawData = exportsSection.PointerToRawData + fileAlign(exportsSize);

-		relocSection.PointerToRelocations = 0;

-		relocSection.PointerToLinenumbers = 0;

-		relocSection.NumberOfRelocations = 0;

-		relocSection.NumberOfLinenumbers = 0;

-		relocSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |

-		                               IMAGE_SCN_MEM_DISCARDABLE |

-		                               IMAGE_SCN_MEM_READ;

-

-		memset(&constSection, 0, sizeof(constSection));

-		strcpy((char*)&constSection.Name, ".rdata");

-		constSection.Misc.VirtualSize = pageAlign(constSize);

-		constSection.VirtualAddress = constPage;

-		constSection.SizeOfRawData = fileAlign(constSize);

-		constSection.PointerToRawData = relocSection.PointerToRawData + fileAlign(relocSize);

-		constSection.PointerToRelocations = 0;

-		constSection.PointerToLinenumbers = 0;

-		constSection.NumberOfRelocations = 0;

-		constSection.NumberOfLinenumbers = 0;

-		constSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |

-		                               IMAGE_SCN_MEM_READ;

-

-		memset(&exportDirectory, 0, sizeof(exportDirectory));

-		exportDirectory.Characteristics = 0;

-		exportDirectory.TimeDateStamp = timeDateStamp;

-		exportDirectory.MajorVersion = 0;

-		exportDirectory.MinorVersion = 0;

-		exportDirectory.Name = (unsigned long)(exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*));

-		exportDirectory.Base = 1;

-		exportDirectory.NumberOfFunctions = (unsigned long)functionList.size();

-		exportDirectory.NumberOfNames = 0;

-		exportDirectory.AddressOfFunctions = exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY);

-		exportDirectory.AddressOfNames = 0;

-		exportDirectory.AddressOfNameOrdinals = 0;

-

-		FILE *file = fopen(dllName, "wb");

-

-		if(file)

-		{

-			fwrite(&DOSheader, 1, sizeof(DOSheader), file);

-

-			if(AMD64)

-			{

-				fwrite(&COFFheader64, 1, sizeof(COFFheader64), file);

-			}

-			else

-			{

-				fwrite(&COFFheader32, 1, sizeof(COFFheader32), file);

-			}

-

-			fwrite(&textSection, 1, sizeof(textSection), file);

-			fwrite(&exportsSection, 1, sizeof(textSection), file);

-			fwrite(&relocSection, 1, sizeof(relocSection), file);

-			fwrite(&constSection, 1, sizeof(constSection), file);

-

-			for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)

-			{

-				const void *function = i->first;

-				unsigned int location = i->second->location;

-				const std::vector<Relocation> &functionRelocations = globalRelocations[function];

-

-				for(unsigned int j = 0; j < functionRelocations.size(); j++)

-				{

-					unsigned int *address = (unsigned int*)((unsigned char*)i->second->buffer + functionRelocations[j].offset);

-

-					if(functionRelocations[j].ripRelative)

-					{

-						*address = base + codePage + location + (*address - (unsigned int)(size_t)function);

-					}

-					else

-					{

-						*address = base + constPage + (*address - (unsigned int)(size_t)constants);

-					}

-				}

-

-				fseek(file, textSection.PointerToRawData + location, SEEK_SET);

-				fwrite(i->second->buffer, 1, i->second->size, file);

-			}

-

-			fseek(file, exportsSection.PointerToRawData, SEEK_SET);

-			fwrite(&exportDirectory, 1, sizeof(exportDirectory), file);

-

-			for(unsigned int i = 0; i < functionOrder.size(); i++)

-			{

-				const void *buffer = functionOrder[i];

-				Function *function = functionList[buffer];

-

-				unsigned int functionAddress = codePage + function->location;

-				unsigned int functionEntry = functionAddress + (int)((size_t)function->entry - (size_t)buffer);

-				fwrite(&functionEntry, 1, sizeof(functionEntry), file);

-			}

-

-			fwrite(dllName, 1, strlen(dllName) + 1, file);

-

-			fseek(file, relocSection.PointerToRawData, SEEK_SET);

-

-			for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)

-			{

-				IMAGE_BASE_RELOCATION relocationBlock;

-

-				relocationBlock.VirtualAddress = codePage + i->first * 0x1000;

-				relocationBlock.SizeOfBlock = (unsigned long)(sizeof(IMAGE_BASE_RELOCATION) + i->second.size() * sizeof(unsigned short));

-

-				fwrite(&relocationBlock, 1, sizeof(IMAGE_BASE_RELOCATION), file);

-

-				if(i->second.size() > 0)

-				{

-					fwrite(&i->second[0], 1, i->second.size() * sizeof(unsigned short), file);

-				}

-			}

-

-			fseek(file, constSection.PointerToRawData, SEEK_SET);

-			fwrite(constants, 1, constSize, file);

-

-			char *padding = new char[fileAlign(constSize) - constSize];

-			fwrite(padding, 1, fileAlign(constSize) - constSize, file);

-			delete[] padding;

-

-			fclose(file);

-		}

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Dll.hpp"
+
+#include <time.h>
+
+#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
+#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
+#endif
+
+#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT
+#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
+#endif
+
+namespace sw
+{
+	#ifdef _M_AMD64
+		const bool AMD64 = true;
+	#else
+		const bool AMD64 = false;
+	#endif
+
+	DLL::DLL(const char *name, const void *constants, int constSize) : constants(constants), constSize(constSize)
+	{
+		dllName = new char[strlen(name) + 1];
+		strcpy(dllName, name);
+
+		codeSize = 0;
+	}
+
+	DLL::~DLL()
+	{
+		delete[] dllName;
+
+		for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)
+		{
+			delete i->second;
+		}
+	}
+
+	void DLL::addFunction(const void *function, const void *entry, int size)
+	{
+		functionOrder.push_back(function);
+		functionList[function] = new Function(codeSize, function, entry, size);
+
+		codeSize += size;
+	}
+
+	void DLL::addRelocation(const void *function, const void *address, bool ripRelative)
+	{
+		globalRelocations[function].push_back(Relocation((unsigned int)((unsigned char*)address - (unsigned char*)function), ripRelative));
+	}
+
+	void DLL::emit()
+	{
+		if(codeSize == 0)
+		{
+			return;
+		}
+
+		for(GlobalRelocations::iterator i = globalRelocations.begin(); i != globalRelocations.end(); i++)
+		{
+			const unsigned char *function = (const unsigned char*)i->first;
+			const std::vector<Relocation> &functionRelocations = i->second;
+			unsigned int location = functionList[function]->location;
+
+			for(unsigned int j = 0; j < functionRelocations.size(); j++)
+			{
+				unsigned int address = location + functionRelocations[j].offset;
+				unsigned int page = address / 0x1000;
+				unsigned short reloc = address - page * 0x1000;
+
+				unsigned int relocType = AMD64 ? IMAGE_REL_BASED_DIR64 : IMAGE_REL_BASED_HIGHLOW;
+				pageRelocations[page].push_back((relocType << 12) | reloc);
+			}
+		}
+
+		if(pageRelocations.empty())
+		{
+			pageRelocations[0];   // Initialize an emtpy list
+		}
+
+		int relocSize = 0;
+
+		for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)
+		{
+			if(i->second.size() % 2)   // Pad to align to DWORD
+			{
+				i->second.push_back(0);
+			}
+
+			relocSize += (int)sizeof(IMAGE_BASE_RELOCATION) + (int)i->second.size() * (int)sizeof(unsigned short);
+		}
+
+		unsigned long timeDateStamp = (unsigned long)time(0);
+
+		memset(&DOSheader, 0, sizeof(DOSheader));
+		DOSheader.e_magic = IMAGE_DOS_SIGNATURE;   // "MZ"
+		DOSheader.e_lfanew = sizeof(DOSheader);
+
+		int base = 0x10000000;
+		int codePage = pageAlign(sizeof(DOSheader) + (AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32)));
+		int exportsPage = codePage + pageAlign(codeSize);
+		int exportsSize = (int)(sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*) + (strlen(dllName) + 1));
+		int relocPage = exportsPage + pageAlign(exportsSize);
+		int constPage = relocPage + pageAlign(relocSize);
+
+		if(!AMD64)
+		{
+			memset(&COFFheader32, 0, sizeof(COFFheader32));
+			COFFheader32.Signature = IMAGE_NT_SIGNATURE;   // "PE"
+			COFFheader32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
+			COFFheader32.FileHeader.NumberOfSections = 4;
+			COFFheader32.FileHeader.TimeDateStamp = timeDateStamp;
+			COFFheader32.FileHeader.PointerToSymbolTable = 0;   // Deprecated COFF symbol table
+			COFFheader32.FileHeader.NumberOfSymbols = 0;
+			COFFheader32.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32);
+			COFFheader32.FileHeader.Characteristics =	IMAGE_FILE_EXECUTABLE_IMAGE |
+														IMAGE_FILE_32BIT_MACHINE |
+														IMAGE_FILE_DLL;
+
+			COFFheader32.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+			COFFheader32.OptionalHeader.MajorLinkerVersion = 8;
+			COFFheader32.OptionalHeader.MinorLinkerVersion = 0;
+			COFFheader32.OptionalHeader.SizeOfCode = fileAlign(codeSize);
+			COFFheader32.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);
+			COFFheader32.OptionalHeader.SizeOfUninitializedData = 0;
+			COFFheader32.OptionalHeader.AddressOfEntryPoint = 0;
+			COFFheader32.OptionalHeader.BaseOfCode = codePage;
+			COFFheader32.OptionalHeader.BaseOfData = exportsPage;
+
+			COFFheader32.OptionalHeader.ImageBase = base;
+			COFFheader32.OptionalHeader.SectionAlignment = 0x1000;
+			COFFheader32.OptionalHeader.FileAlignment = 0x200;
+			COFFheader32.OptionalHeader.MajorOperatingSystemVersion = 4;
+			COFFheader32.OptionalHeader.MinorOperatingSystemVersion = 0;
+			COFFheader32.OptionalHeader.MajorImageVersion = 0;
+			COFFheader32.OptionalHeader.MinorImageVersion = 0;
+			COFFheader32.OptionalHeader.MajorSubsystemVersion = 4;
+			COFFheader32.OptionalHeader.MinorSubsystemVersion = 0;
+			COFFheader32.OptionalHeader.Win32VersionValue = 0;
+			COFFheader32.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);
+			COFFheader32.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader32));
+			COFFheader32.OptionalHeader.CheckSum = 0;
+			COFFheader32.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
+			COFFheader32.OptionalHeader.DllCharacteristics =	IMAGE_DLLCHARACTERISTICS_NO_SEH |
+															IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |   // Base address randomization
+															IMAGE_DLLCHARACTERISTICS_NX_COMPAT;       // Data Execution Prevention compatible
+			COFFheader32.OptionalHeader.SizeOfStackReserve = 1024 * 1024;
+			COFFheader32.OptionalHeader.SizeOfStackCommit = 4 * 1024;
+			COFFheader32.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;
+			COFFheader32.OptionalHeader.SizeOfHeapCommit = 4 * 1024;
+			COFFheader32.OptionalHeader.LoaderFlags = 0;
+			COFFheader32.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+
+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;
+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;
+
+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;
+			COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;
+		}
+		else
+		{
+			memset(&COFFheader64, 0, sizeof(COFFheader64));
+			COFFheader64.Signature = IMAGE_NT_SIGNATURE;   // "PE"
+			COFFheader64.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;
+			COFFheader64.FileHeader.NumberOfSections = 4;
+			COFFheader64.FileHeader.TimeDateStamp = timeDateStamp;
+			COFFheader64.FileHeader.PointerToSymbolTable = 0;   // Deprecated COFF symbol table
+			COFFheader64.FileHeader.NumberOfSymbols = 0;
+			COFFheader64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);
+			COFFheader64.FileHeader.Characteristics =	IMAGE_FILE_EXECUTABLE_IMAGE |
+														IMAGE_FILE_LARGE_ADDRESS_AWARE |
+														IMAGE_FILE_DLL;
+
+			COFFheader64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+			COFFheader64.OptionalHeader.MajorLinkerVersion = 8;
+			COFFheader64.OptionalHeader.MinorLinkerVersion = 0;
+			COFFheader64.OptionalHeader.SizeOfCode = fileAlign(codeSize);
+			COFFheader64.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);
+			COFFheader64.OptionalHeader.SizeOfUninitializedData = 0;
+			COFFheader64.OptionalHeader.AddressOfEntryPoint = 0;
+			COFFheader64.OptionalHeader.BaseOfCode = codePage;
+
+			COFFheader64.OptionalHeader.ImageBase = base;
+			COFFheader64.OptionalHeader.SectionAlignment = 0x1000;
+			COFFheader64.OptionalHeader.FileAlignment = 0x200;
+			COFFheader64.OptionalHeader.MajorOperatingSystemVersion = 4;
+			COFFheader64.OptionalHeader.MinorOperatingSystemVersion = 0;
+			COFFheader64.OptionalHeader.MajorImageVersion = 0;
+			COFFheader64.OptionalHeader.MinorImageVersion = 0;
+			COFFheader64.OptionalHeader.MajorSubsystemVersion = 4;
+			COFFheader64.OptionalHeader.MinorSubsystemVersion = 0;
+			COFFheader64.OptionalHeader.Win32VersionValue = 0;
+			COFFheader64.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);
+			COFFheader64.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader64));
+			COFFheader64.OptionalHeader.CheckSum = 0;
+			COFFheader64.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
+			COFFheader64.OptionalHeader.DllCharacteristics =	IMAGE_DLLCHARACTERISTICS_NO_SEH |
+															IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |   // Base address randomization
+															IMAGE_DLLCHARACTERISTICS_NX_COMPAT;       // Data Execution Prevention compatible
+			COFFheader64.OptionalHeader.SizeOfStackReserve = 1024 * 1024;
+			COFFheader64.OptionalHeader.SizeOfStackCommit = 4 * 1024;
+			COFFheader64.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;
+			COFFheader64.OptionalHeader.SizeOfHeapCommit = 4 * 1024;
+			COFFheader64.OptionalHeader.LoaderFlags = 0;
+			COFFheader64.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+
+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;
+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;
+
+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;
+			COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;
+		}
+
+		memset(&textSection, 0, sizeof(textSection));
+		strcpy((char*)&textSection.Name, ".text");
+		textSection.Misc.VirtualSize = pageAlign(codeSize);
+		textSection.VirtualAddress = codePage;
+		textSection.SizeOfRawData = fileAlign(codeSize);
+		textSection.PointerToRawData = fileAlign(sizeof(DOSheader) + (AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32)));
+		textSection.PointerToRelocations = 0;
+		textSection.PointerToLinenumbers = 0;
+		textSection.NumberOfRelocations = 0;
+		textSection.NumberOfLinenumbers = 0;
+		textSection.Characteristics = IMAGE_SCN_CNT_CODE |
+		                              IMAGE_SCN_MEM_EXECUTE |
+		                              IMAGE_SCN_MEM_READ;
+
+		memset(&exportsSection, 0, sizeof(exportsSection));
+		strcpy((char*)&exportsSection.Name, ".edata");
+		exportsSection.Misc.VirtualSize = pageAlign(exportsSize);
+		exportsSection.VirtualAddress = exportsPage;
+		exportsSection.SizeOfRawData = fileAlign(exportsSize);
+		exportsSection.PointerToRawData = textSection.PointerToRawData + fileAlign(codeSize);
+		exportsSection.PointerToRelocations = 0;
+		exportsSection.PointerToLinenumbers = 0;
+		exportsSection.NumberOfRelocations = 0;
+		exportsSection.NumberOfLinenumbers = 0;
+		exportsSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
+		                                 IMAGE_SCN_MEM_READ;
+
+		memset(&relocSection, 0, sizeof(relocSection));
+		strcpy((char*)&relocSection.Name, ".reloc");
+		relocSection.Misc.VirtualSize = pageAlign(relocSize);
+		relocSection.VirtualAddress = relocPage;
+		relocSection.SizeOfRawData = fileAlign(relocSize);
+		relocSection.PointerToRawData = exportsSection.PointerToRawData + fileAlign(exportsSize);
+		relocSection.PointerToRelocations = 0;
+		relocSection.PointerToLinenumbers = 0;
+		relocSection.NumberOfRelocations = 0;
+		relocSection.NumberOfLinenumbers = 0;
+		relocSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
+		                               IMAGE_SCN_MEM_DISCARDABLE |
+		                               IMAGE_SCN_MEM_READ;
+
+		memset(&constSection, 0, sizeof(constSection));
+		strcpy((char*)&constSection.Name, ".rdata");
+		constSection.Misc.VirtualSize = pageAlign(constSize);
+		constSection.VirtualAddress = constPage;
+		constSection.SizeOfRawData = fileAlign(constSize);
+		constSection.PointerToRawData = relocSection.PointerToRawData + fileAlign(relocSize);
+		constSection.PointerToRelocations = 0;
+		constSection.PointerToLinenumbers = 0;
+		constSection.NumberOfRelocations = 0;
+		constSection.NumberOfLinenumbers = 0;
+		constSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
+		                               IMAGE_SCN_MEM_READ;
+
+		memset(&exportDirectory, 0, sizeof(exportDirectory));
+		exportDirectory.Characteristics = 0;
+		exportDirectory.TimeDateStamp = timeDateStamp;
+		exportDirectory.MajorVersion = 0;
+		exportDirectory.MinorVersion = 0;
+		exportDirectory.Name = (unsigned long)(exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*));
+		exportDirectory.Base = 1;
+		exportDirectory.NumberOfFunctions = (unsigned long)functionList.size();
+		exportDirectory.NumberOfNames = 0;
+		exportDirectory.AddressOfFunctions = exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY);
+		exportDirectory.AddressOfNames = 0;
+		exportDirectory.AddressOfNameOrdinals = 0;
+
+		FILE *file = fopen(dllName, "wb");
+
+		if(file)
+		{
+			fwrite(&DOSheader, 1, sizeof(DOSheader), file);
+
+			if(AMD64)
+			{
+				fwrite(&COFFheader64, 1, sizeof(COFFheader64), file);
+			}
+			else
+			{
+				fwrite(&COFFheader32, 1, sizeof(COFFheader32), file);
+			}
+
+			fwrite(&textSection, 1, sizeof(textSection), file);
+			fwrite(&exportsSection, 1, sizeof(textSection), file);
+			fwrite(&relocSection, 1, sizeof(relocSection), file);
+			fwrite(&constSection, 1, sizeof(constSection), file);
+
+			for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)
+			{
+				const void *function = i->first;
+				unsigned int location = i->second->location;
+				const std::vector<Relocation> &functionRelocations = globalRelocations[function];
+
+				for(unsigned int j = 0; j < functionRelocations.size(); j++)
+				{
+					unsigned int *address = (unsigned int*)((unsigned char*)i->second->buffer + functionRelocations[j].offset);
+
+					if(functionRelocations[j].ripRelative)
+					{
+						*address = base + codePage + location + (*address - (unsigned int)(size_t)function);
+					}
+					else
+					{
+						*address = base + constPage + (*address - (unsigned int)(size_t)constants);
+					}
+				}
+
+				fseek(file, textSection.PointerToRawData + location, SEEK_SET);
+				fwrite(i->second->buffer, 1, i->second->size, file);
+			}
+
+			fseek(file, exportsSection.PointerToRawData, SEEK_SET);
+			fwrite(&exportDirectory, 1, sizeof(exportDirectory), file);
+
+			for(unsigned int i = 0; i < functionOrder.size(); i++)
+			{
+				const void *buffer = functionOrder[i];
+				Function *function = functionList[buffer];
+
+				unsigned int functionAddress = codePage + function->location;
+				unsigned int functionEntry = functionAddress + (int)((size_t)function->entry - (size_t)buffer);
+				fwrite(&functionEntry, 1, sizeof(functionEntry), file);
+			}
+
+			fwrite(dllName, 1, strlen(dllName) + 1, file);
+
+			fseek(file, relocSection.PointerToRawData, SEEK_SET);
+
+			for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)
+			{
+				IMAGE_BASE_RELOCATION relocationBlock;
+
+				relocationBlock.VirtualAddress = codePage + i->first * 0x1000;
+				relocationBlock.SizeOfBlock = (unsigned long)(sizeof(IMAGE_BASE_RELOCATION) + i->second.size() * sizeof(unsigned short));
+
+				fwrite(&relocationBlock, 1, sizeof(IMAGE_BASE_RELOCATION), file);
+
+				if(i->second.size() > 0)
+				{
+					fwrite(&i->second[0], 1, i->second.size() * sizeof(unsigned short), file);
+				}
+			}
+
+			fseek(file, constSection.PointerToRawData, SEEK_SET);
+			fwrite(constants, 1, constSize, file);
+
+			char *padding = new char[fileAlign(constSize) - constSize];
+			fwrite(padding, 1, fileAlign(constSize) - constSize, file);
+			delete[] padding;
+
+			fclose(file);
+		}
+	}
+}
diff --git a/src/Reactor/DLL.hpp b/src/Reactor/DLL.hpp
index 9e10caf..db9eff6 100644
--- a/src/Reactor/DLL.hpp
+++ b/src/Reactor/DLL.hpp
@@ -1,102 +1,105 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_DLL_hpp

-#define sw_DLL_hpp

-

-#include <windows.h>

-#include <vector>

-#include <map>

-

-namespace sw

-{

-	class DLL

-	{

-	public:

-		DLL(const char *name, const void *constants = 0, int constSize = 0);

-

-		~DLL();

-

-		void addFunction(const void *function, const void *entry, int size);

-		void addRelocation(const void *function, const void *address, bool ripRelative);

-		void emit();

-

-	private:

-		int pageAlign(int address)   // Align to 4 kB virtual page size

-		{

-			return (address + 0xFFF) & -0x1000;

-		}

-

-		int fileAlign(int address)   // Align to 512 byte file sections

-		{

-			return (address + 0x1FF) & -0x200;

-		}

-

-		char *dllName;

-

-		IMAGE_DOS_HEADER DOSheader;

-		IMAGE_NT_HEADERS32 COFFheader32;

-		IMAGE_NT_HEADERS64 COFFheader64;

-		IMAGE_SECTION_HEADER textSection;

-		IMAGE_SECTION_HEADER exportsSection;

-		IMAGE_SECTION_HEADER relocSection;

-		IMAGE_SECTION_HEADER constSection;

-

-		IMAGE_EXPORT_DIRECTORY exportDirectory;

-

-		struct Function

-		{

-			Function() {};

-			Function(unsigned int location, const void *function, const void *entry, int size) : location(location), entry(entry), size(size)

-			{

-				buffer = new unsigned char[size];

-				

-				memcpy(buffer, function, size);

-			}

-

-			~Function()

-			{

-				delete[] buffer;

-			}

-

-			void *buffer;

-

-			unsigned int location;

-			const void *entry;

-			int size;

-		};

-

-		std::vector<const void*> functionOrder;

-		typedef std::map<const void*, Function*> FunctionList;

-		FunctionList functionList;

-		int codeSize;

-

-		const void *constants;

-		int constSize;

-

-		struct Relocation

-		{

-			Relocation(unsigned int offset, bool ripRelative) : offset(offset), ripRelative(ripRelative)

-			{

-			}

-

-			unsigned int offset;

-			bool ripRelative;

-		};

-

-		typedef std::map<const void*, std::vector<Relocation> > GlobalRelocations;

-		GlobalRelocations globalRelocations;

-		typedef std::map<unsigned int, std::vector<unsigned short> > PageRelocations;

-		PageRelocations pageRelocations;

-	};

-}

-

-#endif   // sw_DLL_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_DLL_hpp
+#define sw_DLL_hpp
+
+#include <windows.h>
+#include <vector>
+#include <map>
+
+namespace sw
+{
+	class DLL
+	{
+	public:
+		DLL(const char *name, const void *constants = 0, int constSize = 0);
+
+		~DLL();
+
+		void addFunction(const void *function, const void *entry, int size);
+		void addRelocation(const void *function, const void *address, bool ripRelative);
+		void emit();
+
+	private:
+		int pageAlign(int address)   // Align to 4 kB virtual page size
+		{
+			return (address + 0xFFF) & -0x1000;
+		}
+
+		int fileAlign(int address)   // Align to 512 byte file sections
+		{
+			return (address + 0x1FF) & -0x200;
+		}
+
+		char *dllName;
+
+		IMAGE_DOS_HEADER DOSheader;
+		IMAGE_NT_HEADERS32 COFFheader32;
+		IMAGE_NT_HEADERS64 COFFheader64;
+		IMAGE_SECTION_HEADER textSection;
+		IMAGE_SECTION_HEADER exportsSection;
+		IMAGE_SECTION_HEADER relocSection;
+		IMAGE_SECTION_HEADER constSection;
+
+		IMAGE_EXPORT_DIRECTORY exportDirectory;
+
+		struct Function
+		{
+			Function() {};
+			Function(unsigned int location, const void *function, const void *entry, int size) : location(location), entry(entry), size(size)
+			{
+				buffer = new unsigned char[size];
+		
+				memcpy(buffer, function, size);
+			}
+
+			~Function()
+			{
+				delete[] buffer;
+			}
+
+			void *buffer;
+
+			unsigned int location;
+			const void *entry;
+			int size;
+		};
+
+		std::vector<const void*> functionOrder;
+		typedef std::map<const void*, Function*> FunctionList;
+		FunctionList functionList;
+		int codeSize;
+
+		const void *constants;
+		int constSize;
+
+		struct Relocation
+		{
+			Relocation(unsigned int offset, bool ripRelative) : offset(offset), ripRelative(ripRelative)
+			{
+			}
+
+			unsigned int offset;
+			bool ripRelative;
+		};
+
+		typedef std::map<const void*, std::vector<Relocation> > GlobalRelocations;
+		GlobalRelocations globalRelocations;
+		typedef std::map<unsigned int, std::vector<unsigned short> > PageRelocations;
+		PageRelocations pageRelocations;
+	};
+}
+
+#endif   // sw_DLL_hpp
diff --git a/src/Reactor/Nucleus.cpp b/src/Reactor/Nucleus.cpp
index 9df76b2..09c547e 100644
--- a/src/Reactor/Nucleus.cpp
+++ b/src/Reactor/Nucleus.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Nucleus.hpp"
 
diff --git a/src/Reactor/Nucleus.hpp b/src/Reactor/Nucleus.hpp
index 184a2bb..4a2f22d 100644
--- a/src/Reactor/Nucleus.hpp
+++ b/src/Reactor/Nucleus.hpp
@@ -1,3033 +1,3036 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Nucleus_hpp

-#define sw_Nucleus_hpp

-

-#include "Common/Types.hpp"

-#include "Common/MutexLock.hpp"

-

-#include <stdarg.h>

-#include <vector>

-#include <stdio.h>

-#include <wchar.h>

-

-#undef abs

-#undef max

-#undef min

-#undef Bool

-

-namespace llvm

-{

-	class Function;

-	class Module;

-	class BasicBlock;

-	class Value;

-	class Constant;

-	class ConstantInt;

-	class ConstantFP;

-	class Type;

-	class Argument;

-	class GlobalVariable;

-	class GlobalValue;

-	class ExecutionEngine;

-	class LLVMContext;

-}

-

-namespace sw

-{

-	enum Optimization

-	{

-		Disabled             = 0,

-		InstructionCombining = 1,

-		CFGSimplification    = 2,

-		LICM                 = 3,

-		AggressiveDCE        = 4,

-		GVN                  = 5,

-		Reassociate          = 6,

-		DeadStoreElimination = 7,

-		SCCP                 = 8,

-		ScalarReplAggregates = 9,

-

-		OptimizationCount

-	};

-

-	extern Optimization optimization[10];

-

-	class Routine;

-	class RoutineManager;

-	class Builder;

-

-	class Nucleus

-	{

-	public:

-		Nucleus();

-

-		virtual ~Nucleus();

-

-		Routine *acquireRoutine(const wchar_t *name, bool runOptimizations = true);

-

-		static void setFunction(llvm::Function *function);

-

-		static llvm::Module *getModule();

-		static llvm::Function *getFunction();

-		static llvm::LLVMContext *getContext();

-

-		static llvm::Value *allocateStackVariable(llvm::Type *type, int arraySize = 0);

-		static llvm::BasicBlock *createBasicBlock();

-		static llvm::BasicBlock *getInsertBlock();

-		static void setInsertBlock(llvm::BasicBlock *basicBlock);

-		static llvm::BasicBlock *getPredecessor(llvm::BasicBlock *basicBlock);

-

-		static llvm::Function *createFunction(llvm::Type *ReturnType, std::vector<llvm::Type*> &Params);

-		static llvm::Value *getArgument(llvm::Function *function, unsigned int index);

-

-		// Terminators

-		static llvm::Value *createRetVoid();

-		static llvm::Value *createRet(llvm::Value *V);

-		static llvm::Value *createBr(llvm::BasicBlock *dest);

-		static llvm::Value *createCondBr(llvm::Value *cond, llvm::BasicBlock *ifTrue, llvm::BasicBlock *ifFalse);

-

-		// Binary operators

-		static llvm::Value *createAdd(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createSub(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createMul(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createUDiv(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createSDiv(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFAdd(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFSub(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFMul(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFDiv(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createURem(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createSRem(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFRem(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createShl(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createLShr(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createAShr(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createAnd(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createOr(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createXor(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createNeg(llvm::Value *V);

-		static llvm::Value *createFNeg(llvm::Value *V);

-		static llvm::Value *createNot(llvm::Value *V);

-

-		// Memory instructions

-		static llvm::Value *createLoad(llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);

-		static llvm::Value *createStore(llvm::Value *value, llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);

-		static llvm::Value *createGEP(llvm::Value *ptr, llvm::Value *index);

-

-		// Atomic instructions

-		static llvm::Value *createAtomicAdd(llvm::Value *ptr, llvm::Value *value);

-

-		// Cast/Conversion Operators

-		static llvm::Value *createTrunc(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createZExt(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createSExt(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createFPToUI(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createFPToSI(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createUIToFP(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createSIToFP(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createFPTrunc(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createFPExt(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createPtrToInt(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createIntToPtr(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createBitCast(llvm::Value *V, llvm::Type *destType);

-		static llvm::Value *createIntCast(llvm::Value *V, llvm::Type *destType, bool isSigned);

-

-		// Compare instructions

-		static llvm::Value *createICmpEQ(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpNE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpUGT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpUGE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpULT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpULE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpSGT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpSGE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpSLT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createICmpSLE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpOEQ(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpOGT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpOGE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpOLT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpOLE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpONE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpORD(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpUNO(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpUEQ(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpUGT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpUGE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpULT(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpULE(llvm::Value *lhs, llvm::Value *rhs);

-		static llvm::Value *createFCmpUNE(llvm::Value *lhs, llvm::Value *rhs);

-

-		// Call instructions

-		static llvm::Value *createCall(llvm::Value *callee);

-		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg);

-		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2);

-		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2, llvm::Value *Arg3);

-		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2, llvm::Value *Arg3,llvm::Value *Arg4);

-

-		// Vector instructions

-		static llvm::Value *createExtractElement(llvm::Value *vector, int index);

-		static llvm::Value *createInsertElement(llvm::Value *vector, llvm::Value *element, int index);

-		static llvm::Value *createShuffleVector(llvm::Value *V1, llvm::Value *V2, llvm::Value *mask);

-

-		// Other instructions

-		static llvm::Value *createSelect(llvm::Value *C, llvm::Value *ifTrue, llvm::Value *ifFalse);

-		static llvm::Value *createSwitch(llvm::Value *V, llvm::BasicBlock *Dest, unsigned NumCases);

-		static void addSwitchCase(llvm::Value *Switch, int Case, llvm::BasicBlock *Branch);

-		static llvm::Value *createUnreachable();

-

-		// Derived instructions

-		static llvm::Value *createSwizzle(llvm::Value *val, unsigned char select);

-		static llvm::Value *createMask(llvm::Value *lhs, llvm::Value *rhs, unsigned char select);

-

-		// Global values

-		static const llvm::GlobalValue *getGlobalValueAtAddress(void *Addr);

-		static void addGlobalMapping(const llvm::GlobalValue *GV, void *Addr);

-		static llvm::GlobalValue *createGlobalValue(llvm::Type *Ty, bool isConstant, unsigned int Align);

-		static llvm::Type *getPointerType(llvm::Type *ElementType);

-

-		// Constant values

-		static llvm::Constant *createNullValue(llvm::Type *Ty);

-		static llvm::ConstantInt *createConstantInt(int64_t i);

-		static llvm::ConstantInt *createConstantInt(int i);

-		static llvm::ConstantInt *createConstantInt(unsigned int i);

-		static llvm::ConstantInt *createConstantBool(bool b);

-		static llvm::ConstantInt *createConstantByte(signed char i);

-		static llvm::ConstantInt *createConstantByte(unsigned char i);

-		static llvm::ConstantInt *createConstantShort(short i);

-		static llvm::ConstantInt *createConstantShort(unsigned short i);

-		static llvm::Constant *createConstantFloat(float x);

-		static llvm::Value *createNullPointer(llvm::Type *Ty);

-		static llvm::Value *createConstantVector(llvm::Constant *const *Vals, unsigned NumVals);

-

-	private:

-		void optimize();

-

-		static llvm::ExecutionEngine *executionEngine;

-		static Builder *builder;

-		static llvm::Function *function;

-		static llvm::LLVMContext *context;

-		static llvm::Module *module;

-		static RoutineManager *routineManager;

-

-		static BackoffLock codegenMutex;

-	};

-

-	class Byte;

-	class SByte;

-	class Byte4;

-	class SByte4;

-	class Byte8;

-	class SByte8;

-	class Byte16;

-	class SByte16;

-	class Short;

-	class UShort;

-	class Short4;

-	class UShort4;

-	class Short8;

-	class UShort8;

-	class Int;

-	class UInt;

-	class Int2;

-	class UInt2;

-	class Int4;

-	class UInt4;

-	class Long;

-	class Long1;

-	class Long2;

-	class Float;

-	class Float2;

-	class Float4;

-

-	class Void

-	{

-	public:

-		static llvm::Type *getType();

-

-		static bool isVoid()

-		{

-			return true;

-		}

-

-		typedef void ctype;

-	};

-

-	template<class T>

-	class RValue;

-

-	template<class T>

-	class Pointer;

-

-	class LValue

-	{

-	public:

-		LValue(llvm::Type *type, int arraySize = 0);

-

-		static bool isVoid()

-		{

-			return false;

-		}

-

-		llvm::Value *loadValue(unsigned int alignment = 0) const;

-		llvm::Value *storeValue(llvm::Value *value, unsigned int alignment = 0) const;

-		llvm::Value *getAddress(llvm::Value *index) const;

-

-	protected:

-		llvm::Value *address;

-	};

-

-	template<class T>

-	class Variable : public LValue

-	{

-	public:

-		Variable(int arraySize = 0);

-

-		RValue<Pointer<T>> operator&();

-	};

-

-	template<class T>

-	class Reference

-	{

-	public:

-		explicit Reference(llvm::Value *pointer, int alignment = 1);

-

-		RValue<T> operator=(RValue<T> rhs) const;

-		RValue<T> operator=(const Reference<T> &ref) const;

-

-		RValue<T> operator+=(RValue<T> rhs) const;

-

-		llvm::Value *loadValue() const;

-		int getAlignment() const;

-

-	private:

-		llvm::Value *address;

-

-		const int alignment;

-	};

-

-	template<class T>

-	struct IntLiteral

-	{

-		struct type;

-	};

-

-	template<> struct

-	IntLiteral<Int>

-	{

-		typedef int type;

-	};

-

-	template<> struct

-	IntLiteral<UInt>

-	{

-		typedef unsigned int type;

-	};

-

-	template<> struct

-	IntLiteral<Long>

-	{

-		typedef int64_t type;

-	};

-

-	template<class T>

-	struct FloatLiteral

-	{

-		struct type;

-	};

-

-	template<> struct

-	FloatLiteral<Float>

-	{

-		typedef float type;

-	};

-

-	template<class T>

-	class RValue

-	{

-	public:

-		explicit RValue(llvm::Value *rvalue);

-

-		RValue(const T &lvalue);

-		RValue(typename IntLiteral<T>::type i);

-		RValue(typename FloatLiteral<T>::type f);

-		RValue(const Reference<T> &rhs);

-

-		RValue<T> &operator=(const RValue<T>&) = delete;

-

-		llvm::Value *value;   // FIXME: Make private

-	};

-

-	template<typename T>

-	struct Argument

-	{

-		explicit Argument(llvm::Value *value) : value(value) {}

-

-		llvm::Value *value;

-	};

-

-	class MMX : public Variable<MMX>

-	{

-	public:

-		static llvm::Type *getType();

-	};

-

-	class Bool : public Variable<Bool>

-	{

-	public:

-		Bool(Argument<Bool> argument);

-

-		Bool();

-		Bool(bool x);

-		Bool(RValue<Bool> rhs);

-		Bool(const Bool &rhs);

-		Bool(const Reference<Bool> &rhs);

-

-	//	RValue<Bool> operator=(bool rhs) const;   // FIXME: Implement

-		RValue<Bool> operator=(RValue<Bool> rhs) const;

-		RValue<Bool> operator=(const Bool &rhs) const;

-		RValue<Bool> operator=(const Reference<Bool> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Bool> operator!(RValue<Bool> val);

-	RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);

-	RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs);

-

-	class Byte : public Variable<Byte>

-	{

-	public:

-		Byte(Argument<Byte> argument);

-

-		explicit Byte(RValue<Int> cast);

-		explicit Byte(RValue<UInt> cast);

-		explicit Byte(RValue<UShort> cast);

-

-		Byte();

-		Byte(int x);

-		Byte(unsigned char x);

-		Byte(RValue<Byte> rhs);

-		Byte(const Byte &rhs);

-		Byte(const Reference<Byte> &rhs);

-

-	//	RValue<Byte> operator=(unsigned char rhs) const;   // FIXME: Implement

-		RValue<Byte> operator=(RValue<Byte> rhs) const;

-		RValue<Byte> operator=(const Byte &rhs) const;

-		RValue<Byte> operator=(const Reference<Byte> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs);

-	RValue<Byte> operator+(RValue<Byte> val);

-	RValue<Byte> operator-(RValue<Byte> val);

-	RValue<Byte> operator~(RValue<Byte> val);

-	RValue<Byte> operator++(const Byte &val, int);   // Post-increment

-	const Byte &operator++(const Byte &val);   // Pre-increment

-	RValue<Byte> operator--(const Byte &val, int);   // Post-decrement

-	const Byte &operator--(const Byte &val);   // Pre-decrement

-	RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs);

-	RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs);

-

-	class SByte : public Variable<SByte>

-	{

-	public:

-		SByte(Argument<SByte> argument);

-

-		explicit SByte(RValue<Int> cast);

-		explicit SByte(RValue<Short> cast);

-

-		SByte();

-		SByte(signed char x);

-		SByte(RValue<SByte> rhs);

-		SByte(const SByte &rhs);

-		SByte(const Reference<SByte> &rhs);

-

-	//	RValue<SByte> operator=(signed char rhs) const;   // FIXME: Implement

-		RValue<SByte> operator=(RValue<SByte> rhs) const;

-		RValue<SByte> operator=(const SByte &rhs) const;

-		RValue<SByte> operator=(const Reference<SByte> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs);

-	RValue<SByte> operator+(RValue<SByte> val);

-	RValue<SByte> operator-(RValue<SByte> val);

-	RValue<SByte> operator~(RValue<SByte> val);

-	RValue<SByte> operator++(const SByte &val, int);   // Post-increment

-	const SByte &operator++(const SByte &val);   // Pre-increment

-	RValue<SByte> operator--(const SByte &val, int);   // Post-decrement

-	const SByte &operator--(const SByte &val);   // Pre-decrement

-	RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs);

-	RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs);

-

-	class Short : public Variable<Short>

-	{

-	public:

-		Short(Argument<Short> argument);

-

-		explicit Short(RValue<Int> cast);

-

-		Short();

-		Short(short x);

-		Short(RValue<Short> rhs);

-		Short(const Short &rhs);

-		Short(const Reference<Short> &rhs);

-

-	//	RValue<Short> operator=(short rhs) const;   // FIXME: Implement

-		RValue<Short> operator=(RValue<Short> rhs) const;

-		RValue<Short> operator=(const Short &rhs) const;

-		RValue<Short> operator=(const Reference<Short> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs);

-	RValue<Short> operator+(RValue<Short> val);

-	RValue<Short> operator-(RValue<Short> val);

-	RValue<Short> operator~(RValue<Short> val);

-	RValue<Short> operator++(const Short &val, int);   // Post-increment

-	const Short &operator++(const Short &val);   // Pre-increment

-	RValue<Short> operator--(const Short &val, int);   // Post-decrement

-	const Short &operator--(const Short &val);   // Pre-decrement

-	RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs);

-	RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs);

-

-	class UShort : public Variable<UShort>

-	{

-	public:

-		UShort(Argument<UShort> argument);

-

-		explicit UShort(RValue<UInt> cast);

-		explicit UShort(RValue<Int> cast);

-

-		UShort();

-		UShort(unsigned short x);

-		UShort(RValue<UShort> rhs);

-		UShort(const UShort &rhs);

-		UShort(const Reference<UShort> &rhs);

-

-	//	RValue<UShort> operator=(unsigned short rhs) const;   // FIXME: Implement

-		RValue<UShort> operator=(RValue<UShort> rhs) const;

-		RValue<UShort> operator=(const UShort &rhs) const;

-		RValue<UShort> operator=(const Reference<UShort> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs);

-	RValue<UShort> operator+(RValue<UShort> val);

-	RValue<UShort> operator-(RValue<UShort> val);

-	RValue<UShort> operator~(RValue<UShort> val);

-	RValue<UShort> operator++(const UShort &val, int);   // Post-increment

-	const UShort &operator++(const UShort &val);   // Pre-increment

-	RValue<UShort> operator--(const UShort &val, int);   // Post-decrement

-	const UShort &operator--(const UShort &val);   // Pre-decrement

-	RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs);

-	RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs);

-

-	class Byte4 : public Variable<Byte4>

-	{

-	public:

-	//	Byte4();

-	//	Byte4(int x, int y, int z, int w);

-	//	Byte4(RValue<Byte4> rhs);

-	//	Byte4(const Byte4 &rhs);

-	//	Byte4(const Reference<Byte4> &rhs);

-

-	//	RValue<Byte4> operator=(RValue<Byte4> rhs) const;

-	//	RValue<Byte4> operator=(const Byte4 &rhs) const;

-	//	RValue<Byte4> operator=(const Reference<Byte4> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-//	RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator*(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator/(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator%(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator&(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator|(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator^(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator<<(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator>>(RValue<Byte4> lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator+=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator-=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator*=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator/=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator%=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator&=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator|=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator^=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator<<=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator>>=(const Byte4 &lhs, RValue<Byte4> rhs);

-//	RValue<Byte4> operator+(RValue<Byte4> val);

-//	RValue<Byte4> operator-(RValue<Byte4> val);

-//	RValue<Byte4> operator~(RValue<Byte4> val);

-//	RValue<Byte4> operator++(const Byte4 &val, int);   // Post-increment

-//	const Byte4 &operator++(const Byte4 &val);   // Pre-increment

-//	RValue<Byte4> operator--(const Byte4 &val, int);   // Post-decrement

-//	const Byte4 &operator--(const Byte4 &val);   // Pre-decrement

-

-	class SByte4 : public Variable<SByte4>

-	{

-	public:

-	//	SByte4();

-	//	SByte4(int x, int y, int z, int w);

-	//	SByte4(RValue<SByte4> rhs);

-	//	SByte4(const SByte4 &rhs);

-	//	SByte4(const Reference<SByte4> &rhs);

-

-	//	RValue<SByte4> operator=(RValue<SByte4> rhs) const;

-	//	RValue<SByte4> operator=(const SByte4 &rhs) const;

-	//	RValue<SByte4> operator=(const Reference<SByte4> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-//	RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator*(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator/(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator%(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator&(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator|(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator^(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator<<(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator>>(RValue<SByte4> lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator+=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator-=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator*=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator/=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator%=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator&=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator|=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator^=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator<<=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator>>=(const SByte4 &lhs, RValue<SByte4> rhs);

-//	RValue<SByte4> operator+(RValue<SByte4> val);

-//	RValue<SByte4> operator-(RValue<SByte4> val);

-//	RValue<SByte4> operator~(RValue<SByte4> val);

-//	RValue<SByte4> operator++(const SByte4 &val, int);   // Post-increment

-//	const SByte4 &operator++(const SByte4 &val);   // Pre-increment

-//	RValue<SByte4> operator--(const SByte4 &val, int);   // Post-decrement

-//	const SByte4 &operator--(const SByte4 &val);   // Pre-decrement

-

-	class Byte8 : public Variable<Byte8>

-	{

-	public:

-		Byte8();

-		Byte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7);

-		Byte8(int64_t x);

-		Byte8(RValue<Byte8> rhs);

-		Byte8(const Byte8 &rhs);

-		Byte8(const Reference<Byte8> &rhs);

-

-		RValue<Byte8> operator=(RValue<Byte8> rhs) const;

-		RValue<Byte8> operator=(const Byte8 &rhs) const;

-		RValue<Byte8> operator=(const Reference<Byte8> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator<<(RValue<Byte8> lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator>>(RValue<Byte8> lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs);

-	RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs);

-//	RValue<Byte8> operator+(RValue<Byte8> val);

-//	RValue<Byte8> operator-(RValue<Byte8> val);

-	RValue<Byte8> operator~(RValue<Byte8> val);

-//	RValue<Byte8> operator++(const Byte8 &val, int);   // Post-increment

-//	const Byte8 &operator++(const Byte8 &val);   // Pre-increment

-//	RValue<Byte8> operator--(const Byte8 &val, int);   // Post-decrement

-//	const Byte8 &operator--(const Byte8 &val);   // Pre-decrement

-

-	RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y);

-	RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y);

-	RValue<Short4> Unpack(RValue<Byte4> x);

-	RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y);

-	RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y);

-	RValue<Int> SignMask(RValue<Byte8> x);

-//	RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y);

-	RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y);

-

-	class SByte8 : public Variable<SByte8>

-	{

-	public:

-		SByte8();

-		SByte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7);

-		SByte8(int64_t x);

-		SByte8(RValue<SByte8> rhs);

-		SByte8(const SByte8 &rhs);

-		SByte8(const Reference<SByte8> &rhs);

-

-		RValue<SByte8> operator=(RValue<SByte8> rhs) const;

-		RValue<SByte8> operator=(const SByte8 &rhs) const;

-		RValue<SByte8> operator=(const Reference<SByte8> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator<<(RValue<SByte8> lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator>>(RValue<SByte8> lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs);

-	RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs);

-//	RValue<SByte8> operator+(RValue<SByte8> val);

-//	RValue<SByte8> operator-(RValue<SByte8> val);

-	RValue<SByte8> operator~(RValue<SByte8> val);

-//	RValue<SByte8> operator++(const SByte8 &val, int);   // Post-increment

-//	const SByte8 &operator++(const SByte8 &val);   // Pre-increment

-//	RValue<SByte8> operator--(const SByte8 &val, int);   // Post-decrement

-//	const SByte8 &operator--(const SByte8 &val);   // Pre-decrement

-

-    RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y);

-	RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y);

-	RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y);

-	RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y);

-	RValue<Int> SignMask(RValue<SByte8> x);

-	RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y);

-	RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y);

-

-	class Byte16 : public Variable<Byte16>

-	{

-	public:

-	//	Byte16();

-	//	Byte16(int x, int y, int z, int w);

-		Byte16(RValue<Byte16> rhs);

-		Byte16(const Byte16 &rhs);

-		Byte16(const Reference<Byte16> &rhs);

-

-		RValue<Byte16> operator=(RValue<Byte16> rhs) const;

-		RValue<Byte16> operator=(const Byte16 &rhs) const;

-		RValue<Byte16> operator=(const Reference<Byte16> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-//	RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator*(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator/(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator%(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator&(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator|(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator^(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator<<(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator>>(RValue<Byte16> lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator+=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator-=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator*=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator/=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator%=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator&=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator|=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator^=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator<<=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator>>=(const Byte16 &lhs, RValue<Byte16> rhs);

-//	RValue<Byte16> operator+(RValue<Byte16> val);

-//	RValue<Byte16> operator-(RValue<Byte16> val);

-//	RValue<Byte16> operator~(RValue<Byte16> val);

-//	RValue<Byte16> operator++(const Byte16 &val, int);   // Post-increment

-//	const Byte16 &operator++(const Byte16 &val);   // Pre-increment

-//	RValue<Byte16> operator--(const Byte16 &val, int);   // Post-decrement

-//	const Byte16 &operator--(const Byte16 &val);   // Pre-decrement

-

-	class SByte16 : public Variable<SByte16>

-	{

-	public:

-	//	SByte16();

-	//	SByte16(int x, int y, int z, int w);

-	//	SByte16(RValue<SByte16> rhs);

-	//	SByte16(const SByte16 &rhs);

-	//	SByte16(const Reference<SByte16> &rhs);

-

-	//	RValue<SByte16> operator=(RValue<SByte16> rhs) const;

-	//	RValue<SByte16> operator=(const SByte16 &rhs) const;

-	//	RValue<SByte16> operator=(const Reference<SByte16> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-//	RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator*(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator/(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator%(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator&(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator|(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator^(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator<<(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator>>(RValue<SByte16> lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator+=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator-=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator*=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator/=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator%=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator&=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator|=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator^=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator<<=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator>>=(const SByte16 &lhs, RValue<SByte16> rhs);

-//	RValue<SByte16> operator+(RValue<SByte16> val);

-//	RValue<SByte16> operator-(RValue<SByte16> val);

-//	RValue<SByte16> operator~(RValue<SByte16> val);

-//	RValue<SByte16> operator++(const SByte16 &val, int);   // Post-increment

-//	const SByte16 &operator++(const SByte16 &val);   // Pre-increment

-//	RValue<SByte16> operator--(const SByte16 &val, int);   // Post-decrement

-//	const SByte16 &operator--(const SByte16 &val);   // Pre-decrement

-

-	class Short4 : public Variable<Short4>

-	{

-	public:

-		explicit Short4(RValue<Int> cast);

-		explicit Short4(RValue<Int4> cast);

-	//	explicit Short4(RValue<Float> cast);

-		explicit Short4(RValue<Float4> cast);

-

-		Short4();

-		Short4(short xyzw);

-		Short4(short x, short y, short z, short w);

-		Short4(RValue<Short4> rhs);

-		Short4(const Short4 &rhs);

-		Short4(const Reference<Short4> &rhs);

-		Short4(RValue<UShort4> rhs);

-		Short4(const UShort4 &rhs);

-		Short4(const Reference<UShort4> &rhs);

-

-		RValue<Short4> operator=(RValue<Short4> rhs) const;

-		RValue<Short4> operator=(const Short4 &rhs) const;

-		RValue<Short4> operator=(const Reference<Short4> &rhs) const;

-		RValue<Short4> operator=(RValue<UShort4> rhs) const;

-		RValue<Short4> operator=(const UShort4 &rhs) const;

-		RValue<Short4> operator=(const Reference<UShort4> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);

-	RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);

-	RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs);

-//	RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs);

-//	RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs);

-	RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs);

-	RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs);

-	RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs);

-	RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs);

-	RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs);

-	RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs);

-	RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs);

-	RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs);

-	RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs);

-	RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs);

-//	RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs);

-//	RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs);

-	RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs);

-	RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs);

-	RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs);

-	RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs);

-	RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs);

-	RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs);

-	RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs);

-//	RValue<Short4> operator+(RValue<Short4> val);

-	RValue<Short4> operator-(RValue<Short4> val);

-	RValue<Short4> operator~(RValue<Short4> val);

-//	RValue<Short4> operator++(const Short4 &val, int);   // Post-increment

-//	const Short4 &operator++(const Short4 &val);   // Pre-increment

-//	RValue<Short4> operator--(const Short4 &val, int);   // Post-decrement

-//	const Short4 &operator--(const Short4 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<Short4> lhs, RValue<Short4> rhs);

-//	RValue<Bool> operator<=(RValue<Short4> lhs, RValue<Short4> rhs);

-//	RValue<Bool> operator>(RValue<Short4> lhs, RValue<Short4> rhs);

-//	RValue<Bool> operator>=(RValue<Short4> lhs, RValue<Short4> rhs);

-//	RValue<Bool> operator!=(RValue<Short4> lhs, RValue<Short4> rhs);

-//	RValue<Bool> operator==(RValue<Short4> lhs, RValue<Short4> rhs);

-

-	RValue<Short4> RoundShort4(RValue<Float4> cast);

-	RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y);

-	RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y);

-	RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y);

-	RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);

-	RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);

-	RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);

-	RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y);

-	RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);

-	RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);

-	RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select);

-	RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i);

-	RValue<Short> Extract(RValue<Short4> val, int i);

-	RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y);

-	RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y);

-

-	class UShort4 : public Variable<UShort4>

-	{

-	public:

-		explicit UShort4(RValue<Int4> cast);

-		explicit UShort4(RValue<Float4> cast, bool saturate = false);

-

-		UShort4();

-		UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);

-		UShort4(RValue<UShort4> rhs);

-		UShort4(const UShort4 &rhs);

-		UShort4(const Reference<UShort4> &rhs);

-		UShort4(RValue<Short4> rhs);

-		UShort4(const Short4 &rhs);

-		UShort4(const Reference<Short4> &rhs);

-

-		RValue<UShort4> operator=(RValue<UShort4> rhs) const;

-		RValue<UShort4> operator=(const UShort4 &rhs) const;

-		RValue<UShort4> operator=(const Reference<UShort4> &rhs) const;

-		RValue<UShort4> operator=(RValue<Short4> rhs) const;

-		RValue<UShort4> operator=(const Short4 &rhs) const;

-		RValue<UShort4> operator=(const Reference<Short4> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);

-	RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);

-	RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);

-	RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);

-	RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);

-	RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs);

-	RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs);

-//	RValue<UShort4> operator+=(const UShort4 &lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator-=(const UShort4 &lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator*=(const UShort4 &lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator/=(const UShort4 &lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator%=(const UShort4 &lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator&=(const UShort4 &lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator|=(const UShort4 &lhs, RValue<UShort4> rhs);

-//	RValue<UShort4> operator^=(const UShort4 &lhs, RValue<UShort4> rhs);

-	RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs);

-	RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs);

-	RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs);

-	RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs);

-//	RValue<UShort4> operator+(RValue<UShort4> val);

-//	RValue<UShort4> operator-(RValue<UShort4> val);

-	RValue<UShort4> operator~(RValue<UShort4> val);

-//	RValue<UShort4> operator++(const UShort4 &val, int);   // Post-increment

-//	const UShort4 &operator++(const UShort4 &val);   // Pre-increment

-//	RValue<UShort4> operator--(const UShort4 &val, int);   // Post-decrement

-//	const UShort4 &operator--(const UShort4 &val);   // Pre-decrement

-

-	RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);

-	RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);

-	RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);

-	RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);

-	RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);

-	RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);

-	RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y);

-

-	class Short8 : public Variable<Short8>

-	{

-	public:

-	//	Short8();

-		Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);

-		Short8(RValue<Short8> rhs);

-	//	Short8(const Short8 &rhs);

-	//	Short8(const Reference<Short8> &rhs);

-		Short8(RValue<Short4> lo, RValue<Short4> hi);

-

-	//	RValue<Short8> operator=(RValue<Short8> rhs) const;

-	//	RValue<Short8> operator=(const Short8 &rhs) const;

-	//	RValue<Short8> operator=(const Reference<Short8> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator*(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator/(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator%(RValue<Short8> lhs, RValue<Short8> rhs);

-	RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator|(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator^(RValue<Short8> lhs, RValue<Short8> rhs);

-	RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs);

-	RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs);

-//	RValue<Short8> operator<<(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator>>(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator+=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator-=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator*=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator/=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator%=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator&=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator|=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator^=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator<<=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator>>=(const Short8 &lhs, RValue<Short8> rhs);

-//	RValue<Short8> operator+(RValue<Short8> val);

-//	RValue<Short8> operator-(RValue<Short8> val);

-//	RValue<Short8> operator~(RValue<Short8> val);

-//	RValue<Short8> operator++(const Short8 &val, int);   // Post-increment

-//	const Short8 &operator++(const Short8 &val);   // Pre-increment

-//	RValue<Short8> operator--(const Short8 &val, int);   // Post-decrement

-//	const Short8 &operator--(const Short8 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Bool> operator<=(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Bool> operator>(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Bool> operator>=(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Bool> operator!=(RValue<Short8> lhs, RValue<Short8> rhs);

-//	RValue<Bool> operator==(RValue<Short8> lhs, RValue<Short8> rhs);

-

-	RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y);

-	RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y);

-	RValue<Int4> Abs(RValue<Int4> x);

-

-	class UShort8 : public Variable<UShort8>

-	{

-	public:

-	//	UShort8();

-		UShort8(unsigned short c0, unsigned short c1, unsigned short c2, unsigned short c3, unsigned short c4, unsigned short c5, unsigned short c6, unsigned short c7);

-		UShort8(RValue<UShort8> rhs);

-	//	UShort8(const UShort8 &rhs);

-	//	UShort8(const Reference<UShort8> &rhs);

-		UShort8(RValue<UShort4> lo, RValue<UShort4> hi);

-

-		RValue<UShort8> operator=(RValue<UShort8> rhs) const;

-		RValue<UShort8> operator=(const UShort8 &rhs) const;

-		RValue<UShort8> operator=(const Reference<UShort8> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);

-	RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator/(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator%(RValue<UShort8> lhs, RValue<UShort8> rhs);

-	RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator|(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator^(RValue<UShort8> lhs, RValue<UShort8> rhs);

-	RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs);

-	RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs);

-//	RValue<UShort8> operator<<(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator>>(RValue<UShort8> lhs, RValue<UShort8> rhs);

-	RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator-=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator*=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator/=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator%=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator&=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator|=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator^=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator<<=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator>>=(const UShort8 &lhs, RValue<UShort8> rhs);

-//	RValue<UShort8> operator+(RValue<UShort8> val);

-//	RValue<UShort8> operator-(RValue<UShort8> val);

-	RValue<UShort8> operator~(RValue<UShort8> val);

-//	RValue<UShort8> operator++(const UShort8 &val, int);   // Post-increment

-//	const UShort8 &operator++(const UShort8 &val);   // Pre-increment

-//	RValue<UShort8> operator--(const UShort8 &val, int);   // Post-decrement

-//	const UShort8 &operator--(const UShort8 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<Bool> operator<=(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<Bool> operator>(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<Bool> operator>=(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<Bool> operator!=(RValue<UShort8> lhs, RValue<UShort8> rhs);

-//	RValue<Bool> operator==(RValue<UShort8> lhs, RValue<UShort8> rhs);

-

-    RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7);

-    RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y);

-

-	class Int : public Variable<Int>

-	{

-	public:

-		Int(Argument<Int> argument);

-

-		explicit Int(RValue<Byte> cast);

-		explicit Int(RValue<SByte> cast);

-		explicit Int(RValue<Short> cast);

-		explicit Int(RValue<UShort> cast);

-		explicit Int(RValue<Int2> cast);

-		explicit Int(RValue<Long> cast);

-		explicit Int(RValue<Float> cast);

-

-		Int();

-		Int(int x);

-		Int(RValue<Int> rhs);

-		Int(RValue<UInt> rhs);

-		Int(const Int &rhs);

-		Int(const UInt &rhs);

-		Int(const Reference<Int> &rhs);

-		Int(const Reference<UInt> &rhs);

-

-		RValue<Int> operator=(int rhs) const;

-		RValue<Int> operator=(RValue<Int> rhs) const;

-		RValue<Int> operator=(RValue<UInt> rhs) const;

-		RValue<Int> operator=(const Int &rhs) const;

-		RValue<Int> operator=(const UInt &rhs) const;

-		RValue<Int> operator=(const Reference<Int> &rhs) const;

-		RValue<Int> operator=(const Reference<UInt> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);

-    RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs);

-	RValue<Int> operator+(RValue<Int> val);

-	RValue<Int> operator-(RValue<Int> val);

-	RValue<Int> operator~(RValue<Int> val);

-	RValue<Int> operator++(const Int &val, int);   // Post-increment

-	const Int &operator++(const Int &val);   // Pre-increment

-	RValue<Int> operator--(const Int &val, int);   // Post-decrement

-	const Int &operator--(const Int &val);   // Pre-decrement

-	RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs);

-	RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs);

-

-	RValue<Int> Max(RValue<Int> x, RValue<Int> y);

-	RValue<Int> Min(RValue<Int> x, RValue<Int> y);

-	RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max);

-    RValue<Int> RoundInt(RValue<Float> cast);

-

-	class Long : public Variable<Long>

-	{

-	public:

-	//	Long(Argument<Long> argument);

-

-	//	explicit Long(RValue<Short> cast);

-	//	explicit Long(RValue<UShort> cast);

-		explicit Long(RValue<Int> cast);

-		explicit Long(RValue<UInt> cast);

-	//	explicit Long(RValue<Float> cast);

-

-		Long();

-	//	Long(qword x);

-		Long(RValue<Long> rhs);

-	//	Long(RValue<ULong> rhs);

-	//	Long(const Long &rhs);

-	//	Long(const Reference<Long> &rhs);

-	//	Long(const ULong &rhs);

-	//	Long(const Reference<ULong> &rhs);

-

-		RValue<Long> operator=(int64_t rhs) const;

-		RValue<Long> operator=(RValue<Long> rhs) const;

-	//	RValue<Long> operator=(RValue<ULong> rhs) const;

-		RValue<Long> operator=(const Long &rhs) const;

-		RValue<Long> operator=(const Reference<Long> &rhs) const;

-	//	RValue<Long> operator=(const ULong &rhs) const;

-	//	RValue<Long> operator=(const Reference<ULong> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);

-	RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator/(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator%(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator&(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator|(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator^(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator<<(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs);

-	RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs);

-	RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator*=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator/=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator%=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator&=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator|=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator^=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator<<=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator>>=(const Long &lhs, RValue<Long> rhs);

-//	RValue<Long> operator+(RValue<Long> val);

-//	RValue<Long> operator-(RValue<Long> val);

-//	RValue<Long> operator~(RValue<Long> val);

-//	RValue<Long> operator++(const Long &val, int);   // Post-increment

-//	const Long &operator++(const Long &val);   // Pre-increment

-//	RValue<Long> operator--(const Long &val, int);   // Post-decrement

-//	const Long &operator--(const Long &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Bool> operator<=(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Bool> operator>(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Bool> operator>=(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Bool> operator!=(RValue<Long> lhs, RValue<Long> rhs);

-//	RValue<Bool> operator==(RValue<Long> lhs, RValue<Long> rhs);

-

-//	RValue<Long> RoundLong(RValue<Float> cast);

-    RValue<Long> AddAtomic( RValue<Pointer<Long>> x, RValue<Long> y);

-

-	class Long1 : public Variable<Long1>

-	{

-	public:

-	//	Long1(Argument<Long1> argument);

-

-	//	explicit Long1(RValue<Short> cast);

-	//	explicit Long1(RValue<UShort> cast);

-	//	explicit Long1(RValue<Int> cast);

-		explicit Long1(RValue<UInt> cast);

-	//	explicit Long1(RValue<Float> cast);

-

-	//	Long1();

-	//	Long1(qword x);

-		Long1(RValue<Long1> rhs);

-	//	Long1(RValue<ULong1> rhs);

-	//	Long1(const Long1 &rhs);

-	//	Long1(const Reference<Long1> &rhs);

-	//	Long1(const ULong1 &rhs);

-	//	Long1(const Reference<ULong1> &rhs);

-

-	//	RValue<Long1> operator=(qword rhs) const;

-	//	RValue<Long1> operator=(RValue<Long1> rhs) const;

-	//	RValue<Long1> operator=(RValue<ULong1> rhs) const;

-	//	RValue<Long1> operator=(const Long1 &rhs) const;

-	//	RValue<Long1> operator=(const Reference<Long1> &rhs) const;

-	//	RValue<Long1> operator=(const ULong1 &rhs) const;

-	//	RValue<Long1> operator=(const Reference<ULong1> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-//	RValue<Long1> operator+(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator-(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator*(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator/(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator%(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator&(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator|(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator^(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator<<(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator>>(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator+=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator-=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator*=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator/=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator%=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator&=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator|=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator^=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator<<=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator>>=(const Long1 &lhs, RValue<Long1> rhs);

-//	RValue<Long1> operator+(RValue<Long1> val);

-//	RValue<Long1> operator-(RValue<Long1> val);

-//	RValue<Long1> operator~(RValue<Long1> val);

-//	RValue<Long1> operator++(const Long1 &val, int);   // Post-increment

-//	const Long1 &operator++(const Long1 &val);   // Pre-increment

-//	RValue<Long1> operator--(const Long1 &val, int);   // Post-decrement

-//	const Long1 &operator--(const Long1 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Bool> operator<=(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Bool> operator>(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Bool> operator>=(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Bool> operator!=(RValue<Long1> lhs, RValue<Long1> rhs);

-//	RValue<Bool> operator==(RValue<Long1> lhs, RValue<Long1> rhs);

-

-//	RValue<Long1> RoundLong1(RValue<Float> cast);

-

-	class Long2 : public Variable<Long2>

-	{

-	public:

-	//	explicit Long2(RValue<Long> cast);

-	//	explicit Long2(RValue<Long1> cast);

-

-	//	Long2();

-	//	Long2(int x, int y);

-	//	Long2(RValue<Long2> rhs);

-	//	Long2(const Long2 &rhs);

-	//	Long2(const Reference<Long2> &rhs);

-

-	//	RValue<Long2> operator=(RValue<Long2> rhs) const;

-	//	RValue<Long2> operator=(const Long2 &rhs) const;

-	//	RValue<Long2> operator=(const Reference<Long2 &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-//	RValue<Long2> operator+(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator-(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator*(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator/(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator%(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator&(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator|(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator^(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator<<(RValue<Long2> lhs, unsigned char rhs);

-//	RValue<Long2> operator>>(RValue<Long2> lhs, unsigned char rhs);

-//	RValue<Long2> operator<<(RValue<Long2> lhs, RValue<Long1> rhs);

-//	RValue<Long2> operator>>(RValue<Long2> lhs, RValue<Long1> rhs);

-//	RValue<Long2> operator+=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator-=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator*=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator/=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator%=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator&=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator|=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator^=(const Long2 &lhs, RValue<Long2> rhs);

-//	RValue<Long2> operator<<=(const Long2 &lhs, unsigned char rhs);

-//	RValue<Long2> operator>>=(const Long2 &lhs, unsigned char rhs);

-//	RValue<Long2> operator<<=(const Long2 &lhs, RValue<Long1> rhs);

-//	RValue<Long2> operator>>=(const Long2 &lhs, RValue<Long1> rhs);

-//	RValue<Long2> operator+(RValue<Long2> val);

-//	RValue<Long2> operator-(RValue<Long2> val);

-//	RValue<Long2> operator~(RValue<Long2> val);

-//	RValue<Long2> operator++(const Long2 &val, int);   // Post-increment

-//	const Long2 &operator++(const Long2 &val);   // Pre-increment

-//	RValue<Long2> operator--(const Long2 &val, int);   // Post-decrement

-//	const Long2 &operator--(const Long2 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Bool> operator<=(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Bool> operator>(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Bool> operator>=(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Bool> operator!=(RValue<Long2> lhs, RValue<Long2> rhs);

-//	RValue<Bool> operator==(RValue<Long2> lhs, RValue<Long2> rhs);

-

-//	RValue<Long2> RoundInt(RValue<Float4> cast);

-//	RValue<Long2> UnpackLow(RValue<Long2> x, RValue<Long2> y);

-	RValue<Long2> UnpackHigh(RValue<Long2> x, RValue<Long2> y);

-//	RValue<Int> Extract(RValue<Long2> val, int i);

-//	RValue<Long2> Insert(RValue<Long2> val, RValue<Int> element, int i);

-

-	class UInt : public Variable<UInt>

-	{

-	public:

-		UInt(Argument<UInt> argument);

-

-		explicit UInt(RValue<UShort> cast);

-		explicit UInt(RValue<Long> cast);

-		explicit UInt(RValue<Float> cast);

-

-		UInt();

-		UInt(int x);

-		UInt(unsigned int x);

-		UInt(RValue<UInt> rhs);

-		UInt(RValue<Int> rhs);

-		UInt(const UInt &rhs);

-		UInt(const Int &rhs);

-		UInt(const Reference<UInt> &rhs);

-		UInt(const Reference<Int> &rhs);

-

-		RValue<UInt> operator=(unsigned int rhs) const;

-		RValue<UInt> operator=(RValue<UInt> rhs) const;

-		RValue<UInt> operator=(RValue<Int> rhs) const;

-		RValue<UInt> operator=(const UInt &rhs) const;

-		RValue<UInt> operator=(const Int &rhs) const;

-		RValue<UInt> operator=(const Reference<UInt> &rhs) const;

-		RValue<UInt> operator=(const Reference<Int> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-	RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs);

-	RValue<UInt> operator+(RValue<UInt> val);

-	RValue<UInt> operator-(RValue<UInt> val);

-	RValue<UInt> operator~(RValue<UInt> val);

-	RValue<UInt> operator++(const UInt &val, int);   // Post-increment

-	const UInt &operator++(const UInt &val);   // Pre-increment

-	RValue<UInt> operator--(const UInt &val, int);   // Post-decrement

-	const UInt &operator--(const UInt &val);   // Pre-decrement

-	RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs);

-	RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs);

-

-	RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y);

-	RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y);

-	RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);

-//	RValue<UInt> RoundUInt(RValue<Float> cast);

-

-	class Int2 : public Variable<Int2>

-	{

-	public:

-	//	explicit Int2(RValue<Int> cast);

-		explicit Int2(RValue<Int4> cast);

-

-		Int2();

-		Int2(int x, int y);

-		Int2(RValue<Int2> rhs);

-		Int2(const Int2 &rhs);

-		Int2(const Reference<Int2> &rhs);

-		Int2(RValue<Int> lo, RValue<Int> hi);

-

-		RValue<Int2> operator=(RValue<Int2> rhs) const;

-		RValue<Int2> operator=(const Int2 &rhs) const;

-		RValue<Int2> operator=(const Reference<Int2> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-    RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);

-    RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs);

-    RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs);

-    RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs);

-    RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs);

-    RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs);

-    RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs);

-    RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs);

-    RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs);

-    RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs);

-    RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs);

-//	RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs);

-//	RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs);

-//	RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs);

-    RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs);

-    RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs);

-    RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs);

-    RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs);

-    RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs);

-    RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs);

-    RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs);

-//	RValue<Int2> operator+(RValue<Int2> val);

-//	RValue<Int2> operator-(RValue<Int2> val);

-    RValue<Int2> operator~(RValue<Int2> val);

-//	RValue<Int2> operator++(const Int2 &val, int);   // Post-increment

-//	const Int2 &operator++(const Int2 &val);   // Pre-increment

-//	RValue<Int2> operator--(const Int2 &val, int);   // Post-decrement

-//	const Int2 &operator--(const Int2 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Bool> operator<=(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Bool> operator>(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Bool> operator>=(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Bool> operator!=(RValue<Int2> lhs, RValue<Int2> rhs);

-//	RValue<Bool> operator==(RValue<Int2> lhs, RValue<Int2> rhs);

-

-//	RValue<Int2> RoundInt(RValue<Float4> cast);

-	RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y);

-	RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y);

-	RValue<Int> Extract(RValue<Int2> val, int i);

-	RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i);

-

-	class UInt2 : public Variable<UInt2>

-	{

-	public:

-		UInt2();

-		UInt2(unsigned int x, unsigned int y);

-		UInt2(RValue<UInt2> rhs);

-		UInt2(const UInt2 &rhs);

-		UInt2(const Reference<UInt2> &rhs);

-

-		RValue<UInt2> operator=(RValue<UInt2> rhs) const;

-		RValue<UInt2> operator=(const UInt2 &rhs) const;

-		RValue<UInt2> operator=(const Reference<UInt2> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-    RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs);

-    RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs);

-    RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs);

-    RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs);

-    RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs);

-//	RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs);

-//	RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs);

-//	RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs);

-    RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs);

-    RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs);

-    RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs);

-    RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs);

-//	RValue<UInt2> operator+(RValue<UInt2> val);

-//	RValue<UInt2> operator-(RValue<UInt2> val);

-    RValue<UInt2> operator~(RValue<UInt2> val);

-//	RValue<UInt2> operator++(const UInt2 &val, int);   // Post-increment

-//	const UInt2 &operator++(const UInt2 &val);   // Pre-increment

-//	RValue<UInt2> operator--(const UInt2 &val, int);   // Post-decrement

-//	const UInt2 &operator--(const UInt2 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<Bool> operator<=(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<Bool> operator>(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<Bool> operator>=(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<Bool> operator!=(RValue<UInt2> lhs, RValue<UInt2> rhs);

-//	RValue<Bool> operator==(RValue<UInt2> lhs, RValue<UInt2> rhs);

-

-//	RValue<UInt2> RoundInt(RValue<Float4> cast);

-

-	class Int4 : public Variable<Int4>

-	{

-	public:

-		explicit Int4(RValue<Float4> cast);

-		explicit Int4(RValue<Short4> cast);

-		explicit Int4(RValue<UShort4> cast);

-

-		Int4();

-		Int4(int xyzw);

-		Int4(int x, int yzw);

-		Int4(int x, int y, int zw);

-		Int4(int x, int y, int z, int w);

-		Int4(RValue<Int4> rhs);

-		Int4(const Int4 &rhs);

-		Int4(const Reference<Int4> &rhs);

-		Int4(RValue<UInt4> rhs);

-		Int4(const UInt4 &rhs);

-		Int4(const Reference<UInt4> &rhs);

-		Int4(RValue<Int2> lo, RValue<Int2> hi);

-

-		RValue<Int4> operator=(RValue<Int4> rhs) const;

-		RValue<Int4> operator=(const Int4 &rhs) const;

-		RValue<Int4> operator=(const Reference<Int4> &rhs) const;

-

-		static llvm::Type *getType();

-

-	private:

-		void constant(int x, int y, int z, int w);

-	};

-

-    RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs);

-    RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs);

-    RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs);

-    RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs);

-    RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs);

-    RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs);

-//	RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs);

-//	RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs);

-    RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs);

-    RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs);

-    RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs);

-    RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs);

-    RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs);

-    RValue<Int4> operator+(RValue<Int4> val);

-    RValue<Int4> operator-(RValue<Int4> val);

-    RValue<Int4> operator~(RValue<Int4> val);

-//	RValue<Int4> operator++(const Int4 &val, int);   // Post-increment

-//	const Int4 &operator++(const Int4 &val);   // Pre-increment

-//	RValue<Int4> operator--(const Int4 &val, int);   // Post-decrement

-//	const Int4 &operator--(const Int4 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<Int4> lhs, RValue<Int4> rhs);

-//	RValue<Bool> operator<=(RValue<Int4> lhs, RValue<Int4> rhs);

-//	RValue<Bool> operator>(RValue<Int4> lhs, RValue<Int4> rhs);

-//	RValue<Bool> operator>=(RValue<Int4> lhs, RValue<Int4> rhs);

-//	RValue<Bool> operator!=(RValue<Int4> lhs, RValue<Int4> rhs);

-//	RValue<Bool> operator==(RValue<Int4> lhs, RValue<Int4> rhs);

-

-	RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int4> RoundInt(RValue<Float4> cast);

-	RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y);

-	RValue<Int> Extract(RValue<Int4> x, int i);

-	RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);

-	RValue<Int> SignMask(RValue<Int4> x);

-	RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select);

-

-	class UInt4 : public Variable<UInt4>

-	{

-	public:

-		explicit UInt4(RValue<Float4> cast);

-

-		UInt4();

-		UInt4(int xyzw);

-		UInt4(int x, int yzw);

-		UInt4(int x, int y, int zw);

-		UInt4(int x, int y, int z, int w);

-		UInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w);

-		UInt4(RValue<UInt4> rhs);

-		UInt4(const UInt4 &rhs);

-		UInt4(const Reference<UInt4> &rhs);

-		UInt4(RValue<Int4> rhs);

-		UInt4(const Int4 &rhs);

-		UInt4(const Reference<Int4> &rhs);

-		UInt4(RValue<UInt2> lo, RValue<UInt2> hi);

-

-		RValue<UInt4> operator=(RValue<UInt4> rhs) const;

-		RValue<UInt4> operator=(const UInt4 &rhs) const;

-		RValue<UInt4> operator=(const Reference<UInt4> &rhs) const;

-

-		static llvm::Type *getType();

-

-	private:

-		void constant(int x, int y, int z, int w);

-	};

-

-    RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs);

-    RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs);

-    RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs);

-//	RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs);

-//	RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs);

-    RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs);

-    RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs);

-    RValue<UInt4> operator+(RValue<UInt4> val);

-    RValue<UInt4> operator-(RValue<UInt4> val);

-    RValue<UInt4> operator~(RValue<UInt4> val);

-//	RValue<UInt4> operator++(const UInt4 &val, int);   // Post-increment

-//	const UInt4 &operator++(const UInt4 &val);   // Pre-increment

-//	RValue<UInt4> operator--(const UInt4 &val, int);   // Post-decrement

-//	const UInt4 &operator--(const UInt4 &val);   // Pre-decrement

-//	RValue<Bool> operator<(RValue<UInt4> lhs, RValue<UInt4> rhs);

-//	RValue<Bool> operator<=(RValue<UInt4> lhs, RValue<UInt4> rhs);

-//	RValue<Bool> operator>(RValue<UInt4> lhs, RValue<UInt4> rhs);

-//	RValue<Bool> operator>=(RValue<UInt4> lhs, RValue<UInt4> rhs);

-//	RValue<Bool> operator!=(RValue<UInt4> lhs, RValue<UInt4> rhs);

-//	RValue<Bool> operator==(RValue<UInt4> lhs, RValue<UInt4> rhs);

-

-	RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y);

-	RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y);

-	RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y);

-	RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y);

-	RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y);

-	RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y);

-	RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);

-	RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);

-//	RValue<UInt4> RoundInt(RValue<Float4> cast);

-	RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y);

-

-	template<int T>

-	class Swizzle2Float4

-	{

-		friend class Float4;

-

-	public:

-		operator RValue<Float4>() const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleFloat4

-	{

-	public:

-		operator RValue<Float4>() const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleMaskFloat4

-	{

-		friend class Float4;

-

-	public:

-		operator RValue<Float4>() const;

-

-		RValue<Float4> operator=(RValue<Float4> rhs) const;

-		RValue<Float4> operator=(RValue<Float> rhs) const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleMask1Float4

-	{

-	public:

-		operator RValue<Float>() const;

-		operator RValue<Float4>() const;

-

-		RValue<Float4> operator=(float x) const;

-		RValue<Float4> operator=(RValue<Float4> rhs) const;

-		RValue<Float4> operator=(RValue<Float> rhs) const;

-

-	private:

-		Float4 *parent;

-	};

-

-	template<int T>

-	class SwizzleMask2Float4

-	{

-		friend class Float4;

-

-	public:

-		operator RValue<Float4>() const;

-

-		RValue<Float4> operator=(RValue<Float4> rhs) const;

-

-	private:

-		Float4 *parent;

-	};

-

-	class Float : public Variable<Float>

-	{

-	public:

-		explicit Float(RValue<Int> cast);

-

-		Float();

-		Float(float x);

-		Float(RValue<Float> rhs);

-		Float(const Float &rhs);

-		Float(const Reference<Float> &rhs);

-

-		template<int T>

-		Float(const SwizzleMask1Float4<T> &rhs);

-

-	//	RValue<Float> operator=(float rhs) const;   // FIXME: Implement

-		RValue<Float> operator=(RValue<Float> rhs) const;

-		RValue<Float> operator=(const Float &rhs) const;

-		RValue<Float> operator=(const Reference<Float> &rhs) const;

-

-		template<int T>

-		RValue<Float> operator=(const SwizzleMask1Float4<T> &rhs) const;

-

-		static llvm::Type *getType();

-	};

-

-    RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs);

-    RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs);

-    RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs);

-    RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs);

-    RValue<Float> operator+(RValue<Float> val);

-    RValue<Float> operator-(RValue<Float> val);

-    RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs);

-    RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs);

-

-	RValue<Float> Abs(RValue<Float> x);

-	RValue<Float> Max(RValue<Float> x, RValue<Float> y);

-	RValue<Float> Min(RValue<Float> x, RValue<Float> y);

-	RValue<Float> Rcp_pp(RValue<Float> val, bool exactAtPow2 = false);

-	RValue<Float> RcpSqrt_pp(RValue<Float> val);

-	RValue<Float> Sqrt(RValue<Float> x);

-	RValue<Float> Round(RValue<Float> val);

-	RValue<Float> Trunc(RValue<Float> val);

-	RValue<Float> Frac(RValue<Float> val);

-	RValue<Float> Floor(RValue<Float> val);

-	RValue<Float> Ceil(RValue<Float> val);

-

-	class Float2 : public Variable<Float2>

-	{

-	public:

-	//	explicit Float2(RValue<Byte2> cast);

-	//	explicit Float2(RValue<Short2> cast);

-	//	explicit Float2(RValue<UShort2> cast);

-	//	explicit Float2(RValue<Int2> cast);

-	//	explicit Float2(RValue<UInt2> cast);

-		explicit Float2(RValue<Float4> cast);

-

-	//	Float2();

-	//	Float2(float x, float y);

-	//	Float2(RValue<Float2> rhs);

-	//	Float2(const Float2 &rhs);

-	//	Float2(const Reference<Float2> &rhs);

-	//	Float2(RValue<Float> rhs);

-	//	Float2(const Float &rhs);

-	//	Float2(const Reference<Float> &rhs);

-

-	//	template<int T>

-	//	Float2(const SwizzleMask1Float4<T> &rhs);

-

-	//	RValue<Float2> operator=(float replicate) const;

-	//	RValue<Float2> operator=(RValue<Float2> rhs) const;

-	//	RValue<Float2> operator=(const Float2 &rhs) const;

-	//	RValue<Float2> operator=(const Reference<Float2> &rhs) const;

-	//	RValue<Float2> operator=(RValue<Float> rhs) const;

-	//	RValue<Float2> operator=(const Float &rhs) const;

-	//	RValue<Float2> operator=(const Reference<Float> &rhs) const;

-

-	//	template<int T>

-	//	RValue<Float2> operator=(const SwizzleMask1Float4<T> &rhs);

-

-		static llvm::Type *getType();

-	};

-

-//	RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator/(RValue<Float2> lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator%(RValue<Float2> lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator+=(const Float2 &lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator-=(const Float2 &lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator*=(const Float2 &lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator/=(const Float2 &lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator%=(const Float2 &lhs, RValue<Float2> rhs);

-//	RValue<Float2> operator+(RValue<Float2> val);

-//	RValue<Float2> operator-(RValue<Float2> val);

-

-//	RValue<Float2> Abs(RValue<Float2> x);

-//	RValue<Float2> Max(RValue<Float2> x, RValue<Float2> y);

-//	RValue<Float2> Min(RValue<Float2> x, RValue<Float2> y);

-//	RValue<Float2> Swizzle(RValue<Float2> x, unsigned char select);

-//	RValue<Float2> Mask(Float2 &lhs, RValue<Float2> rhs, unsigned char select);

-

-	class Float4 : public Variable<Float4>

-	{

-	public:

-		explicit Float4(RValue<Byte4> cast);

-		explicit Float4(RValue<SByte4> cast);

-		explicit Float4(RValue<Short4> cast);

-		explicit Float4(RValue<UShort4> cast);

-		explicit Float4(RValue<Int4> cast);

-		explicit Float4(RValue<UInt4> cast);

-

-		Float4();

-		Float4(float xyzw);

-		Float4(float x, float yzw);

-		Float4(float x, float y, float zw);

-		Float4(float x, float y, float z, float w);

-		Float4(RValue<Float4> rhs);

-		Float4(const Float4 &rhs);

-		Float4(const Reference<Float4> &rhs);

-		Float4(RValue<Float> rhs);

-		Float4(const Float &rhs);

-		Float4(const Reference<Float> &rhs);

-

-		template<int T>

-		Float4(const SwizzleMask1Float4<T> &rhs);

-		template<int T>

-		Float4(const SwizzleFloat4<T> &rhs);

-		template<int X, int Y>

-		Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y);

-		template<int X, int Y>

-		Float4(const SwizzleMask2Float4<X> &x, const Swizzle2Float4<Y> &y);

-		template<int X, int Y>

-		Float4(const Swizzle2Float4<X> &x, const SwizzleMask2Float4<Y> &y);

-		template<int X, int Y>

-		Float4(const SwizzleMask2Float4<X> &x, const SwizzleMask2Float4<Y> &y);

-

-		RValue<Float4> operator=(float replicate) const;

-		RValue<Float4> operator=(RValue<Float4> rhs) const;

-		RValue<Float4> operator=(const Float4 &rhs) const;

-		RValue<Float4> operator=(const Reference<Float4> &rhs) const;

-		RValue<Float4> operator=(RValue<Float> rhs) const;

-		RValue<Float4> operator=(const Float &rhs) const;

-		RValue<Float4> operator=(const Reference<Float> &rhs) const;

-

-		template<int T>

-		RValue<Float4> operator=(const SwizzleMask1Float4<T> &rhs);

-		template<int T>

-		RValue<Float4> operator=(const SwizzleFloat4<T> &rhs);

-

-		static llvm::Type *getType();

-

-		union

-		{

-			SwizzleMask1Float4<0x00> x;

-			SwizzleMask1Float4<0x55> y;

-			SwizzleMask1Float4<0xAA> z;

-			SwizzleMask1Float4<0xFF> w;

-			Swizzle2Float4<0x00>     xx;

-			Swizzle2Float4<0x01>     yx;

-			Swizzle2Float4<0x02>     zx;

-			Swizzle2Float4<0x03>     wx;

-			SwizzleMask2Float4<0x54> xy;

-			Swizzle2Float4<0x55>     yy;

-			Swizzle2Float4<0x56>     zy;

-			Swizzle2Float4<0x57>     wy;

-			SwizzleMask2Float4<0xA8> xz;

-			SwizzleMask2Float4<0xA9> yz;

-			Swizzle2Float4<0xAA>     zz;

-			Swizzle2Float4<0xAB>     wz;

-			SwizzleMask2Float4<0xFC> xw;

-			SwizzleMask2Float4<0xFD> yw;

-			SwizzleMask2Float4<0xFE> zw;

-			Swizzle2Float4<0xFF>     ww;

-			SwizzleFloat4<0x00>      xxx;

-			SwizzleFloat4<0x01>      yxx;

-			SwizzleFloat4<0x02>      zxx;

-			SwizzleFloat4<0x03>      wxx;

-			SwizzleFloat4<0x04>      xyx;

-			SwizzleFloat4<0x05>      yyx;

-			SwizzleFloat4<0x06>      zyx;

-			SwizzleFloat4<0x07>      wyx;

-			SwizzleFloat4<0x08>      xzx;

-			SwizzleFloat4<0x09>      yzx;

-			SwizzleFloat4<0x0A>      zzx;

-			SwizzleFloat4<0x0B>      wzx;

-			SwizzleFloat4<0x0C>      xwx;

-			SwizzleFloat4<0x0D>      ywx;

-			SwizzleFloat4<0x0E>      zwx;

-			SwizzleFloat4<0x0F>      wwx;

-			SwizzleFloat4<0x50>      xxy;

-			SwizzleFloat4<0x51>      yxy;

-			SwizzleFloat4<0x52>      zxy;

-			SwizzleFloat4<0x53>      wxy;

-			SwizzleFloat4<0x54>      xyy;

-			SwizzleFloat4<0x55>      yyy;

-			SwizzleFloat4<0x56>      zyy;

-			SwizzleFloat4<0x57>      wyy;

-			SwizzleFloat4<0x58>      xzy;

-			SwizzleFloat4<0x59>      yzy;

-			SwizzleFloat4<0x5A>      zzy;

-			SwizzleFloat4<0x5B>      wzy;

-			SwizzleFloat4<0x5C>      xwy;

-			SwizzleFloat4<0x5D>      ywy;

-			SwizzleFloat4<0x5E>      zwy;

-			SwizzleFloat4<0x5F>      wwy;

-			SwizzleFloat4<0xA0>      xxz;

-			SwizzleFloat4<0xA1>      yxz;

-			SwizzleFloat4<0xA2>      zxz;

-			SwizzleFloat4<0xA3>      wxz;

-			SwizzleMaskFloat4<0xA4>  xyz;

-			SwizzleFloat4<0xA5>      yyz;

-			SwizzleFloat4<0xA6>      zyz;

-			SwizzleFloat4<0xA7>      wyz;

-			SwizzleFloat4<0xA8>      xzz;

-			SwizzleFloat4<0xA9>      yzz;

-			SwizzleFloat4<0xAA>      zzz;

-			SwizzleFloat4<0xAB>      wzz;

-			SwizzleFloat4<0xAC>      xwz;

-			SwizzleFloat4<0xAD>      ywz;

-			SwizzleFloat4<0xAE>      zwz;

-			SwizzleFloat4<0xAF>      wwz;

-			SwizzleFloat4<0xF0>      xxw;

-			SwizzleFloat4<0xF1>      yxw;

-			SwizzleFloat4<0xF2>      zxw;

-			SwizzleFloat4<0xF3>      wxw;

-			SwizzleMaskFloat4<0xF4>  xyw;

-			SwizzleFloat4<0xF5>      yyw;

-			SwizzleFloat4<0xF6>      zyw;

-			SwizzleFloat4<0xF7>      wyw;

-			SwizzleMaskFloat4<0xF8>  xzw;

-			SwizzleMaskFloat4<0xF9>  yzw;

-			SwizzleFloat4<0xFA>      zzw;

-			SwizzleFloat4<0xFB>      wzw;

-			SwizzleFloat4<0xFC>      xww;

-			SwizzleFloat4<0xFD>      yww;

-			SwizzleFloat4<0xFE>      zww;

-			SwizzleFloat4<0xFF>      www;

-			SwizzleFloat4<0x00>      xxxx;

-			SwizzleFloat4<0x01>      yxxx;

-			SwizzleFloat4<0x02>      zxxx;

-			SwizzleFloat4<0x03>      wxxx;

-			SwizzleFloat4<0x04>      xyxx;

-			SwizzleFloat4<0x05>      yyxx;

-			SwizzleFloat4<0x06>      zyxx;

-			SwizzleFloat4<0x07>      wyxx;

-			SwizzleFloat4<0x08>      xzxx;

-			SwizzleFloat4<0x09>      yzxx;

-			SwizzleFloat4<0x0A>      zzxx;

-			SwizzleFloat4<0x0B>      wzxx;

-			SwizzleFloat4<0x0C>      xwxx;

-			SwizzleFloat4<0x0D>      ywxx;

-			SwizzleFloat4<0x0E>      zwxx;

-			SwizzleFloat4<0x0F>      wwxx;

-			SwizzleFloat4<0x10>      xxyx;

-			SwizzleFloat4<0x11>      yxyx;

-			SwizzleFloat4<0x12>      zxyx;

-			SwizzleFloat4<0x13>      wxyx;

-			SwizzleFloat4<0x14>      xyyx;

-			SwizzleFloat4<0x15>      yyyx;

-			SwizzleFloat4<0x16>      zyyx;

-			SwizzleFloat4<0x17>      wyyx;

-			SwizzleFloat4<0x18>      xzyx;

-			SwizzleFloat4<0x19>      yzyx;

-			SwizzleFloat4<0x1A>      zzyx;

-			SwizzleFloat4<0x1B>      wzyx;

-			SwizzleFloat4<0x1C>      xwyx;

-			SwizzleFloat4<0x1D>      ywyx;

-			SwizzleFloat4<0x1E>      zwyx;

-			SwizzleFloat4<0x1F>      wwyx;

-			SwizzleFloat4<0x20>      xxzx;

-			SwizzleFloat4<0x21>      yxzx;

-			SwizzleFloat4<0x22>      zxzx;

-			SwizzleFloat4<0x23>      wxzx;

-			SwizzleFloat4<0x24>      xyzx;

-			SwizzleFloat4<0x25>      yyzx;

-			SwizzleFloat4<0x26>      zyzx;

-			SwizzleFloat4<0x27>      wyzx;

-			SwizzleFloat4<0x28>      xzzx;

-			SwizzleFloat4<0x29>      yzzx;

-			SwizzleFloat4<0x2A>      zzzx;

-			SwizzleFloat4<0x2B>      wzzx;

-			SwizzleFloat4<0x2C>      xwzx;

-			SwizzleFloat4<0x2D>      ywzx;

-			SwizzleFloat4<0x2E>      zwzx;

-			SwizzleFloat4<0x2F>      wwzx;

-			SwizzleFloat4<0x30>      xxwx;

-			SwizzleFloat4<0x31>      yxwx;

-			SwizzleFloat4<0x32>      zxwx;

-			SwizzleFloat4<0x33>      wxwx;

-			SwizzleFloat4<0x34>      xywx;

-			SwizzleFloat4<0x35>      yywx;

-			SwizzleFloat4<0x36>      zywx;

-			SwizzleFloat4<0x37>      wywx;

-			SwizzleFloat4<0x38>      xzwx;

-			SwizzleFloat4<0x39>      yzwx;

-			SwizzleFloat4<0x3A>      zzwx;

-			SwizzleFloat4<0x3B>      wzwx;

-			SwizzleFloat4<0x3C>      xwwx;

-			SwizzleFloat4<0x3D>      ywwx;

-			SwizzleFloat4<0x3E>      zwwx;

-			SwizzleFloat4<0x3F>      wwwx;

-			SwizzleFloat4<0x40>      xxxy;

-			SwizzleFloat4<0x41>      yxxy;

-			SwizzleFloat4<0x42>      zxxy;

-			SwizzleFloat4<0x43>      wxxy;

-			SwizzleFloat4<0x44>      xyxy;

-			SwizzleFloat4<0x45>      yyxy;

-			SwizzleFloat4<0x46>      zyxy;

-			SwizzleFloat4<0x47>      wyxy;

-			SwizzleFloat4<0x48>      xzxy;

-			SwizzleFloat4<0x49>      yzxy;

-			SwizzleFloat4<0x4A>      zzxy;

-			SwizzleFloat4<0x4B>      wzxy;

-			SwizzleFloat4<0x4C>      xwxy;

-			SwizzleFloat4<0x4D>      ywxy;

-			SwizzleFloat4<0x4E>      zwxy;

-			SwizzleFloat4<0x4F>      wwxy;

-			SwizzleFloat4<0x50>      xxyy;

-			SwizzleFloat4<0x51>      yxyy;

-			SwizzleFloat4<0x52>      zxyy;

-			SwizzleFloat4<0x53>      wxyy;

-			SwizzleFloat4<0x54>      xyyy;

-			SwizzleFloat4<0x55>      yyyy;

-			SwizzleFloat4<0x56>      zyyy;

-			SwizzleFloat4<0x57>      wyyy;

-			SwizzleFloat4<0x58>      xzyy;

-			SwizzleFloat4<0x59>      yzyy;

-			SwizzleFloat4<0x5A>      zzyy;

-			SwizzleFloat4<0x5B>      wzyy;

-			SwizzleFloat4<0x5C>      xwyy;

-			SwizzleFloat4<0x5D>      ywyy;

-			SwizzleFloat4<0x5E>      zwyy;

-			SwizzleFloat4<0x5F>      wwyy;

-			SwizzleFloat4<0x60>      xxzy;

-			SwizzleFloat4<0x61>      yxzy;

-			SwizzleFloat4<0x62>      zxzy;

-			SwizzleFloat4<0x63>      wxzy;

-			SwizzleFloat4<0x64>      xyzy;

-			SwizzleFloat4<0x65>      yyzy;

-			SwizzleFloat4<0x66>      zyzy;

-			SwizzleFloat4<0x67>      wyzy;

-			SwizzleFloat4<0x68>      xzzy;

-			SwizzleFloat4<0x69>      yzzy;

-			SwizzleFloat4<0x6A>      zzzy;

-			SwizzleFloat4<0x6B>      wzzy;

-			SwizzleFloat4<0x6C>      xwzy;

-			SwizzleFloat4<0x6D>      ywzy;

-			SwizzleFloat4<0x6E>      zwzy;

-			SwizzleFloat4<0x6F>      wwzy;

-			SwizzleFloat4<0x70>      xxwy;

-			SwizzleFloat4<0x71>      yxwy;

-			SwizzleFloat4<0x72>      zxwy;

-			SwizzleFloat4<0x73>      wxwy;

-			SwizzleFloat4<0x74>      xywy;

-			SwizzleFloat4<0x75>      yywy;

-			SwizzleFloat4<0x76>      zywy;

-			SwizzleFloat4<0x77>      wywy;

-			SwizzleFloat4<0x78>      xzwy;

-			SwizzleFloat4<0x79>      yzwy;

-			SwizzleFloat4<0x7A>      zzwy;

-			SwizzleFloat4<0x7B>      wzwy;

-			SwizzleFloat4<0x7C>      xwwy;

-			SwizzleFloat4<0x7D>      ywwy;

-			SwizzleFloat4<0x7E>      zwwy;

-			SwizzleFloat4<0x7F>      wwwy;

-			SwizzleFloat4<0x80>      xxxz;

-			SwizzleFloat4<0x81>      yxxz;

-			SwizzleFloat4<0x82>      zxxz;

-			SwizzleFloat4<0x83>      wxxz;

-			SwizzleFloat4<0x84>      xyxz;

-			SwizzleFloat4<0x85>      yyxz;

-			SwizzleFloat4<0x86>      zyxz;

-			SwizzleFloat4<0x87>      wyxz;

-			SwizzleFloat4<0x88>      xzxz;

-			SwizzleFloat4<0x89>      yzxz;

-			SwizzleFloat4<0x8A>      zzxz;

-			SwizzleFloat4<0x8B>      wzxz;

-			SwizzleFloat4<0x8C>      xwxz;

-			SwizzleFloat4<0x8D>      ywxz;

-			SwizzleFloat4<0x8E>      zwxz;

-			SwizzleFloat4<0x8F>      wwxz;

-			SwizzleFloat4<0x90>      xxyz;

-			SwizzleFloat4<0x91>      yxyz;

-			SwizzleFloat4<0x92>      zxyz;

-			SwizzleFloat4<0x93>      wxyz;

-			SwizzleFloat4<0x94>      xyyz;

-			SwizzleFloat4<0x95>      yyyz;

-			SwizzleFloat4<0x96>      zyyz;

-			SwizzleFloat4<0x97>      wyyz;

-			SwizzleFloat4<0x98>      xzyz;

-			SwizzleFloat4<0x99>      yzyz;

-			SwizzleFloat4<0x9A>      zzyz;

-			SwizzleFloat4<0x9B>      wzyz;

-			SwizzleFloat4<0x9C>      xwyz;

-			SwizzleFloat4<0x9D>      ywyz;

-			SwizzleFloat4<0x9E>      zwyz;

-			SwizzleFloat4<0x9F>      wwyz;

-			SwizzleFloat4<0xA0>      xxzz;

-			SwizzleFloat4<0xA1>      yxzz;

-			SwizzleFloat4<0xA2>      zxzz;

-			SwizzleFloat4<0xA3>      wxzz;

-			SwizzleFloat4<0xA4>      xyzz;

-			SwizzleFloat4<0xA5>      yyzz;

-			SwizzleFloat4<0xA6>      zyzz;

-			SwizzleFloat4<0xA7>      wyzz;

-			SwizzleFloat4<0xA8>      xzzz;

-			SwizzleFloat4<0xA9>      yzzz;

-			SwizzleFloat4<0xAA>      zzzz;

-			SwizzleFloat4<0xAB>      wzzz;

-			SwizzleFloat4<0xAC>      xwzz;

-			SwizzleFloat4<0xAD>      ywzz;

-			SwizzleFloat4<0xAE>      zwzz;

-			SwizzleFloat4<0xAF>      wwzz;

-			SwizzleFloat4<0xB0>      xxwz;

-			SwizzleFloat4<0xB1>      yxwz;

-			SwizzleFloat4<0xB2>      zxwz;

-			SwizzleFloat4<0xB3>      wxwz;

-			SwizzleFloat4<0xB4>      xywz;

-			SwizzleFloat4<0xB5>      yywz;

-			SwizzleFloat4<0xB6>      zywz;

-			SwizzleFloat4<0xB7>      wywz;

-			SwizzleFloat4<0xB8>      xzwz;

-			SwizzleFloat4<0xB9>      yzwz;

-			SwizzleFloat4<0xBA>      zzwz;

-			SwizzleFloat4<0xBB>      wzwz;

-			SwizzleFloat4<0xBC>      xwwz;

-			SwizzleFloat4<0xBD>      ywwz;

-			SwizzleFloat4<0xBE>      zwwz;

-			SwizzleFloat4<0xBF>      wwwz;

-			SwizzleFloat4<0xC0>      xxxw;

-			SwizzleFloat4<0xC1>      yxxw;

-			SwizzleFloat4<0xC2>      zxxw;

-			SwizzleFloat4<0xC3>      wxxw;

-			SwizzleFloat4<0xC4>      xyxw;

-			SwizzleFloat4<0xC5>      yyxw;

-			SwizzleFloat4<0xC6>      zyxw;

-			SwizzleFloat4<0xC7>      wyxw;

-			SwizzleFloat4<0xC8>      xzxw;

-			SwizzleFloat4<0xC9>      yzxw;

-			SwizzleFloat4<0xCA>      zzxw;

-			SwizzleFloat4<0xCB>      wzxw;

-			SwizzleFloat4<0xCC>      xwxw;

-			SwizzleFloat4<0xCD>      ywxw;

-			SwizzleFloat4<0xCE>      zwxw;

-			SwizzleFloat4<0xCF>      wwxw;

-			SwizzleFloat4<0xD0>      xxyw;

-			SwizzleFloat4<0xD1>      yxyw;

-			SwizzleFloat4<0xD2>      zxyw;

-			SwizzleFloat4<0xD3>      wxyw;

-			SwizzleFloat4<0xD4>      xyyw;

-			SwizzleFloat4<0xD5>      yyyw;

-			SwizzleFloat4<0xD6>      zyyw;

-			SwizzleFloat4<0xD7>      wyyw;

-			SwizzleFloat4<0xD8>      xzyw;

-			SwizzleFloat4<0xD9>      yzyw;

-			SwizzleFloat4<0xDA>      zzyw;

-			SwizzleFloat4<0xDB>      wzyw;

-			SwizzleFloat4<0xDC>      xwyw;

-			SwizzleFloat4<0xDD>      ywyw;

-			SwizzleFloat4<0xDE>      zwyw;

-			SwizzleFloat4<0xDF>      wwyw;

-			SwizzleFloat4<0xE0>      xxzw;

-			SwizzleFloat4<0xE1>      yxzw;

-			SwizzleFloat4<0xE2>      zxzw;

-			SwizzleFloat4<0xE3>      wxzw;

-			SwizzleMaskFloat4<0xE4>  xyzw;

-			SwizzleFloat4<0xE5>      yyzw;

-			SwizzleFloat4<0xE6>      zyzw;

-			SwizzleFloat4<0xE7>      wyzw;

-			SwizzleFloat4<0xE8>      xzzw;

-			SwizzleFloat4<0xE9>      yzzw;

-			SwizzleFloat4<0xEA>      zzzw;

-			SwizzleFloat4<0xEB>      wzzw;

-			SwizzleFloat4<0xEC>      xwzw;

-			SwizzleFloat4<0xED>      ywzw;

-			SwizzleFloat4<0xEE>      zwzw;

-			SwizzleFloat4<0xEF>      wwzw;

-			SwizzleFloat4<0xF0>      xxww;

-			SwizzleFloat4<0xF1>      yxww;

-			SwizzleFloat4<0xF2>      zxww;

-			SwizzleFloat4<0xF3>      wxww;

-			SwizzleFloat4<0xF4>      xyww;

-			SwizzleFloat4<0xF5>      yyww;

-			SwizzleFloat4<0xF6>      zyww;

-			SwizzleFloat4<0xF7>      wyww;

-			SwizzleFloat4<0xF8>      xzww;

-			SwizzleFloat4<0xF9>      yzww;

-			SwizzleFloat4<0xFA>      zzww;

-			SwizzleFloat4<0xFB>      wzww;

-			SwizzleFloat4<0xFC>      xwww;

-			SwizzleFloat4<0xFD>      ywww;

-			SwizzleFloat4<0xFE>      zwww;

-			SwizzleFloat4<0xFF>      wwww;

-		};

-

-	private:

-		void constant(float x, float y, float z, float w);

-	};

-

-	RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);

-	RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);

-	RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs);

-	RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs);

-	RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs);

-	RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs);

-	RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs);

-	RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs);

-	RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs);

-	RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs);

-	RValue<Float4> operator+(RValue<Float4> val);

-	RValue<Float4> operator-(RValue<Float4> val);

-

-	RValue<Float4> Abs(RValue<Float4> x);

-	RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y);

-	RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y);

-	RValue<Float4> Rcp_pp(RValue<Float4> val, bool exactAtPow2 = false);

-	RValue<Float4> RcpSqrt_pp(RValue<Float4> val);

-	RValue<Float4> Sqrt(RValue<Float4> x);

-	RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i);

-	RValue<Float> Extract(RValue<Float4> x, int i);

-	RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select);

-	RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm);

-	RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y);

-	RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y);

-	RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select);

-	RValue<Int> SignMask(RValue<Float4> x);

-	RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y);

-	RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y);

-	RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y);

-	RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);

-	RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);

-	RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);

-	RValue<Float4> Round(RValue<Float4> x);

-	RValue<Float4> Trunc(RValue<Float4> x);

-	RValue<Float4> Frac(RValue<Float4> x);

-	RValue<Float4> Floor(RValue<Float4> x);

-	RValue<Float4> Ceil(RValue<Float4> x);

-

-	template<class T>

-	class Pointer : public Variable<Pointer<T>>

-	{

-	public:

-		template<class S>

-		Pointer(RValue<Pointer<S>> pointerS, int alignment = 1) : alignment(alignment)

-		{

-			llvm::Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));

-			LValue::storeValue(pointerT);

-		}

-

-		template<class S>

-		Pointer(const Pointer<S> &pointer, int alignment = 1) : alignment(alignment)

-		{

-			llvm::Value *pointerS = pointer.loadValue(alignment);

-			llvm::Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));

-			LValue::storeValue(pointerT);

-		}

-

-		Pointer(Argument<Pointer<T>> argument);

-		explicit Pointer(const void *external);

-

-		Pointer();

-		Pointer(RValue<Pointer<T>> rhs);

-		Pointer(const Pointer<T> &rhs);

-		Pointer(const Reference<Pointer<T>> &rhs);

-

-		RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs) const;

-		RValue<Pointer<T>> operator=(const Pointer<T> &rhs) const;

-		RValue<Pointer<T>> operator=(const Reference<Pointer<T>> &rhs) const;

-

-		Reference<T> operator*();

-

-		static llvm::Type *getType();

-

-	private:

-		const int alignment;

-	};

-

-    RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);

-    RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);

-    RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);

-    RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset);

-    RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset);

-    RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset);

-

-    RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);

-    RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);

-    RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);

-    RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset);

-    RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset);

-    RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset);

-

-	template<class T, int S = 1>

-	class Array : public Variable<T>

-	{

-	public:

-		Array(int size = S);

-

-		Reference<T> operator[](int index);

-		Reference<T> operator[](RValue<Int> index);

-		Reference<T> operator[](RValue<UInt> index);

-	};

-

-//	RValue<Array<T>> operator++(const Array<T> &val, int);   // Post-increment

-//	const Array<T> &operator++(const Array<T> &val);   // Pre-increment

-//	RValue<Array<T>> operator--(const Array<T> &val, int);   // Post-decrement

-//	const Array<T> &operator--(const Array<T> &val);   // Pre-decrement

-

-	llvm::BasicBlock *beginLoop();

-	bool branch(RValue<Bool> cmp, llvm::BasicBlock *bodyBB, llvm::BasicBlock *endBB);

-	bool elseBlock(llvm::BasicBlock *falseBB);

-

-	void Return();

-	void Return(bool ret);

-	void Return(const Int &ret);

-

-	template<class T>

-	void Return(const Pointer<T> &ret);

-

-	template<class T>

-	void Return(RValue<Pointer<T>> ret);

-

-	template<unsigned int index, typename... Arguments>

-	struct ArgI;

-

-	template<typename Arg0, typename... Arguments>

-	struct ArgI<0, Arg0, Arguments...>

-	{

-		typedef Arg0 Type;

-	};

-

-	template<unsigned int index, typename Arg0, typename... Arguments>

-	struct ArgI<index, Arg0, Arguments...>

-	{

-		typedef typename ArgI<index - 1, Arguments...>::Type Type;

-	};

-

-	// Generic template, leave undefined!

-	template<typename FunctionType>

-	class Function;

-

-	// Specialized for function types

-	template<typename Return, typename... Arguments>

-	class Function<Return(Arguments...)>

-	{

-	public:

-		Function();

-

-		virtual ~Function();

-

-		template<int index>

-        Argument<typename ArgI<index, Arguments...>::Type> Arg() const

-        {

-			llvm::Value *arg = Nucleus::getArgument(function, index);

-            return Argument<typename ArgI<index, Arguments...>::Type>(arg);

-        }

-

-		Routine *operator()(const wchar_t *name, ...);

-

-	private:

-		Nucleus *core;

-		llvm::Function *function;

-		std::vector<llvm::Type*> arguments;

-	};

-

-	template<int index, typename Return, typename... Arguments>

-	Argument<typename ArgI<index, Arguments...>::Type> Arg(Function<Return(Arguments...)> &function)

-	{

-		return Argument<typename ArgI<index, Arguments...>::Type>(function.arg(index));

-	}

-

-	RValue<Long> Ticks();

-}

-

-namespace sw

-{

-	template<class T>

-	Variable<T>::Variable(int arraySize) : LValue(T::getType(), arraySize)

-	{

-	}

-

-	template<class T>

-	RValue<Pointer<T>> Variable<T>::operator&()

-	{

-		return RValue<Pointer<T>>(LValue::address);

-	}

-

-	template<class T>

-	Reference<T>::Reference(llvm::Value *pointer, int alignment) : alignment(alignment)

-	{

-		address = pointer;

-	}

-

-	template<class T>

-	RValue<T> Reference<T>::operator=(RValue<T> rhs) const

-	{

-		Nucleus::createStore(rhs.value, address, false, alignment);

-

-		return rhs;

-	}

-

-	template<class T>

-	RValue<T> Reference<T>::operator=(const Reference<T> &ref) const

-	{

-		llvm::Value *tmp = Nucleus::createLoad(ref.address, false, ref.alignment);

-		Nucleus::createStore(tmp, address, false, alignment);

-

-		return RValue<T>(tmp);

-	}

-

-	template<class T>

-	RValue<T> Reference<T>::operator+=(RValue<T> rhs) const

-	{

-		return *this = *this + rhs;

-	}

-

-	template<class T>

-	llvm::Value *Reference<T>::loadValue() const

-	{

-		return Nucleus::createLoad(address, false, alignment);

-	}

-

-	template<class T>

-	int Reference<T>::getAlignment() const

-	{

-		return alignment;

-	}

-

-	template<class T>

-	RValue<T>::RValue(llvm::Value *rvalue)

-	{

-		value = rvalue;

-	}

-

-	template<class T>

-	RValue<T>::RValue(const T &lvalue)

-	{

-		value = lvalue.loadValue();

-	}

-

-	template<class T>

-	RValue<T>::RValue(typename IntLiteral<T>::type i)

-	{

-		value = (llvm::Value*)Nucleus::createConstantInt(i);

-	}

-

-	template<class T>

-	RValue<T>::RValue(typename FloatLiteral<T>::type f)

-	{

-		value = (llvm::Value*)Nucleus::createConstantFloat(f);

-	}

-

-	template<class T>

-	RValue<T>::RValue(const Reference<T> &ref)

-	{

-		value = ref.loadValue();

-	}

-

-	template<int T>

-	Swizzle2Float4<T>::operator RValue<Float4>() const

-	{

-		llvm::Value *vector = parent->loadValue();

-

-		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

-	}

-

-	template<int T>

-	SwizzleFloat4<T>::operator RValue<Float4>() const

-	{

-		llvm::Value *vector = parent->loadValue();

-

-		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

-	}

-

-	template<int T>

-	SwizzleMaskFloat4<T>::operator RValue<Float4>() const

-	{

-		llvm::Value *vector = parent->loadValue();

-

-		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

-	}

-

-	template<int T>

-	RValue<Float4> SwizzleMaskFloat4<T>::operator=(RValue<Float4> rhs) const

-	{

-		return Mask(*parent, rhs, T);

-	}

-

-	template<int T>

-	RValue<Float4> SwizzleMaskFloat4<T>::operator=(RValue<Float> rhs) const

-	{

-		return Mask(*parent, Float4(rhs), T);

-	}

-

-	template<int T>

-	SwizzleMask1Float4<T>::operator RValue<Float>() const   // FIXME: Call a non-template function

-	{

-		return Extract(*parent, T & 0x3);

-	}

-

-	template<int T>

-	SwizzleMask1Float4<T>::operator RValue<Float4>() const

-	{

-		llvm::Value *vector = parent->loadValue();

-

-		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

-	}

-

-	template<int T>

-	RValue<Float4> SwizzleMask1Float4<T>::operator=(float x) const

-	{

-		return Insert(*parent, Float(x), T & 0x3);

-	}

-

-	template<int T>

-	RValue<Float4> SwizzleMask1Float4<T>::operator=(RValue<Float4> rhs) const

-	{

-		return Mask(*parent, Float4(rhs), T);

-	}

-

-	template<int T>

-	RValue<Float4> SwizzleMask1Float4<T>::operator=(RValue<Float> rhs) const   // FIXME: Call a non-template function

-	{

-		return Insert(*parent, rhs, T & 0x3);

-	}

-

-	template<int T>

-	SwizzleMask2Float4<T>::operator RValue<Float4>() const

-	{

-		llvm::Value *vector = parent->loadValue();

-

-		return RValue<Float4>(Nucleus::createSwizzle(vector, T));

-	}

-

-	template<int T>

-	RValue<Float4> SwizzleMask2Float4<T>::operator=(RValue<Float4> rhs) const

-	{

-		return Mask(*parent, Float4(rhs), T);

-	}

-

-	template<int T>

-	Float::Float(const SwizzleMask1Float4<T> &rhs)

-	{

-		*this = rhs.operator RValue<Float>();

-	}

-

-	template<int T>

-	RValue<Float> Float::operator=(const SwizzleMask1Float4<T> &rhs) const

-	{

-		return *this = rhs.operator RValue<Float>();

-	}

-

-	template<int T>

-	Float4::Float4(const SwizzleMask1Float4<T> &rhs)

-	{

-		xyzw.parent = this;

-

-		*this = rhs.operator RValue<Float4>();

-	}

-

-	template<int T>

-	Float4::Float4(const SwizzleFloat4<T> &rhs)

-	{

-		xyzw.parent = this;

-

-		*this = rhs.operator RValue<Float4>();

-	}

-

-	template<int X, int Y>

-	Float4::Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y)

-	{

-		xyzw.parent = this;

-

-		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

-	}

-

-	template<int X, int Y>

-	Float4::Float4(const SwizzleMask2Float4<X> &x, const Swizzle2Float4<Y> &y)

-	{

-		xyzw.parent = this;

-

-		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

-	}

-

-	template<int X, int Y>

-	Float4::Float4(const Swizzle2Float4<X> &x, const SwizzleMask2Float4<Y> &y)

-	{

-		xyzw.parent = this;

-

-		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

-	}

-

-	template<int X, int Y>

-	Float4::Float4(const SwizzleMask2Float4<X> &x, const SwizzleMask2Float4<Y> &y)

-	{

-		xyzw.parent = this;

-

-		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);

-	}

-

-	template<int T>

-	RValue<Float4> Float4::operator=(const SwizzleMask1Float4<T> &rhs)

-	{

-		return *this = rhs.operator RValue<Float4>();

-	}

-

-	template<int T>

-	RValue<Float4> Float4::operator=(const SwizzleFloat4<T> &rhs)

-	{

-		return *this = rhs.operator RValue<Float4>();

-	}

-

-	template<class T>

-	Pointer<T>::Pointer(Argument<Pointer<T>> argument) : alignment(1)

-	{

-		LValue::storeValue(argument.value);

-	}

-

-	template<class T>

-	Pointer<T>::Pointer(const void *external) : alignment((intptr_t)external & 0x0000000F ? 1 : 16)

-	{

-		const llvm::GlobalValue *globalPointer = Nucleus::getGlobalValueAtAddress(const_cast<void*>(external));   // FIXME: Const

-

-		if(!globalPointer)

-		{

-			globalPointer = Nucleus::createGlobalValue(T::getType(), false, alignment);

-

-			Nucleus::addGlobalMapping(globalPointer, const_cast<void*>(external));   // FIXME: Const

-		}

-

-		LValue::storeValue((llvm::Value*)globalPointer);   // FIXME: Const

-	}

-

-	template<class T>

-	Pointer<T>::Pointer() : alignment(1)

-	{

-		LValue::storeValue(Nucleus::createNullPointer(T::getType()));

-	}

-

-	template<class T>

-	Pointer<T>::Pointer(RValue<Pointer<T>> rhs) : alignment(1)

-	{

-		LValue::storeValue(rhs.value);

-	}

-

-	template<class T>

-	Pointer<T>::Pointer(const Pointer<T> &rhs) : alignment(rhs.alignment)

-	{

-		llvm::Value *value = rhs.loadValue();

-		LValue::storeValue(value);

-	}

-

-	template<class T>

-	Pointer<T>::Pointer(const Reference<Pointer<T>> &rhs) : alignment(rhs.getAlignment())

-	{

-		llvm::Value *value = rhs.loadValue();

-		LValue::storeValue(value);

-	}

-

-	template<class T>

-	RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs) const

-	{

-		LValue::storeValue(rhs.value);

-

-		return rhs;

-	}

-

-	template<class T>

-	RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs) const

-	{

-		llvm::Value *value = rhs.loadValue();

-		LValue::storeValue(value);

-

-		return RValue<Pointer<T>>(value);

-	}

-

-	template<class T>

-	RValue<Pointer<T>> Pointer<T>::operator=(const Reference<Pointer<T>> &rhs) const

-	{

-		llvm::Value *value = rhs.loadValue();

-		LValue::storeValue(value);

-

-		return RValue<Pointer<T>>(value);

-	}

-

-	template<class T>

-	Reference<T> Pointer<T>::operator*()

-	{

-		return Reference<T>(LValue::loadValue(), alignment);

-	}

-

-	template<class T>

-	llvm::Type *Pointer<T>::getType()

-	{

-		return Nucleus::getPointerType(T::getType());

-	}

-

-	template<class T, int S>

-	Array<T, S>::Array(int size) : Variable<T>(size)

-	{

-	}

-

-	template<class T, int S>

-	Reference<T> Array<T, S>::operator[](int index)

-	{

-		llvm::Value *element = LValue::getAddress((llvm::Value*)Nucleus::createConstantInt(index));

-

-		return Reference<T>(element);

-	}

-

-	template<class T, int S>

-	Reference<T> Array<T, S>::operator[](RValue<Int> index)

-	{

-		llvm::Value *element = LValue::getAddress(index.value);

-

-		return Reference<T>(element);

-	}

-

-	template<class T, int S>

-	Reference<T> Array<T, S>::operator[](RValue<UInt> index)

-	{

-		llvm::Value *element = LValue::getAddress(index.value);

-

-		return Reference<T>(element);

-	}

-

-//	template<class T>

-//	RValue<Array<T>> operator++(const Array<T> &val, int)

-//	{

-//		// FIXME: Requires storing the address of the array

-//	}

-

-//	template<class T>

-//	const Array<T> &operator++(const Array<T> &val)

-//	{

-//		// FIXME: Requires storing the address of the array

-//	}

-

-//	template<class T>

-//	RValue<Array<T>> operator--(const Array<T> &val, int)

-//	{

-//		// FIXME: Requires storing the address of the array

-//	}

-

-//	template<class T>

-//	const Array<T> &operator--(const Array<T> &val)

-//	{

-//		// FIXME: Requires storing the address of the array

-//	}

-

-	template<class T>

-	RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, RValue<T> ifFalse)

-	{

-		return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value));

-	}

-

-	template<class T>

-	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)

-	{

-		llvm::Value *trueValue = ifTrue.loadValue();

-

-		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));

-	}

-

-	template<class T>

-	RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)

-	{

-		llvm::Value *falseValue = ifFalse.loadValue();

-

-		return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));

-	}

-

-	template<class T>

-	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)

-	{

-		llvm::Value *trueValue = ifTrue.loadValue();

-		llvm::Value *falseValue = ifFalse.loadValue();

-

-		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));

-	}

-

-	template<class T>

-	void Return(const Pointer<T> &ret)

-	{

-		Nucleus::createRet(Nucleus::createLoad(ret.address));

-		Nucleus::setInsertBlock(Nucleus::createBasicBlock());

-	}

-

-	template<class T>

-	void Return(RValue<Pointer<T>> ret)

-	{

-		Nucleus::createRet(ret.value);

-		Nucleus::setInsertBlock(Nucleus::createBasicBlock());

-	}

-

-	template<typename Return, typename... Arguments>

-	Function<Return(Arguments...)>::Function()

-	{

-		core = new Nucleus();

-

-		llvm::Type *types[] = {Arguments::getType()...};

-		for(llvm::Type *type : types)

-		{

-			arguments.push_back(type);

-		}

-

-		function = Nucleus::createFunction(Return::getType(), arguments);

-		Nucleus::setFunction(function);

-	}

-

-	template<typename Return, typename... Arguments>

-	Function<Return(Arguments...)>::~Function()

-	{

-		delete core;

-	}

-

-	template<typename Return, typename... Arguments>

-	Routine *Function<Return(Arguments...)>::operator()(const wchar_t *name, ...)

-	{

-		wchar_t fullName[1024 + 1];

-

-		va_list vararg;

-		va_start(vararg, name);

-		vswprintf(fullName, 1024, name, vararg);

-		va_end(vararg);

-

-		return core->acquireRoutine(fullName, true);

-	}

-

-	template<class T, class S>

-	RValue<T> ReinterpretCast(RValue<S> val)

-	{

-		return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));

-	}

-

-	template<class T>

-	RValue<T> ReinterpretCast(const LValue &var)

-	{

-		llvm::Value *val = var.loadValue();

-

-		return RValue<T>(Nucleus::createBitCast(val, T::getType()));

-	}

-

-	template<class T, class S>

-	RValue<T> ReinterpretCast(const Reference<S> &var)

-	{

-		return ReinterpretCast<T>(RValue<S>(var));

-	}

-

-	template<class T, class S>

-	RValue<T> As(RValue<S> val)

-	{

-		return ReinterpretCast<T>(val);

-	}

-

-	template<class T>

-	RValue<T> As(const LValue &var)

-	{

-		return ReinterpretCast<T>(var);

-	}

-

-	template<class T, class S>

-	RValue<T> As(const Reference<S> &val)

-	{

-		return ReinterpretCast<T>(val);

-	}

-}

-

-#endif   // sw_Nucleus_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Nucleus_hpp
+#define sw_Nucleus_hpp
+
+#include "Common/Types.hpp"
+#include "Common/MutexLock.hpp"
+
+#include <stdarg.h>
+#include <vector>
+#include <stdio.h>
+#include <wchar.h>
+
+#undef abs
+#undef max
+#undef min
+#undef Bool
+
+namespace llvm
+{
+	class Function;
+	class Module;
+	class BasicBlock;
+	class Value;
+	class Constant;
+	class ConstantInt;
+	class ConstantFP;
+	class Type;
+	class Argument;
+	class GlobalVariable;
+	class GlobalValue;
+	class ExecutionEngine;
+	class LLVMContext;
+}
+
+namespace sw
+{
+	enum Optimization
+	{
+		Disabled             = 0,
+		InstructionCombining = 1,
+		CFGSimplification    = 2,
+		LICM                 = 3,
+		AggressiveDCE        = 4,
+		GVN                  = 5,
+		Reassociate          = 6,
+		DeadStoreElimination = 7,
+		SCCP                 = 8,
+		ScalarReplAggregates = 9,
+
+		OptimizationCount
+	};
+
+	extern Optimization optimization[10];
+
+	class Routine;
+	class RoutineManager;
+	class Builder;
+
+	class Nucleus
+	{
+	public:
+		Nucleus();
+
+		virtual ~Nucleus();
+
+		Routine *acquireRoutine(const wchar_t *name, bool runOptimizations = true);
+
+		static void setFunction(llvm::Function *function);
+
+		static llvm::Module *getModule();
+		static llvm::Function *getFunction();
+		static llvm::LLVMContext *getContext();
+
+		static llvm::Value *allocateStackVariable(llvm::Type *type, int arraySize = 0);
+		static llvm::BasicBlock *createBasicBlock();
+		static llvm::BasicBlock *getInsertBlock();
+		static void setInsertBlock(llvm::BasicBlock *basicBlock);
+		static llvm::BasicBlock *getPredecessor(llvm::BasicBlock *basicBlock);
+
+		static llvm::Function *createFunction(llvm::Type *ReturnType, std::vector<llvm::Type*> &Params);
+		static llvm::Value *getArgument(llvm::Function *function, unsigned int index);
+
+		// Terminators
+		static llvm::Value *createRetVoid();
+		static llvm::Value *createRet(llvm::Value *V);
+		static llvm::Value *createBr(llvm::BasicBlock *dest);
+		static llvm::Value *createCondBr(llvm::Value *cond, llvm::BasicBlock *ifTrue, llvm::BasicBlock *ifFalse);
+
+		// Binary operators
+		static llvm::Value *createAdd(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createSub(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createMul(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createUDiv(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createSDiv(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFAdd(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFSub(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFMul(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFDiv(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createURem(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createSRem(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFRem(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createShl(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createLShr(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createAShr(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createAnd(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createOr(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createXor(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createNeg(llvm::Value *V);
+		static llvm::Value *createFNeg(llvm::Value *V);
+		static llvm::Value *createNot(llvm::Value *V);
+
+		// Memory instructions
+		static llvm::Value *createLoad(llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);
+		static llvm::Value *createStore(llvm::Value *value, llvm::Value *ptr, bool isVolatile = false, unsigned int align = 0);
+		static llvm::Value *createGEP(llvm::Value *ptr, llvm::Value *index);
+
+		// Atomic instructions
+		static llvm::Value *createAtomicAdd(llvm::Value *ptr, llvm::Value *value);
+
+		// Cast/Conversion Operators
+		static llvm::Value *createTrunc(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createZExt(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createSExt(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createFPToUI(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createFPToSI(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createUIToFP(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createSIToFP(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createFPTrunc(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createFPExt(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createPtrToInt(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createIntToPtr(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createBitCast(llvm::Value *V, llvm::Type *destType);
+		static llvm::Value *createIntCast(llvm::Value *V, llvm::Type *destType, bool isSigned);
+
+		// Compare instructions
+		static llvm::Value *createICmpEQ(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpNE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpUGT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpUGE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpULT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpULE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpSGT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpSGE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpSLT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createICmpSLE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpOEQ(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpOGT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpOGE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpOLT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpOLE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpONE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpORD(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpUNO(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpUEQ(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpUGT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpUGE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpULT(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpULE(llvm::Value *lhs, llvm::Value *rhs);
+		static llvm::Value *createFCmpUNE(llvm::Value *lhs, llvm::Value *rhs);
+
+		// Call instructions
+		static llvm::Value *createCall(llvm::Value *callee);
+		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg);
+		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2);
+		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2, llvm::Value *Arg3);
+		static llvm::Value *createCall(llvm::Value *callee, llvm::Value *Arg1, llvm::Value *Arg2, llvm::Value *Arg3,llvm::Value *Arg4);
+
+		// Vector instructions
+		static llvm::Value *createExtractElement(llvm::Value *vector, int index);
+		static llvm::Value *createInsertElement(llvm::Value *vector, llvm::Value *element, int index);
+		static llvm::Value *createShuffleVector(llvm::Value *V1, llvm::Value *V2, llvm::Value *mask);
+
+		// Other instructions
+		static llvm::Value *createSelect(llvm::Value *C, llvm::Value *ifTrue, llvm::Value *ifFalse);
+		static llvm::Value *createSwitch(llvm::Value *V, llvm::BasicBlock *Dest, unsigned NumCases);
+		static void addSwitchCase(llvm::Value *Switch, int Case, llvm::BasicBlock *Branch);
+		static llvm::Value *createUnreachable();
+
+		// Derived instructions
+		static llvm::Value *createSwizzle(llvm::Value *val, unsigned char select);
+		static llvm::Value *createMask(llvm::Value *lhs, llvm::Value *rhs, unsigned char select);
+
+		// Global values
+		static const llvm::GlobalValue *getGlobalValueAtAddress(void *Addr);
+		static void addGlobalMapping(const llvm::GlobalValue *GV, void *Addr);
+		static llvm::GlobalValue *createGlobalValue(llvm::Type *Ty, bool isConstant, unsigned int Align);
+		static llvm::Type *getPointerType(llvm::Type *ElementType);
+
+		// Constant values
+		static llvm::Constant *createNullValue(llvm::Type *Ty);
+		static llvm::ConstantInt *createConstantInt(int64_t i);
+		static llvm::ConstantInt *createConstantInt(int i);
+		static llvm::ConstantInt *createConstantInt(unsigned int i);
+		static llvm::ConstantInt *createConstantBool(bool b);
+		static llvm::ConstantInt *createConstantByte(signed char i);
+		static llvm::ConstantInt *createConstantByte(unsigned char i);
+		static llvm::ConstantInt *createConstantShort(short i);
+		static llvm::ConstantInt *createConstantShort(unsigned short i);
+		static llvm::Constant *createConstantFloat(float x);
+		static llvm::Value *createNullPointer(llvm::Type *Ty);
+		static llvm::Value *createConstantVector(llvm::Constant *const *Vals, unsigned NumVals);
+
+	private:
+		void optimize();
+
+		static llvm::ExecutionEngine *executionEngine;
+		static Builder *builder;
+		static llvm::Function *function;
+		static llvm::LLVMContext *context;
+		static llvm::Module *module;
+		static RoutineManager *routineManager;
+
+		static BackoffLock codegenMutex;
+	};
+
+	class Byte;
+	class SByte;
+	class Byte4;
+	class SByte4;
+	class Byte8;
+	class SByte8;
+	class Byte16;
+	class SByte16;
+	class Short;
+	class UShort;
+	class Short4;
+	class UShort4;
+	class Short8;
+	class UShort8;
+	class Int;
+	class UInt;
+	class Int2;
+	class UInt2;
+	class Int4;
+	class UInt4;
+	class Long;
+	class Long1;
+	class Long2;
+	class Float;
+	class Float2;
+	class Float4;
+
+	class Void
+	{
+	public:
+		static llvm::Type *getType();
+
+		static bool isVoid()
+		{
+			return true;
+		}
+
+		typedef void ctype;
+	};
+
+	template<class T>
+	class RValue;
+
+	template<class T>
+	class Pointer;
+
+	class LValue
+	{
+	public:
+		LValue(llvm::Type *type, int arraySize = 0);
+
+		static bool isVoid()
+		{
+			return false;
+		}
+
+		llvm::Value *loadValue(unsigned int alignment = 0) const;
+		llvm::Value *storeValue(llvm::Value *value, unsigned int alignment = 0) const;
+		llvm::Value *getAddress(llvm::Value *index) const;
+
+	protected:
+		llvm::Value *address;
+	};
+
+	template<class T>
+	class Variable : public LValue
+	{
+	public:
+		Variable(int arraySize = 0);
+
+		RValue<Pointer<T>> operator&();
+	};
+
+	template<class T>
+	class Reference
+	{
+	public:
+		explicit Reference(llvm::Value *pointer, int alignment = 1);
+
+		RValue<T> operator=(RValue<T> rhs) const;
+		RValue<T> operator=(const Reference<T> &ref) const;
+
+		RValue<T> operator+=(RValue<T> rhs) const;
+
+		llvm::Value *loadValue() const;
+		int getAlignment() const;
+
+	private:
+		llvm::Value *address;
+
+		const int alignment;
+	};
+
+	template<class T>
+	struct IntLiteral
+	{
+		struct type;
+	};
+
+	template<> struct
+	IntLiteral<Int>
+	{
+		typedef int type;
+	};
+
+	template<> struct
+	IntLiteral<UInt>
+	{
+		typedef unsigned int type;
+	};
+
+	template<> struct
+	IntLiteral<Long>
+	{
+		typedef int64_t type;
+	};
+
+	template<class T>
+	struct FloatLiteral
+	{
+		struct type;
+	};
+
+	template<> struct
+	FloatLiteral<Float>
+	{
+		typedef float type;
+	};
+
+	template<class T>
+	class RValue
+	{
+	public:
+		explicit RValue(llvm::Value *rvalue);
+
+		RValue(const T &lvalue);
+		RValue(typename IntLiteral<T>::type i);
+		RValue(typename FloatLiteral<T>::type f);
+		RValue(const Reference<T> &rhs);
+
+		RValue<T> &operator=(const RValue<T>&) = delete;
+
+		llvm::Value *value;   // FIXME: Make private
+	};
+
+	template<typename T>
+	struct Argument
+	{
+		explicit Argument(llvm::Value *value) : value(value) {}
+
+		llvm::Value *value;
+	};
+
+	class MMX : public Variable<MMX>
+	{
+	public:
+		static llvm::Type *getType();
+	};
+
+	class Bool : public Variable<Bool>
+	{
+	public:
+		Bool(Argument<Bool> argument);
+
+		Bool();
+		Bool(bool x);
+		Bool(RValue<Bool> rhs);
+		Bool(const Bool &rhs);
+		Bool(const Reference<Bool> &rhs);
+
+	//	RValue<Bool> operator=(bool rhs) const;   // FIXME: Implement
+		RValue<Bool> operator=(RValue<Bool> rhs) const;
+		RValue<Bool> operator=(const Bool &rhs) const;
+		RValue<Bool> operator=(const Reference<Bool> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Bool> operator!(RValue<Bool> val);
+	RValue<Bool> operator&&(RValue<Bool> lhs, RValue<Bool> rhs);
+	RValue<Bool> operator||(RValue<Bool> lhs, RValue<Bool> rhs);
+
+	class Byte : public Variable<Byte>
+	{
+	public:
+		Byte(Argument<Byte> argument);
+
+		explicit Byte(RValue<Int> cast);
+		explicit Byte(RValue<UInt> cast);
+		explicit Byte(RValue<UShort> cast);
+
+		Byte();
+		Byte(int x);
+		Byte(unsigned char x);
+		Byte(RValue<Byte> rhs);
+		Byte(const Byte &rhs);
+		Byte(const Reference<Byte> &rhs);
+
+	//	RValue<Byte> operator=(unsigned char rhs) const;   // FIXME: Implement
+		RValue<Byte> operator=(RValue<Byte> rhs) const;
+		RValue<Byte> operator=(const Byte &rhs) const;
+		RValue<Byte> operator=(const Reference<Byte> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Byte> operator+(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator-(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator*(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator/(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator%(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator&(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator|(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator^(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator<<(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator>>(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Byte> operator+=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator-=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator*=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator/=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator%=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator&=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator|=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator^=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator<<=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator>>=(const Byte &lhs, RValue<Byte> rhs);
+	RValue<Byte> operator+(RValue<Byte> val);
+	RValue<Byte> operator-(RValue<Byte> val);
+	RValue<Byte> operator~(RValue<Byte> val);
+	RValue<Byte> operator++(const Byte &val, int);   // Post-increment
+	const Byte &operator++(const Byte &val);   // Pre-increment
+	RValue<Byte> operator--(const Byte &val, int);   // Post-decrement
+	const Byte &operator--(const Byte &val);   // Pre-decrement
+	RValue<Bool> operator<(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Bool> operator<=(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Bool> operator>(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Bool> operator>=(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Bool> operator!=(RValue<Byte> lhs, RValue<Byte> rhs);
+	RValue<Bool> operator==(RValue<Byte> lhs, RValue<Byte> rhs);
+
+	class SByte : public Variable<SByte>
+	{
+	public:
+		SByte(Argument<SByte> argument);
+
+		explicit SByte(RValue<Int> cast);
+		explicit SByte(RValue<Short> cast);
+
+		SByte();
+		SByte(signed char x);
+		SByte(RValue<SByte> rhs);
+		SByte(const SByte &rhs);
+		SByte(const Reference<SByte> &rhs);
+
+	//	RValue<SByte> operator=(signed char rhs) const;   // FIXME: Implement
+		RValue<SByte> operator=(RValue<SByte> rhs) const;
+		RValue<SByte> operator=(const SByte &rhs) const;
+		RValue<SByte> operator=(const Reference<SByte> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<SByte> operator+(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator-(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator*(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator/(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator%(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator&(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator|(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator^(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator<<(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator>>(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<SByte> operator+=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator-=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator*=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator/=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator%=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator&=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator|=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator^=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator<<=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator>>=(const SByte &lhs, RValue<SByte> rhs);
+	RValue<SByte> operator+(RValue<SByte> val);
+	RValue<SByte> operator-(RValue<SByte> val);
+	RValue<SByte> operator~(RValue<SByte> val);
+	RValue<SByte> operator++(const SByte &val, int);   // Post-increment
+	const SByte &operator++(const SByte &val);   // Pre-increment
+	RValue<SByte> operator--(const SByte &val, int);   // Post-decrement
+	const SByte &operator--(const SByte &val);   // Pre-decrement
+	RValue<Bool> operator<(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<Bool> operator<=(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<Bool> operator>(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<Bool> operator>=(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<Bool> operator!=(RValue<SByte> lhs, RValue<SByte> rhs);
+	RValue<Bool> operator==(RValue<SByte> lhs, RValue<SByte> rhs);
+
+	class Short : public Variable<Short>
+	{
+	public:
+		Short(Argument<Short> argument);
+
+		explicit Short(RValue<Int> cast);
+
+		Short();
+		Short(short x);
+		Short(RValue<Short> rhs);
+		Short(const Short &rhs);
+		Short(const Reference<Short> &rhs);
+
+	//	RValue<Short> operator=(short rhs) const;   // FIXME: Implement
+		RValue<Short> operator=(RValue<Short> rhs) const;
+		RValue<Short> operator=(const Short &rhs) const;
+		RValue<Short> operator=(const Reference<Short> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Short> operator+(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator-(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator*(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator/(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator%(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator&(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator|(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator^(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator<<(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator>>(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Short> operator+=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator-=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator*=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator/=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator%=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator&=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator|=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator^=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator<<=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator>>=(const Short &lhs, RValue<Short> rhs);
+	RValue<Short> operator+(RValue<Short> val);
+	RValue<Short> operator-(RValue<Short> val);
+	RValue<Short> operator~(RValue<Short> val);
+	RValue<Short> operator++(const Short &val, int);   // Post-increment
+	const Short &operator++(const Short &val);   // Pre-increment
+	RValue<Short> operator--(const Short &val, int);   // Post-decrement
+	const Short &operator--(const Short &val);   // Pre-decrement
+	RValue<Bool> operator<(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Bool> operator<=(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Bool> operator>(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Bool> operator>=(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Bool> operator!=(RValue<Short> lhs, RValue<Short> rhs);
+	RValue<Bool> operator==(RValue<Short> lhs, RValue<Short> rhs);
+
+	class UShort : public Variable<UShort>
+	{
+	public:
+		UShort(Argument<UShort> argument);
+
+		explicit UShort(RValue<UInt> cast);
+		explicit UShort(RValue<Int> cast);
+
+		UShort();
+		UShort(unsigned short x);
+		UShort(RValue<UShort> rhs);
+		UShort(const UShort &rhs);
+		UShort(const Reference<UShort> &rhs);
+
+	//	RValue<UShort> operator=(unsigned short rhs) const;   // FIXME: Implement
+		RValue<UShort> operator=(RValue<UShort> rhs) const;
+		RValue<UShort> operator=(const UShort &rhs) const;
+		RValue<UShort> operator=(const Reference<UShort> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<UShort> operator+(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator-(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator*(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator/(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator%(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator&(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator|(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator^(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator<<(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator>>(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<UShort> operator+=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator-=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator*=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator/=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator%=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator&=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator|=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator^=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator<<=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator>>=(const UShort &lhs, RValue<UShort> rhs);
+	RValue<UShort> operator+(RValue<UShort> val);
+	RValue<UShort> operator-(RValue<UShort> val);
+	RValue<UShort> operator~(RValue<UShort> val);
+	RValue<UShort> operator++(const UShort &val, int);   // Post-increment
+	const UShort &operator++(const UShort &val);   // Pre-increment
+	RValue<UShort> operator--(const UShort &val, int);   // Post-decrement
+	const UShort &operator--(const UShort &val);   // Pre-decrement
+	RValue<Bool> operator<(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<Bool> operator<=(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<Bool> operator>(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<Bool> operator>=(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<Bool> operator!=(RValue<UShort> lhs, RValue<UShort> rhs);
+	RValue<Bool> operator==(RValue<UShort> lhs, RValue<UShort> rhs);
+
+	class Byte4 : public Variable<Byte4>
+	{
+	public:
+	//	Byte4();
+	//	Byte4(int x, int y, int z, int w);
+	//	Byte4(RValue<Byte4> rhs);
+	//	Byte4(const Byte4 &rhs);
+	//	Byte4(const Reference<Byte4> &rhs);
+
+	//	RValue<Byte4> operator=(RValue<Byte4> rhs) const;
+	//	RValue<Byte4> operator=(const Byte4 &rhs) const;
+	//	RValue<Byte4> operator=(const Reference<Byte4> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+//	RValue<Byte4> operator+(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator-(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator*(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator/(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator%(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator&(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator|(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator^(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator<<(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator>>(RValue<Byte4> lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator+=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator-=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator*=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator/=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator%=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator&=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator|=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator^=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator<<=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator>>=(const Byte4 &lhs, RValue<Byte4> rhs);
+//	RValue<Byte4> operator+(RValue<Byte4> val);
+//	RValue<Byte4> operator-(RValue<Byte4> val);
+//	RValue<Byte4> operator~(RValue<Byte4> val);
+//	RValue<Byte4> operator++(const Byte4 &val, int);   // Post-increment
+//	const Byte4 &operator++(const Byte4 &val);   // Pre-increment
+//	RValue<Byte4> operator--(const Byte4 &val, int);   // Post-decrement
+//	const Byte4 &operator--(const Byte4 &val);   // Pre-decrement
+
+	class SByte4 : public Variable<SByte4>
+	{
+	public:
+	//	SByte4();
+	//	SByte4(int x, int y, int z, int w);
+	//	SByte4(RValue<SByte4> rhs);
+	//	SByte4(const SByte4 &rhs);
+	//	SByte4(const Reference<SByte4> &rhs);
+
+	//	RValue<SByte4> operator=(RValue<SByte4> rhs) const;
+	//	RValue<SByte4> operator=(const SByte4 &rhs) const;
+	//	RValue<SByte4> operator=(const Reference<SByte4> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+//	RValue<SByte4> operator+(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator-(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator*(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator/(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator%(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator&(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator|(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator^(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator<<(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator>>(RValue<SByte4> lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator+=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator-=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator*=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator/=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator%=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator&=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator|=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator^=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator<<=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator>>=(const SByte4 &lhs, RValue<SByte4> rhs);
+//	RValue<SByte4> operator+(RValue<SByte4> val);
+//	RValue<SByte4> operator-(RValue<SByte4> val);
+//	RValue<SByte4> operator~(RValue<SByte4> val);
+//	RValue<SByte4> operator++(const SByte4 &val, int);   // Post-increment
+//	const SByte4 &operator++(const SByte4 &val);   // Pre-increment
+//	RValue<SByte4> operator--(const SByte4 &val, int);   // Post-decrement
+//	const SByte4 &operator--(const SByte4 &val);   // Pre-decrement
+
+	class Byte8 : public Variable<Byte8>
+	{
+	public:
+		Byte8();
+		Byte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7);
+		Byte8(int64_t x);
+		Byte8(RValue<Byte8> rhs);
+		Byte8(const Byte8 &rhs);
+		Byte8(const Reference<Byte8> &rhs);
+
+		RValue<Byte8> operator=(RValue<Byte8> rhs) const;
+		RValue<Byte8> operator=(const Byte8 &rhs) const;
+		RValue<Byte8> operator=(const Reference<Byte8> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Byte8> operator+(RValue<Byte8> lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator-(RValue<Byte8> lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator*(RValue<Byte8> lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator/(RValue<Byte8> lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator%(RValue<Byte8> lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator&(RValue<Byte8> lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator|(RValue<Byte8> lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator^(RValue<Byte8> lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator<<(RValue<Byte8> lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator>>(RValue<Byte8> lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator+=(const Byte8 &lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator-=(const Byte8 &lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator*=(const Byte8 &lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator/=(const Byte8 &lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator%=(const Byte8 &lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator&=(const Byte8 &lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator|=(const Byte8 &lhs, RValue<Byte8> rhs);
+	RValue<Byte8> operator^=(const Byte8 &lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator<<=(const Byte8 &lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator>>=(const Byte8 &lhs, RValue<Byte8> rhs);
+//	RValue<Byte8> operator+(RValue<Byte8> val);
+//	RValue<Byte8> operator-(RValue<Byte8> val);
+	RValue<Byte8> operator~(RValue<Byte8> val);
+//	RValue<Byte8> operator++(const Byte8 &val, int);   // Post-increment
+//	const Byte8 &operator++(const Byte8 &val);   // Pre-increment
+//	RValue<Byte8> operator--(const Byte8 &val, int);   // Post-decrement
+//	const Byte8 &operator--(const Byte8 &val);   // Pre-decrement
+
+	RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y);
+	RValue<Byte8> SubSat(RValue<Byte8> x, RValue<Byte8> y);
+	RValue<Short4> Unpack(RValue<Byte4> x);
+	RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y);
+	RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y);
+	RValue<Int> SignMask(RValue<Byte8> x);
+//	RValue<Byte8> CmpGT(RValue<Byte8> x, RValue<Byte8> y);
+	RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y);
+
+	class SByte8 : public Variable<SByte8>
+	{
+	public:
+		SByte8();
+		SByte8(byte x0, byte x1, byte x2, byte x3, byte x4, byte x5, byte x6, byte x7);
+		SByte8(int64_t x);
+		SByte8(RValue<SByte8> rhs);
+		SByte8(const SByte8 &rhs);
+		SByte8(const Reference<SByte8> &rhs);
+
+		RValue<SByte8> operator=(RValue<SByte8> rhs) const;
+		RValue<SByte8> operator=(const SByte8 &rhs) const;
+		RValue<SByte8> operator=(const Reference<SByte8> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<SByte8> operator+(RValue<SByte8> lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator-(RValue<SByte8> lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator*(RValue<SByte8> lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator/(RValue<SByte8> lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator%(RValue<SByte8> lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator&(RValue<SByte8> lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator|(RValue<SByte8> lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator^(RValue<SByte8> lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator<<(RValue<SByte8> lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator>>(RValue<SByte8> lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator+=(const SByte8 &lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator-=(const SByte8 &lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator*=(const SByte8 &lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator/=(const SByte8 &lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator%=(const SByte8 &lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator&=(const SByte8 &lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator|=(const SByte8 &lhs, RValue<SByte8> rhs);
+	RValue<SByte8> operator^=(const SByte8 &lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator<<=(const SByte8 &lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator>>=(const SByte8 &lhs, RValue<SByte8> rhs);
+//	RValue<SByte8> operator+(RValue<SByte8> val);
+//	RValue<SByte8> operator-(RValue<SByte8> val);
+	RValue<SByte8> operator~(RValue<SByte8> val);
+//	RValue<SByte8> operator++(const SByte8 &val, int);   // Post-increment
+//	const SByte8 &operator++(const SByte8 &val);   // Pre-increment
+//	RValue<SByte8> operator--(const SByte8 &val, int);   // Post-decrement
+//	const SByte8 &operator--(const SByte8 &val);   // Pre-decrement
+
+	RValue<SByte8> AddSat(RValue<SByte8> x, RValue<SByte8> y);
+	RValue<SByte8> SubSat(RValue<SByte8> x, RValue<SByte8> y);
+	RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y);
+	RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y);
+	RValue<Int> SignMask(RValue<SByte8> x);
+	RValue<Byte8> CmpGT(RValue<SByte8> x, RValue<SByte8> y);
+	RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y);
+
+	class Byte16 : public Variable<Byte16>
+	{
+	public:
+	//	Byte16();
+	//	Byte16(int x, int y, int z, int w);
+		Byte16(RValue<Byte16> rhs);
+		Byte16(const Byte16 &rhs);
+		Byte16(const Reference<Byte16> &rhs);
+
+		RValue<Byte16> operator=(RValue<Byte16> rhs) const;
+		RValue<Byte16> operator=(const Byte16 &rhs) const;
+		RValue<Byte16> operator=(const Reference<Byte16> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+//	RValue<Byte16> operator+(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator-(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator*(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator/(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator%(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator&(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator|(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator^(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator<<(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator>>(RValue<Byte16> lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator+=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator-=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator*=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator/=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator%=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator&=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator|=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator^=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator<<=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator>>=(const Byte16 &lhs, RValue<Byte16> rhs);
+//	RValue<Byte16> operator+(RValue<Byte16> val);
+//	RValue<Byte16> operator-(RValue<Byte16> val);
+//	RValue<Byte16> operator~(RValue<Byte16> val);
+//	RValue<Byte16> operator++(const Byte16 &val, int);   // Post-increment
+//	const Byte16 &operator++(const Byte16 &val);   // Pre-increment
+//	RValue<Byte16> operator--(const Byte16 &val, int);   // Post-decrement
+//	const Byte16 &operator--(const Byte16 &val);   // Pre-decrement
+
+	class SByte16 : public Variable<SByte16>
+	{
+	public:
+	//	SByte16();
+	//	SByte16(int x, int y, int z, int w);
+	//	SByte16(RValue<SByte16> rhs);
+	//	SByte16(const SByte16 &rhs);
+	//	SByte16(const Reference<SByte16> &rhs);
+
+	//	RValue<SByte16> operator=(RValue<SByte16> rhs) const;
+	//	RValue<SByte16> operator=(const SByte16 &rhs) const;
+	//	RValue<SByte16> operator=(const Reference<SByte16> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+//	RValue<SByte16> operator+(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator-(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator*(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator/(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator%(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator&(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator|(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator^(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator<<(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator>>(RValue<SByte16> lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator+=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator-=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator*=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator/=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator%=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator&=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator|=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator^=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator<<=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator>>=(const SByte16 &lhs, RValue<SByte16> rhs);
+//	RValue<SByte16> operator+(RValue<SByte16> val);
+//	RValue<SByte16> operator-(RValue<SByte16> val);
+//	RValue<SByte16> operator~(RValue<SByte16> val);
+//	RValue<SByte16> operator++(const SByte16 &val, int);   // Post-increment
+//	const SByte16 &operator++(const SByte16 &val);   // Pre-increment
+//	RValue<SByte16> operator--(const SByte16 &val, int);   // Post-decrement
+//	const SByte16 &operator--(const SByte16 &val);   // Pre-decrement
+
+	class Short4 : public Variable<Short4>
+	{
+	public:
+		explicit Short4(RValue<Int> cast);
+		explicit Short4(RValue<Int4> cast);
+	//	explicit Short4(RValue<Float> cast);
+		explicit Short4(RValue<Float4> cast);
+
+		Short4();
+		Short4(short xyzw);
+		Short4(short x, short y, short z, short w);
+		Short4(RValue<Short4> rhs);
+		Short4(const Short4 &rhs);
+		Short4(const Reference<Short4> &rhs);
+		Short4(RValue<UShort4> rhs);
+		Short4(const UShort4 &rhs);
+		Short4(const Reference<UShort4> &rhs);
+
+		RValue<Short4> operator=(RValue<Short4> rhs) const;
+		RValue<Short4> operator=(const Short4 &rhs) const;
+		RValue<Short4> operator=(const Reference<Short4> &rhs) const;
+		RValue<Short4> operator=(RValue<UShort4> rhs) const;
+		RValue<Short4> operator=(const UShort4 &rhs) const;
+		RValue<Short4> operator=(const Reference<UShort4> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Short4> operator+(RValue<Short4> lhs, RValue<Short4> rhs);
+	RValue<Short4> operator-(RValue<Short4> lhs, RValue<Short4> rhs);
+	RValue<Short4> operator*(RValue<Short4> lhs, RValue<Short4> rhs);
+//	RValue<Short4> operator/(RValue<Short4> lhs, RValue<Short4> rhs);
+//	RValue<Short4> operator%(RValue<Short4> lhs, RValue<Short4> rhs);
+	RValue<Short4> operator&(RValue<Short4> lhs, RValue<Short4> rhs);
+	RValue<Short4> operator|(RValue<Short4> lhs, RValue<Short4> rhs);
+	RValue<Short4> operator^(RValue<Short4> lhs, RValue<Short4> rhs);
+	RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs);
+	RValue<Short4> operator>>(RValue<Short4> lhs, unsigned char rhs);
+	RValue<Short4> operator<<(RValue<Short4> lhs, RValue<Long1> rhs);
+	RValue<Short4> operator>>(RValue<Short4> lhs, RValue<Long1> rhs);
+	RValue<Short4> operator+=(const Short4 &lhs, RValue<Short4> rhs);
+	RValue<Short4> operator-=(const Short4 &lhs, RValue<Short4> rhs);
+	RValue<Short4> operator*=(const Short4 &lhs, RValue<Short4> rhs);
+//	RValue<Short4> operator/=(const Short4 &lhs, RValue<Short4> rhs);
+//	RValue<Short4> operator%=(const Short4 &lhs, RValue<Short4> rhs);
+	RValue<Short4> operator&=(const Short4 &lhs, RValue<Short4> rhs);
+	RValue<Short4> operator|=(const Short4 &lhs, RValue<Short4> rhs);
+	RValue<Short4> operator^=(const Short4 &lhs, RValue<Short4> rhs);
+	RValue<Short4> operator<<=(const Short4 &lhs, unsigned char rhs);
+	RValue<Short4> operator>>=(const Short4 &lhs, unsigned char rhs);
+	RValue<Short4> operator<<=(const Short4 &lhs, RValue<Long1> rhs);
+	RValue<Short4> operator>>=(const Short4 &lhs, RValue<Long1> rhs);
+//	RValue<Short4> operator+(RValue<Short4> val);
+	RValue<Short4> operator-(RValue<Short4> val);
+	RValue<Short4> operator~(RValue<Short4> val);
+//	RValue<Short4> operator++(const Short4 &val, int);   // Post-increment
+//	const Short4 &operator++(const Short4 &val);   // Pre-increment
+//	RValue<Short4> operator--(const Short4 &val, int);   // Post-decrement
+//	const Short4 &operator--(const Short4 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<Short4> lhs, RValue<Short4> rhs);
+//	RValue<Bool> operator<=(RValue<Short4> lhs, RValue<Short4> rhs);
+//	RValue<Bool> operator>(RValue<Short4> lhs, RValue<Short4> rhs);
+//	RValue<Bool> operator>=(RValue<Short4> lhs, RValue<Short4> rhs);
+//	RValue<Bool> operator!=(RValue<Short4> lhs, RValue<Short4> rhs);
+//	RValue<Bool> operator==(RValue<Short4> lhs, RValue<Short4> rhs);
+
+	RValue<Short4> RoundShort4(RValue<Float4> cast);
+	RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y);
+	RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y);
+	RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y);
+	RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);
+	RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);
+	RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);
+	RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y);
+	RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);
+	RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);
+	RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select);
+	RValue<Short4> Insert(RValue<Short4> val, RValue<Short> element, int i);
+	RValue<Short> Extract(RValue<Short4> val, int i);
+	RValue<Short4> CmpGT(RValue<Short4> x, RValue<Short4> y);
+	RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y);
+
+	class UShort4 : public Variable<UShort4>
+	{
+	public:
+		explicit UShort4(RValue<Int4> cast);
+		explicit UShort4(RValue<Float4> cast, bool saturate = false);
+
+		UShort4();
+		UShort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w);
+		UShort4(RValue<UShort4> rhs);
+		UShort4(const UShort4 &rhs);
+		UShort4(const Reference<UShort4> &rhs);
+		UShort4(RValue<Short4> rhs);
+		UShort4(const Short4 &rhs);
+		UShort4(const Reference<Short4> &rhs);
+
+		RValue<UShort4> operator=(RValue<UShort4> rhs) const;
+		RValue<UShort4> operator=(const UShort4 &rhs) const;
+		RValue<UShort4> operator=(const Reference<UShort4> &rhs) const;
+		RValue<UShort4> operator=(RValue<Short4> rhs) const;
+		RValue<UShort4> operator=(const Short4 &rhs) const;
+		RValue<UShort4> operator=(const Reference<Short4> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<UShort4> operator+(RValue<UShort4> lhs, RValue<UShort4> rhs);
+	RValue<UShort4> operator-(RValue<UShort4> lhs, RValue<UShort4> rhs);
+	RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
+	RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);
+	RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);
+	RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs);
+	RValue<UShort4> operator>>(RValue<UShort4> lhs, RValue<Long1> rhs);
+//	RValue<UShort4> operator+=(const UShort4 &lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator-=(const UShort4 &lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator*=(const UShort4 &lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator/=(const UShort4 &lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator%=(const UShort4 &lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator&=(const UShort4 &lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator|=(const UShort4 &lhs, RValue<UShort4> rhs);
+//	RValue<UShort4> operator^=(const UShort4 &lhs, RValue<UShort4> rhs);
+	RValue<UShort4> operator<<=(const UShort4 &lhs, unsigned char rhs);
+	RValue<UShort4> operator>>=(const UShort4 &lhs, unsigned char rhs);
+	RValue<UShort4> operator<<=(const UShort4 &lhs, RValue<Long1> rhs);
+	RValue<UShort4> operator>>=(const UShort4 &lhs, RValue<Long1> rhs);
+//	RValue<UShort4> operator+(RValue<UShort4> val);
+//	RValue<UShort4> operator-(RValue<UShort4> val);
+	RValue<UShort4> operator~(RValue<UShort4> val);
+//	RValue<UShort4> operator++(const UShort4 &val, int);   // Post-increment
+//	const UShort4 &operator++(const UShort4 &val);   // Pre-increment
+//	RValue<UShort4> operator--(const UShort4 &val, int);   // Post-decrement
+//	const UShort4 &operator--(const UShort4 &val);   // Pre-decrement
+
+	RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y);
+	RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y);
+	RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y);
+	RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);
+	RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);
+	RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);
+	RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y);
+
+	class Short8 : public Variable<Short8>
+	{
+	public:
+	//	Short8();
+		Short8(short c0, short c1, short c2, short c3, short c4, short c5, short c6, short c7);
+		Short8(RValue<Short8> rhs);
+	//	Short8(const Short8 &rhs);
+	//	Short8(const Reference<Short8> &rhs);
+		Short8(RValue<Short4> lo, RValue<Short4> hi);
+
+	//	RValue<Short8> operator=(RValue<Short8> rhs) const;
+	//	RValue<Short8> operator=(const Short8 &rhs) const;
+	//	RValue<Short8> operator=(const Reference<Short8> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator-(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator*(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator/(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator%(RValue<Short8> lhs, RValue<Short8> rhs);
+	RValue<Short8> operator&(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator|(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator^(RValue<Short8> lhs, RValue<Short8> rhs);
+	RValue<Short8> operator<<(RValue<Short8> lhs, unsigned char rhs);
+	RValue<Short8> operator>>(RValue<Short8> lhs, unsigned char rhs);
+//	RValue<Short8> operator<<(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator>>(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator+=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator-=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator*=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator/=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator%=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator&=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator|=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator^=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator<<=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator>>=(const Short8 &lhs, RValue<Short8> rhs);
+//	RValue<Short8> operator+(RValue<Short8> val);
+//	RValue<Short8> operator-(RValue<Short8> val);
+//	RValue<Short8> operator~(RValue<Short8> val);
+//	RValue<Short8> operator++(const Short8 &val, int);   // Post-increment
+//	const Short8 &operator++(const Short8 &val);   // Pre-increment
+//	RValue<Short8> operator--(const Short8 &val, int);   // Post-decrement
+//	const Short8 &operator--(const Short8 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Bool> operator<=(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Bool> operator>(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Bool> operator>=(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Bool> operator!=(RValue<Short8> lhs, RValue<Short8> rhs);
+//	RValue<Bool> operator==(RValue<Short8> lhs, RValue<Short8> rhs);
+
+	RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y);
+	RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y);
+	RValue<Int4> Abs(RValue<Int4> x);
+
+	class UShort8 : public Variable<UShort8>
+	{
+	public:
+	//	UShort8();
+		UShort8(unsigned short c0, unsigned short c1, unsigned short c2, unsigned short c3, unsigned short c4, unsigned short c5, unsigned short c6, unsigned short c7);
+		UShort8(RValue<UShort8> rhs);
+	//	UShort8(const UShort8 &rhs);
+	//	UShort8(const Reference<UShort8> &rhs);
+		UShort8(RValue<UShort4> lo, RValue<UShort4> hi);
+
+		RValue<UShort8> operator=(RValue<UShort8> rhs) const;
+		RValue<UShort8> operator=(const UShort8 &rhs) const;
+		RValue<UShort8> operator=(const Reference<UShort8> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<UShort8> operator+(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator-(RValue<UShort8> lhs, RValue<UShort8> rhs);
+	RValue<UShort8> operator*(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator/(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator%(RValue<UShort8> lhs, RValue<UShort8> rhs);
+	RValue<UShort8> operator&(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator|(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator^(RValue<UShort8> lhs, RValue<UShort8> rhs);
+	RValue<UShort8> operator<<(RValue<UShort8> lhs, unsigned char rhs);
+	RValue<UShort8> operator>>(RValue<UShort8> lhs, unsigned char rhs);
+//	RValue<UShort8> operator<<(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator>>(RValue<UShort8> lhs, RValue<UShort8> rhs);
+	RValue<UShort8> operator+=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator-=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator*=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator/=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator%=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator&=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator|=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator^=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator<<=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator>>=(const UShort8 &lhs, RValue<UShort8> rhs);
+//	RValue<UShort8> operator+(RValue<UShort8> val);
+//	RValue<UShort8> operator-(RValue<UShort8> val);
+	RValue<UShort8> operator~(RValue<UShort8> val);
+//	RValue<UShort8> operator++(const UShort8 &val, int);   // Post-increment
+//	const UShort8 &operator++(const UShort8 &val);   // Pre-increment
+//	RValue<UShort8> operator--(const UShort8 &val, int);   // Post-decrement
+//	const UShort8 &operator--(const UShort8 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<Bool> operator<=(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<Bool> operator>(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<Bool> operator>=(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<Bool> operator!=(RValue<UShort8> lhs, RValue<UShort8> rhs);
+//	RValue<Bool> operator==(RValue<UShort8> lhs, RValue<UShort8> rhs);
+
+	RValue<UShort8> Swizzle(RValue<UShort8> x, char select0, char select1, char select2, char select3, char select4, char select5, char select6, char select7);
+	RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y);
+
+	class Int : public Variable<Int>
+	{
+	public:
+		Int(Argument<Int> argument);
+
+		explicit Int(RValue<Byte> cast);
+		explicit Int(RValue<SByte> cast);
+		explicit Int(RValue<Short> cast);
+		explicit Int(RValue<UShort> cast);
+		explicit Int(RValue<Int2> cast);
+		explicit Int(RValue<Long> cast);
+		explicit Int(RValue<Float> cast);
+
+		Int();
+		Int(int x);
+		Int(RValue<Int> rhs);
+		Int(RValue<UInt> rhs);
+		Int(const Int &rhs);
+		Int(const UInt &rhs);
+		Int(const Reference<Int> &rhs);
+		Int(const Reference<UInt> &rhs);
+
+		RValue<Int> operator=(int rhs) const;
+		RValue<Int> operator=(RValue<Int> rhs) const;
+		RValue<Int> operator=(RValue<UInt> rhs) const;
+		RValue<Int> operator=(const Int &rhs) const;
+		RValue<Int> operator=(const UInt &rhs) const;
+		RValue<Int> operator=(const Reference<Int> &rhs) const;
+		RValue<Int> operator=(const Reference<UInt> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Int> operator+(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator-(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator*(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator/(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator%(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator&(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator|(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator^(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator<<(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator>>(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Int> operator+=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator-=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator*=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator/=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator%=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator&=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator|=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator^=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator<<=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator>>=(const Int &lhs, RValue<Int> rhs);
+	RValue<Int> operator+(RValue<Int> val);
+	RValue<Int> operator-(RValue<Int> val);
+	RValue<Int> operator~(RValue<Int> val);
+	RValue<Int> operator++(const Int &val, int);   // Post-increment
+	const Int &operator++(const Int &val);   // Pre-increment
+	RValue<Int> operator--(const Int &val, int);   // Post-decrement
+	const Int &operator--(const Int &val);   // Pre-decrement
+	RValue<Bool> operator<(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Bool> operator<=(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Bool> operator>(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Bool> operator>=(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Bool> operator!=(RValue<Int> lhs, RValue<Int> rhs);
+	RValue<Bool> operator==(RValue<Int> lhs, RValue<Int> rhs);
+
+	RValue<Int> Max(RValue<Int> x, RValue<Int> y);
+	RValue<Int> Min(RValue<Int> x, RValue<Int> y);
+	RValue<Int> Clamp(RValue<Int> x, RValue<Int> min, RValue<Int> max);
+	RValue<Int> RoundInt(RValue<Float> cast);
+
+	class Long : public Variable<Long>
+	{
+	public:
+	//	Long(Argument<Long> argument);
+
+	//	explicit Long(RValue<Short> cast);
+	//	explicit Long(RValue<UShort> cast);
+		explicit Long(RValue<Int> cast);
+		explicit Long(RValue<UInt> cast);
+	//	explicit Long(RValue<Float> cast);
+
+		Long();
+	//	Long(qword x);
+		Long(RValue<Long> rhs);
+	//	Long(RValue<ULong> rhs);
+	//	Long(const Long &rhs);
+	//	Long(const Reference<Long> &rhs);
+	//	Long(const ULong &rhs);
+	//	Long(const Reference<ULong> &rhs);
+
+		RValue<Long> operator=(int64_t rhs) const;
+		RValue<Long> operator=(RValue<Long> rhs) const;
+	//	RValue<Long> operator=(RValue<ULong> rhs) const;
+		RValue<Long> operator=(const Long &rhs) const;
+		RValue<Long> operator=(const Reference<Long> &rhs) const;
+	//	RValue<Long> operator=(const ULong &rhs) const;
+	//	RValue<Long> operator=(const Reference<ULong> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Long> operator+(RValue<Long> lhs, RValue<Long> rhs);
+	RValue<Long> operator-(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator*(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator/(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator%(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator&(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator|(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator^(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator<<(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Long> operator>>(RValue<Long> lhs, RValue<Long> rhs);
+	RValue<Long> operator+=(const Long &lhs, RValue<Long> rhs);
+	RValue<Long> operator-=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator*=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator/=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator%=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator&=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator|=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator^=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator<<=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator>>=(const Long &lhs, RValue<Long> rhs);
+//	RValue<Long> operator+(RValue<Long> val);
+//	RValue<Long> operator-(RValue<Long> val);
+//	RValue<Long> operator~(RValue<Long> val);
+//	RValue<Long> operator++(const Long &val, int);   // Post-increment
+//	const Long &operator++(const Long &val);   // Pre-increment
+//	RValue<Long> operator--(const Long &val, int);   // Post-decrement
+//	const Long &operator--(const Long &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Bool> operator<=(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Bool> operator>(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Bool> operator>=(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Bool> operator!=(RValue<Long> lhs, RValue<Long> rhs);
+//	RValue<Bool> operator==(RValue<Long> lhs, RValue<Long> rhs);
+
+//	RValue<Long> RoundLong(RValue<Float> cast);
+	RValue<Long> AddAtomic( RValue<Pointer<Long>> x, RValue<Long> y);
+
+	class Long1 : public Variable<Long1>
+	{
+	public:
+	//	Long1(Argument<Long1> argument);
+
+	//	explicit Long1(RValue<Short> cast);
+	//	explicit Long1(RValue<UShort> cast);
+	//	explicit Long1(RValue<Int> cast);
+		explicit Long1(RValue<UInt> cast);
+	//	explicit Long1(RValue<Float> cast);
+
+	//	Long1();
+	//	Long1(qword x);
+		Long1(RValue<Long1> rhs);
+	//	Long1(RValue<ULong1> rhs);
+	//	Long1(const Long1 &rhs);
+	//	Long1(const Reference<Long1> &rhs);
+	//	Long1(const ULong1 &rhs);
+	//	Long1(const Reference<ULong1> &rhs);
+
+	//	RValue<Long1> operator=(qword rhs) const;
+	//	RValue<Long1> operator=(RValue<Long1> rhs) const;
+	//	RValue<Long1> operator=(RValue<ULong1> rhs) const;
+	//	RValue<Long1> operator=(const Long1 &rhs) const;
+	//	RValue<Long1> operator=(const Reference<Long1> &rhs) const;
+	//	RValue<Long1> operator=(const ULong1 &rhs) const;
+	//	RValue<Long1> operator=(const Reference<ULong1> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+//	RValue<Long1> operator+(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator-(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator*(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator/(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator%(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator&(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator|(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator^(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator<<(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator>>(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator+=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator-=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator*=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator/=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator%=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator&=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator|=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator^=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator<<=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator>>=(const Long1 &lhs, RValue<Long1> rhs);
+//	RValue<Long1> operator+(RValue<Long1> val);
+//	RValue<Long1> operator-(RValue<Long1> val);
+//	RValue<Long1> operator~(RValue<Long1> val);
+//	RValue<Long1> operator++(const Long1 &val, int);   // Post-increment
+//	const Long1 &operator++(const Long1 &val);   // Pre-increment
+//	RValue<Long1> operator--(const Long1 &val, int);   // Post-decrement
+//	const Long1 &operator--(const Long1 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Bool> operator<=(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Bool> operator>(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Bool> operator>=(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Bool> operator!=(RValue<Long1> lhs, RValue<Long1> rhs);
+//	RValue<Bool> operator==(RValue<Long1> lhs, RValue<Long1> rhs);
+
+//	RValue<Long1> RoundLong1(RValue<Float> cast);
+
+	class Long2 : public Variable<Long2>
+	{
+	public:
+	//	explicit Long2(RValue<Long> cast);
+	//	explicit Long2(RValue<Long1> cast);
+
+	//	Long2();
+	//	Long2(int x, int y);
+	//	Long2(RValue<Long2> rhs);
+	//	Long2(const Long2 &rhs);
+	//	Long2(const Reference<Long2> &rhs);
+
+	//	RValue<Long2> operator=(RValue<Long2> rhs) const;
+	//	RValue<Long2> operator=(const Long2 &rhs) const;
+	//	RValue<Long2> operator=(const Reference<Long2 &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+//	RValue<Long2> operator+(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator-(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator*(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator/(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator%(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator&(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator|(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator^(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator<<(RValue<Long2> lhs, unsigned char rhs);
+//	RValue<Long2> operator>>(RValue<Long2> lhs, unsigned char rhs);
+//	RValue<Long2> operator<<(RValue<Long2> lhs, RValue<Long1> rhs);
+//	RValue<Long2> operator>>(RValue<Long2> lhs, RValue<Long1> rhs);
+//	RValue<Long2> operator+=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator-=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator*=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator/=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator%=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator&=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator|=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator^=(const Long2 &lhs, RValue<Long2> rhs);
+//	RValue<Long2> operator<<=(const Long2 &lhs, unsigned char rhs);
+//	RValue<Long2> operator>>=(const Long2 &lhs, unsigned char rhs);
+//	RValue<Long2> operator<<=(const Long2 &lhs, RValue<Long1> rhs);
+//	RValue<Long2> operator>>=(const Long2 &lhs, RValue<Long1> rhs);
+//	RValue<Long2> operator+(RValue<Long2> val);
+//	RValue<Long2> operator-(RValue<Long2> val);
+//	RValue<Long2> operator~(RValue<Long2> val);
+//	RValue<Long2> operator++(const Long2 &val, int);   // Post-increment
+//	const Long2 &operator++(const Long2 &val);   // Pre-increment
+//	RValue<Long2> operator--(const Long2 &val, int);   // Post-decrement
+//	const Long2 &operator--(const Long2 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Bool> operator<=(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Bool> operator>(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Bool> operator>=(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Bool> operator!=(RValue<Long2> lhs, RValue<Long2> rhs);
+//	RValue<Bool> operator==(RValue<Long2> lhs, RValue<Long2> rhs);
+
+//	RValue<Long2> RoundInt(RValue<Float4> cast);
+//	RValue<Long2> UnpackLow(RValue<Long2> x, RValue<Long2> y);
+	RValue<Long2> UnpackHigh(RValue<Long2> x, RValue<Long2> y);
+//	RValue<Int> Extract(RValue<Long2> val, int i);
+//	RValue<Long2> Insert(RValue<Long2> val, RValue<Int> element, int i);
+
+	class UInt : public Variable<UInt>
+	{
+	public:
+		UInt(Argument<UInt> argument);
+
+		explicit UInt(RValue<UShort> cast);
+		explicit UInt(RValue<Long> cast);
+		explicit UInt(RValue<Float> cast);
+
+		UInt();
+		UInt(int x);
+		UInt(unsigned int x);
+		UInt(RValue<UInt> rhs);
+		UInt(RValue<Int> rhs);
+		UInt(const UInt &rhs);
+		UInt(const Int &rhs);
+		UInt(const Reference<UInt> &rhs);
+		UInt(const Reference<Int> &rhs);
+
+		RValue<UInt> operator=(unsigned int rhs) const;
+		RValue<UInt> operator=(RValue<UInt> rhs) const;
+		RValue<UInt> operator=(RValue<Int> rhs) const;
+		RValue<UInt> operator=(const UInt &rhs) const;
+		RValue<UInt> operator=(const Int &rhs) const;
+		RValue<UInt> operator=(const Reference<UInt> &rhs) const;
+		RValue<UInt> operator=(const Reference<Int> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<UInt> operator+(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator-(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator*(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator/(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator%(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator&(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator|(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator^(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator<<(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator>>(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<UInt> operator+=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator-=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator*=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator/=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator%=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator&=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator|=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator^=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator<<=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator>>=(const UInt &lhs, RValue<UInt> rhs);
+	RValue<UInt> operator+(RValue<UInt> val);
+	RValue<UInt> operator-(RValue<UInt> val);
+	RValue<UInt> operator~(RValue<UInt> val);
+	RValue<UInt> operator++(const UInt &val, int);   // Post-increment
+	const UInt &operator++(const UInt &val);   // Pre-increment
+	RValue<UInt> operator--(const UInt &val, int);   // Post-decrement
+	const UInt &operator--(const UInt &val);   // Pre-decrement
+	RValue<Bool> operator<(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<Bool> operator<=(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<Bool> operator>(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<Bool> operator>=(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<Bool> operator!=(RValue<UInt> lhs, RValue<UInt> rhs);
+	RValue<Bool> operator==(RValue<UInt> lhs, RValue<UInt> rhs);
+
+	RValue<UInt> Max(RValue<UInt> x, RValue<UInt> y);
+	RValue<UInt> Min(RValue<UInt> x, RValue<UInt> y);
+	RValue<UInt> Clamp(RValue<UInt> x, RValue<UInt> min, RValue<UInt> max);
+//	RValue<UInt> RoundUInt(RValue<Float> cast);
+
+	class Int2 : public Variable<Int2>
+	{
+	public:
+	//	explicit Int2(RValue<Int> cast);
+		explicit Int2(RValue<Int4> cast);
+
+		Int2();
+		Int2(int x, int y);
+		Int2(RValue<Int2> rhs);
+		Int2(const Int2 &rhs);
+		Int2(const Reference<Int2> &rhs);
+		Int2(RValue<Int> lo, RValue<Int> hi);
+
+		RValue<Int2> operator=(RValue<Int2> rhs) const;
+		RValue<Int2> operator=(const Int2 &rhs) const;
+		RValue<Int2> operator=(const Reference<Int2> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Int2> operator+(RValue<Int2> lhs, RValue<Int2> rhs);
+	RValue<Int2> operator-(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Int2> operator*(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Int2> operator/(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Int2> operator%(RValue<Int2> lhs, RValue<Int2> rhs);
+	RValue<Int2> operator&(RValue<Int2> lhs, RValue<Int2> rhs);
+	RValue<Int2> operator|(RValue<Int2> lhs, RValue<Int2> rhs);
+	RValue<Int2> operator^(RValue<Int2> lhs, RValue<Int2> rhs);
+	RValue<Int2> operator<<(RValue<Int2> lhs, unsigned char rhs);
+	RValue<Int2> operator>>(RValue<Int2> lhs, unsigned char rhs);
+	RValue<Int2> operator<<(RValue<Int2> lhs, RValue<Long1> rhs);
+	RValue<Int2> operator>>(RValue<Int2> lhs, RValue<Long1> rhs);
+	RValue<Int2> operator+=(const Int2 &lhs, RValue<Int2> rhs);
+	RValue<Int2> operator-=(const Int2 &lhs, RValue<Int2> rhs);
+//	RValue<Int2> operator*=(const Int2 &lhs, RValue<Int2> rhs);
+//	RValue<Int2> operator/=(const Int2 &lhs, RValue<Int2> rhs);
+//	RValue<Int2> operator%=(const Int2 &lhs, RValue<Int2> rhs);
+	RValue<Int2> operator&=(const Int2 &lhs, RValue<Int2> rhs);
+	RValue<Int2> operator|=(const Int2 &lhs, RValue<Int2> rhs);
+	RValue<Int2> operator^=(const Int2 &lhs, RValue<Int2> rhs);
+	RValue<Int2> operator<<=(const Int2 &lhs, unsigned char rhs);
+	RValue<Int2> operator>>=(const Int2 &lhs, unsigned char rhs);
+	RValue<Int2> operator<<=(const Int2 &lhs, RValue<Long1> rhs);
+	RValue<Int2> operator>>=(const Int2 &lhs, RValue<Long1> rhs);
+//	RValue<Int2> operator+(RValue<Int2> val);
+//	RValue<Int2> operator-(RValue<Int2> val);
+	RValue<Int2> operator~(RValue<Int2> val);
+//	RValue<Int2> operator++(const Int2 &val, int);   // Post-increment
+//	const Int2 &operator++(const Int2 &val);   // Pre-increment
+//	RValue<Int2> operator--(const Int2 &val, int);   // Post-decrement
+//	const Int2 &operator--(const Int2 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Bool> operator<=(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Bool> operator>(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Bool> operator>=(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Bool> operator!=(RValue<Int2> lhs, RValue<Int2> rhs);
+//	RValue<Bool> operator==(RValue<Int2> lhs, RValue<Int2> rhs);
+
+//	RValue<Int2> RoundInt(RValue<Float4> cast);
+	RValue<Long1> UnpackLow(RValue<Int2> x, RValue<Int2> y);
+	RValue<Long1> UnpackHigh(RValue<Int2> x, RValue<Int2> y);
+	RValue<Int> Extract(RValue<Int2> val, int i);
+	RValue<Int2> Insert(RValue<Int2> val, RValue<Int> element, int i);
+
+	class UInt2 : public Variable<UInt2>
+	{
+	public:
+		UInt2();
+		UInt2(unsigned int x, unsigned int y);
+		UInt2(RValue<UInt2> rhs);
+		UInt2(const UInt2 &rhs);
+		UInt2(const Reference<UInt2> &rhs);
+
+		RValue<UInt2> operator=(RValue<UInt2> rhs) const;
+		RValue<UInt2> operator=(const UInt2 &rhs) const;
+		RValue<UInt2> operator=(const Reference<UInt2> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<UInt2> operator+(RValue<UInt2> lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator-(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<UInt2> operator*(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<UInt2> operator/(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<UInt2> operator%(RValue<UInt2> lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator&(RValue<UInt2> lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator|(RValue<UInt2> lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator^(RValue<UInt2> lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator<<(RValue<UInt2> lhs, unsigned char rhs);
+	RValue<UInt2> operator>>(RValue<UInt2> lhs, unsigned char rhs);
+	RValue<UInt2> operator<<(RValue<UInt2> lhs, RValue<Long1> rhs);
+	RValue<UInt2> operator>>(RValue<UInt2> lhs, RValue<Long1> rhs);
+	RValue<UInt2> operator+=(const UInt2 &lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator-=(const UInt2 &lhs, RValue<UInt2> rhs);
+//	RValue<UInt2> operator*=(const UInt2 &lhs, RValue<UInt2> rhs);
+//	RValue<UInt2> operator/=(const UInt2 &lhs, RValue<UInt2> rhs);
+//	RValue<UInt2> operator%=(const UInt2 &lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator&=(const UInt2 &lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator|=(const UInt2 &lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator^=(const UInt2 &lhs, RValue<UInt2> rhs);
+	RValue<UInt2> operator<<=(const UInt2 &lhs, unsigned char rhs);
+	RValue<UInt2> operator>>=(const UInt2 &lhs, unsigned char rhs);
+	RValue<UInt2> operator<<=(const UInt2 &lhs, RValue<Long1> rhs);
+	RValue<UInt2> operator>>=(const UInt2 &lhs, RValue<Long1> rhs);
+//	RValue<UInt2> operator+(RValue<UInt2> val);
+//	RValue<UInt2> operator-(RValue<UInt2> val);
+	RValue<UInt2> operator~(RValue<UInt2> val);
+//	RValue<UInt2> operator++(const UInt2 &val, int);   // Post-increment
+//	const UInt2 &operator++(const UInt2 &val);   // Pre-increment
+//	RValue<UInt2> operator--(const UInt2 &val, int);   // Post-decrement
+//	const UInt2 &operator--(const UInt2 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<Bool> operator<=(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<Bool> operator>(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<Bool> operator>=(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<Bool> operator!=(RValue<UInt2> lhs, RValue<UInt2> rhs);
+//	RValue<Bool> operator==(RValue<UInt2> lhs, RValue<UInt2> rhs);
+
+//	RValue<UInt2> RoundInt(RValue<Float4> cast);
+
+	class Int4 : public Variable<Int4>
+	{
+	public:
+		explicit Int4(RValue<Float4> cast);
+		explicit Int4(RValue<Short4> cast);
+		explicit Int4(RValue<UShort4> cast);
+
+		Int4();
+		Int4(int xyzw);
+		Int4(int x, int yzw);
+		Int4(int x, int y, int zw);
+		Int4(int x, int y, int z, int w);
+		Int4(RValue<Int4> rhs);
+		Int4(const Int4 &rhs);
+		Int4(const Reference<Int4> &rhs);
+		Int4(RValue<UInt4> rhs);
+		Int4(const UInt4 &rhs);
+		Int4(const Reference<UInt4> &rhs);
+		Int4(RValue<Int2> lo, RValue<Int2> hi);
+
+		RValue<Int4> operator=(RValue<Int4> rhs) const;
+		RValue<Int4> operator=(const Int4 &rhs) const;
+		RValue<Int4> operator=(const Reference<Int4> &rhs) const;
+
+		static llvm::Type *getType();
+
+	private:
+		void constant(int x, int y, int z, int w);
+	};
+
+	RValue<Int4> operator+(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator-(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator*(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator/(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator%(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator&(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator|(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator^(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator<<(RValue<Int4> lhs, unsigned char rhs);
+	RValue<Int4> operator>>(RValue<Int4> lhs, unsigned char rhs);
+	RValue<Int4> operator<<(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator>>(RValue<Int4> lhs, RValue<Int4> rhs);
+	RValue<Int4> operator+=(const Int4 &lhs, RValue<Int4> rhs);
+	RValue<Int4> operator-=(const Int4 &lhs, RValue<Int4> rhs);
+	RValue<Int4> operator*=(const Int4 &lhs, RValue<Int4> rhs);
+//	RValue<Int4> operator/=(const Int4 &lhs, RValue<Int4> rhs);
+//	RValue<Int4> operator%=(const Int4 &lhs, RValue<Int4> rhs);
+	RValue<Int4> operator&=(const Int4 &lhs, RValue<Int4> rhs);
+	RValue<Int4> operator|=(const Int4 &lhs, RValue<Int4> rhs);
+	RValue<Int4> operator^=(const Int4 &lhs, RValue<Int4> rhs);
+	RValue<Int4> operator<<=(const Int4 &lhs, unsigned char rhs);
+	RValue<Int4> operator>>=(const Int4 &lhs, unsigned char rhs);
+	RValue<Int4> operator+(RValue<Int4> val);
+	RValue<Int4> operator-(RValue<Int4> val);
+	RValue<Int4> operator~(RValue<Int4> val);
+//	RValue<Int4> operator++(const Int4 &val, int);   // Post-increment
+//	const Int4 &operator++(const Int4 &val);   // Pre-increment
+//	RValue<Int4> operator--(const Int4 &val, int);   // Post-decrement
+//	const Int4 &operator--(const Int4 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<Int4> lhs, RValue<Int4> rhs);
+//	RValue<Bool> operator<=(RValue<Int4> lhs, RValue<Int4> rhs);
+//	RValue<Bool> operator>(RValue<Int4> lhs, RValue<Int4> rhs);
+//	RValue<Bool> operator>=(RValue<Int4> lhs, RValue<Int4> rhs);
+//	RValue<Bool> operator!=(RValue<Int4> lhs, RValue<Int4> rhs);
+//	RValue<Bool> operator==(RValue<Int4> lhs, RValue<Int4> rhs);
+
+	RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int4> RoundInt(RValue<Float4> cast);
+	RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y);
+	RValue<Int> Extract(RValue<Int4> x, int i);
+	RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);
+	RValue<Int> SignMask(RValue<Int4> x);
+	RValue<Int4> Swizzle(RValue<Int4> x, unsigned char select);
+
+	class UInt4 : public Variable<UInt4>
+	{
+	public:
+		explicit UInt4(RValue<Float4> cast);
+
+		UInt4();
+		UInt4(int xyzw);
+		UInt4(int x, int yzw);
+		UInt4(int x, int y, int zw);
+		UInt4(int x, int y, int z, int w);
+		UInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w);
+		UInt4(RValue<UInt4> rhs);
+		UInt4(const UInt4 &rhs);
+		UInt4(const Reference<UInt4> &rhs);
+		UInt4(RValue<Int4> rhs);
+		UInt4(const Int4 &rhs);
+		UInt4(const Reference<Int4> &rhs);
+		UInt4(RValue<UInt2> lo, RValue<UInt2> hi);
+
+		RValue<UInt4> operator=(RValue<UInt4> rhs) const;
+		RValue<UInt4> operator=(const UInt4 &rhs) const;
+		RValue<UInt4> operator=(const Reference<UInt4> &rhs) const;
+
+		static llvm::Type *getType();
+
+	private:
+		void constant(int x, int y, int z, int w);
+	};
+
+	RValue<UInt4> operator+(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator-(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator*(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator/(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator%(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator&(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator|(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator^(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator<<(RValue<UInt4> lhs, unsigned char rhs);
+	RValue<UInt4> operator>>(RValue<UInt4> lhs, unsigned char rhs);
+	RValue<UInt4> operator<<(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator>>(RValue<UInt4> lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator+=(const UInt4 &lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator-=(const UInt4 &lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator*=(const UInt4 &lhs, RValue<UInt4> rhs);
+//	RValue<UInt4> operator/=(const UInt4 &lhs, RValue<UInt4> rhs);
+//	RValue<UInt4> operator%=(const UInt4 &lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator&=(const UInt4 &lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator|=(const UInt4 &lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator^=(const UInt4 &lhs, RValue<UInt4> rhs);
+	RValue<UInt4> operator<<=(const UInt4 &lhs, unsigned char rhs);
+	RValue<UInt4> operator>>=(const UInt4 &lhs, unsigned char rhs);
+	RValue<UInt4> operator+(RValue<UInt4> val);
+	RValue<UInt4> operator-(RValue<UInt4> val);
+	RValue<UInt4> operator~(RValue<UInt4> val);
+//	RValue<UInt4> operator++(const UInt4 &val, int);   // Post-increment
+//	const UInt4 &operator++(const UInt4 &val);   // Pre-increment
+//	RValue<UInt4> operator--(const UInt4 &val, int);   // Post-decrement
+//	const UInt4 &operator--(const UInt4 &val);   // Pre-decrement
+//	RValue<Bool> operator<(RValue<UInt4> lhs, RValue<UInt4> rhs);
+//	RValue<Bool> operator<=(RValue<UInt4> lhs, RValue<UInt4> rhs);
+//	RValue<Bool> operator>(RValue<UInt4> lhs, RValue<UInt4> rhs);
+//	RValue<Bool> operator>=(RValue<UInt4> lhs, RValue<UInt4> rhs);
+//	RValue<Bool> operator!=(RValue<UInt4> lhs, RValue<UInt4> rhs);
+//	RValue<Bool> operator==(RValue<UInt4> lhs, RValue<UInt4> rhs);
+
+	RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y);
+	RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y);
+	RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y);
+	RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y);
+	RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y);
+	RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y);
+	RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
+	RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
+//	RValue<UInt4> RoundInt(RValue<Float4> cast);
+	RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y);
+
+	template<int T>
+	class Swizzle2Float4
+	{
+		friend class Float4;
+
+	public:
+		operator RValue<Float4>() const;
+
+	private:
+		Float4 *parent;
+	};
+
+	template<int T>
+	class SwizzleFloat4
+	{
+	public:
+		operator RValue<Float4>() const;
+
+	private:
+		Float4 *parent;
+	};
+
+	template<int T>
+	class SwizzleMaskFloat4
+	{
+		friend class Float4;
+
+	public:
+		operator RValue<Float4>() const;
+
+		RValue<Float4> operator=(RValue<Float4> rhs) const;
+		RValue<Float4> operator=(RValue<Float> rhs) const;
+
+	private:
+		Float4 *parent;
+	};
+
+	template<int T>
+	class SwizzleMask1Float4
+	{
+	public:
+		operator RValue<Float>() const;
+		operator RValue<Float4>() const;
+
+		RValue<Float4> operator=(float x) const;
+		RValue<Float4> operator=(RValue<Float4> rhs) const;
+		RValue<Float4> operator=(RValue<Float> rhs) const;
+
+	private:
+		Float4 *parent;
+	};
+
+	template<int T>
+	class SwizzleMask2Float4
+	{
+		friend class Float4;
+
+	public:
+		operator RValue<Float4>() const;
+
+		RValue<Float4> operator=(RValue<Float4> rhs) const;
+
+	private:
+		Float4 *parent;
+	};
+
+	class Float : public Variable<Float>
+	{
+	public:
+		explicit Float(RValue<Int> cast);
+
+		Float();
+		Float(float x);
+		Float(RValue<Float> rhs);
+		Float(const Float &rhs);
+		Float(const Reference<Float> &rhs);
+
+		template<int T>
+		Float(const SwizzleMask1Float4<T> &rhs);
+
+	//	RValue<Float> operator=(float rhs) const;   // FIXME: Implement
+		RValue<Float> operator=(RValue<Float> rhs) const;
+		RValue<Float> operator=(const Float &rhs) const;
+		RValue<Float> operator=(const Reference<Float> &rhs) const;
+
+		template<int T>
+		RValue<Float> operator=(const SwizzleMask1Float4<T> &rhs) const;
+
+		static llvm::Type *getType();
+	};
+
+	RValue<Float> operator+(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Float> operator-(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Float> operator*(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Float> operator/(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Float> operator+=(const Float &lhs, RValue<Float> rhs);
+	RValue<Float> operator-=(const Float &lhs, RValue<Float> rhs);
+	RValue<Float> operator*=(const Float &lhs, RValue<Float> rhs);
+	RValue<Float> operator/=(const Float &lhs, RValue<Float> rhs);
+	RValue<Float> operator+(RValue<Float> val);
+	RValue<Float> operator-(RValue<Float> val);
+	RValue<Bool> operator<(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Bool> operator<=(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Bool> operator>(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Bool> operator>=(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Bool> operator!=(RValue<Float> lhs, RValue<Float> rhs);
+	RValue<Bool> operator==(RValue<Float> lhs, RValue<Float> rhs);
+
+	RValue<Float> Abs(RValue<Float> x);
+	RValue<Float> Max(RValue<Float> x, RValue<Float> y);
+	RValue<Float> Min(RValue<Float> x, RValue<Float> y);
+	RValue<Float> Rcp_pp(RValue<Float> val, bool exactAtPow2 = false);
+	RValue<Float> RcpSqrt_pp(RValue<Float> val);
+	RValue<Float> Sqrt(RValue<Float> x);
+	RValue<Float> Round(RValue<Float> val);
+	RValue<Float> Trunc(RValue<Float> val);
+	RValue<Float> Frac(RValue<Float> val);
+	RValue<Float> Floor(RValue<Float> val);
+	RValue<Float> Ceil(RValue<Float> val);
+
+	class Float2 : public Variable<Float2>
+	{
+	public:
+	//	explicit Float2(RValue<Byte2> cast);
+	//	explicit Float2(RValue<Short2> cast);
+	//	explicit Float2(RValue<UShort2> cast);
+	//	explicit Float2(RValue<Int2> cast);
+	//	explicit Float2(RValue<UInt2> cast);
+		explicit Float2(RValue<Float4> cast);
+
+	//	Float2();
+	//	Float2(float x, float y);
+	//	Float2(RValue<Float2> rhs);
+	//	Float2(const Float2 &rhs);
+	//	Float2(const Reference<Float2> &rhs);
+	//	Float2(RValue<Float> rhs);
+	//	Float2(const Float &rhs);
+	//	Float2(const Reference<Float> &rhs);
+
+	//	template<int T>
+	//	Float2(const SwizzleMask1Float4<T> &rhs);
+
+	//	RValue<Float2> operator=(float replicate) const;
+	//	RValue<Float2> operator=(RValue<Float2> rhs) const;
+	//	RValue<Float2> operator=(const Float2 &rhs) const;
+	//	RValue<Float2> operator=(const Reference<Float2> &rhs) const;
+	//	RValue<Float2> operator=(RValue<Float> rhs) const;
+	//	RValue<Float2> operator=(const Float &rhs) const;
+	//	RValue<Float2> operator=(const Reference<Float> &rhs) const;
+
+	//	template<int T>
+	//	RValue<Float2> operator=(const SwizzleMask1Float4<T> &rhs);
+
+		static llvm::Type *getType();
+	};
+
+//	RValue<Float2> operator+(RValue<Float2> lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator-(RValue<Float2> lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator*(RValue<Float2> lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator/(RValue<Float2> lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator%(RValue<Float2> lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator+=(const Float2 &lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator-=(const Float2 &lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator*=(const Float2 &lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator/=(const Float2 &lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator%=(const Float2 &lhs, RValue<Float2> rhs);
+//	RValue<Float2> operator+(RValue<Float2> val);
+//	RValue<Float2> operator-(RValue<Float2> val);
+
+//	RValue<Float2> Abs(RValue<Float2> x);
+//	RValue<Float2> Max(RValue<Float2> x, RValue<Float2> y);
+//	RValue<Float2> Min(RValue<Float2> x, RValue<Float2> y);
+//	RValue<Float2> Swizzle(RValue<Float2> x, unsigned char select);
+//	RValue<Float2> Mask(Float2 &lhs, RValue<Float2> rhs, unsigned char select);
+
+	class Float4 : public Variable<Float4>
+	{
+	public:
+		explicit Float4(RValue<Byte4> cast);
+		explicit Float4(RValue<SByte4> cast);
+		explicit Float4(RValue<Short4> cast);
+		explicit Float4(RValue<UShort4> cast);
+		explicit Float4(RValue<Int4> cast);
+		explicit Float4(RValue<UInt4> cast);
+
+		Float4();
+		Float4(float xyzw);
+		Float4(float x, float yzw);
+		Float4(float x, float y, float zw);
+		Float4(float x, float y, float z, float w);
+		Float4(RValue<Float4> rhs);
+		Float4(const Float4 &rhs);
+		Float4(const Reference<Float4> &rhs);
+		Float4(RValue<Float> rhs);
+		Float4(const Float &rhs);
+		Float4(const Reference<Float> &rhs);
+
+		template<int T>
+		Float4(const SwizzleMask1Float4<T> &rhs);
+		template<int T>
+		Float4(const SwizzleFloat4<T> &rhs);
+		template<int X, int Y>
+		Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y);
+		template<int X, int Y>
+		Float4(const SwizzleMask2Float4<X> &x, const Swizzle2Float4<Y> &y);
+		template<int X, int Y>
+		Float4(const Swizzle2Float4<X> &x, const SwizzleMask2Float4<Y> &y);
+		template<int X, int Y>
+		Float4(const SwizzleMask2Float4<X> &x, const SwizzleMask2Float4<Y> &y);
+
+		RValue<Float4> operator=(float replicate) const;
+		RValue<Float4> operator=(RValue<Float4> rhs) const;
+		RValue<Float4> operator=(const Float4 &rhs) const;
+		RValue<Float4> operator=(const Reference<Float4> &rhs) const;
+		RValue<Float4> operator=(RValue<Float> rhs) const;
+		RValue<Float4> operator=(const Float &rhs) const;
+		RValue<Float4> operator=(const Reference<Float> &rhs) const;
+
+		template<int T>
+		RValue<Float4> operator=(const SwizzleMask1Float4<T> &rhs);
+		template<int T>
+		RValue<Float4> operator=(const SwizzleFloat4<T> &rhs);
+
+		static llvm::Type *getType();
+
+		union
+		{
+			SwizzleMask1Float4<0x00> x;
+			SwizzleMask1Float4<0x55> y;
+			SwizzleMask1Float4<0xAA> z;
+			SwizzleMask1Float4<0xFF> w;
+			Swizzle2Float4<0x00>     xx;
+			Swizzle2Float4<0x01>     yx;
+			Swizzle2Float4<0x02>     zx;
+			Swizzle2Float4<0x03>     wx;
+			SwizzleMask2Float4<0x54> xy;
+			Swizzle2Float4<0x55>     yy;
+			Swizzle2Float4<0x56>     zy;
+			Swizzle2Float4<0x57>     wy;
+			SwizzleMask2Float4<0xA8> xz;
+			SwizzleMask2Float4<0xA9> yz;
+			Swizzle2Float4<0xAA>     zz;
+			Swizzle2Float4<0xAB>     wz;
+			SwizzleMask2Float4<0xFC> xw;
+			SwizzleMask2Float4<0xFD> yw;
+			SwizzleMask2Float4<0xFE> zw;
+			Swizzle2Float4<0xFF>     ww;
+			SwizzleFloat4<0x00>      xxx;
+			SwizzleFloat4<0x01>      yxx;
+			SwizzleFloat4<0x02>      zxx;
+			SwizzleFloat4<0x03>      wxx;
+			SwizzleFloat4<0x04>      xyx;
+			SwizzleFloat4<0x05>      yyx;
+			SwizzleFloat4<0x06>      zyx;
+			SwizzleFloat4<0x07>      wyx;
+			SwizzleFloat4<0x08>      xzx;
+			SwizzleFloat4<0x09>      yzx;
+			SwizzleFloat4<0x0A>      zzx;
+			SwizzleFloat4<0x0B>      wzx;
+			SwizzleFloat4<0x0C>      xwx;
+			SwizzleFloat4<0x0D>      ywx;
+			SwizzleFloat4<0x0E>      zwx;
+			SwizzleFloat4<0x0F>      wwx;
+			SwizzleFloat4<0x50>      xxy;
+			SwizzleFloat4<0x51>      yxy;
+			SwizzleFloat4<0x52>      zxy;
+			SwizzleFloat4<0x53>      wxy;
+			SwizzleFloat4<0x54>      xyy;
+			SwizzleFloat4<0x55>      yyy;
+			SwizzleFloat4<0x56>      zyy;
+			SwizzleFloat4<0x57>      wyy;
+			SwizzleFloat4<0x58>      xzy;
+			SwizzleFloat4<0x59>      yzy;
+			SwizzleFloat4<0x5A>      zzy;
+			SwizzleFloat4<0x5B>      wzy;
+			SwizzleFloat4<0x5C>      xwy;
+			SwizzleFloat4<0x5D>      ywy;
+			SwizzleFloat4<0x5E>      zwy;
+			SwizzleFloat4<0x5F>      wwy;
+			SwizzleFloat4<0xA0>      xxz;
+			SwizzleFloat4<0xA1>      yxz;
+			SwizzleFloat4<0xA2>      zxz;
+			SwizzleFloat4<0xA3>      wxz;
+			SwizzleMaskFloat4<0xA4>  xyz;
+			SwizzleFloat4<0xA5>      yyz;
+			SwizzleFloat4<0xA6>      zyz;
+			SwizzleFloat4<0xA7>      wyz;
+			SwizzleFloat4<0xA8>      xzz;
+			SwizzleFloat4<0xA9>      yzz;
+			SwizzleFloat4<0xAA>      zzz;
+			SwizzleFloat4<0xAB>      wzz;
+			SwizzleFloat4<0xAC>      xwz;
+			SwizzleFloat4<0xAD>      ywz;
+			SwizzleFloat4<0xAE>      zwz;
+			SwizzleFloat4<0xAF>      wwz;
+			SwizzleFloat4<0xF0>      xxw;
+			SwizzleFloat4<0xF1>      yxw;
+			SwizzleFloat4<0xF2>      zxw;
+			SwizzleFloat4<0xF3>      wxw;
+			SwizzleMaskFloat4<0xF4>  xyw;
+			SwizzleFloat4<0xF5>      yyw;
+			SwizzleFloat4<0xF6>      zyw;
+			SwizzleFloat4<0xF7>      wyw;
+			SwizzleMaskFloat4<0xF8>  xzw;
+			SwizzleMaskFloat4<0xF9>  yzw;
+			SwizzleFloat4<0xFA>      zzw;
+			SwizzleFloat4<0xFB>      wzw;
+			SwizzleFloat4<0xFC>      xww;
+			SwizzleFloat4<0xFD>      yww;
+			SwizzleFloat4<0xFE>      zww;
+			SwizzleFloat4<0xFF>      www;
+			SwizzleFloat4<0x00>      xxxx;
+			SwizzleFloat4<0x01>      yxxx;
+			SwizzleFloat4<0x02>      zxxx;
+			SwizzleFloat4<0x03>      wxxx;
+			SwizzleFloat4<0x04>      xyxx;
+			SwizzleFloat4<0x05>      yyxx;
+			SwizzleFloat4<0x06>      zyxx;
+			SwizzleFloat4<0x07>      wyxx;
+			SwizzleFloat4<0x08>      xzxx;
+			SwizzleFloat4<0x09>      yzxx;
+			SwizzleFloat4<0x0A>      zzxx;
+			SwizzleFloat4<0x0B>      wzxx;
+			SwizzleFloat4<0x0C>      xwxx;
+			SwizzleFloat4<0x0D>      ywxx;
+			SwizzleFloat4<0x0E>      zwxx;
+			SwizzleFloat4<0x0F>      wwxx;
+			SwizzleFloat4<0x10>      xxyx;
+			SwizzleFloat4<0x11>      yxyx;
+			SwizzleFloat4<0x12>      zxyx;
+			SwizzleFloat4<0x13>      wxyx;
+			SwizzleFloat4<0x14>      xyyx;
+			SwizzleFloat4<0x15>      yyyx;
+			SwizzleFloat4<0x16>      zyyx;
+			SwizzleFloat4<0x17>      wyyx;
+			SwizzleFloat4<0x18>      xzyx;
+			SwizzleFloat4<0x19>      yzyx;
+			SwizzleFloat4<0x1A>      zzyx;
+			SwizzleFloat4<0x1B>      wzyx;
+			SwizzleFloat4<0x1C>      xwyx;
+			SwizzleFloat4<0x1D>      ywyx;
+			SwizzleFloat4<0x1E>      zwyx;
+			SwizzleFloat4<0x1F>      wwyx;
+			SwizzleFloat4<0x20>      xxzx;
+			SwizzleFloat4<0x21>      yxzx;
+			SwizzleFloat4<0x22>      zxzx;
+			SwizzleFloat4<0x23>      wxzx;
+			SwizzleFloat4<0x24>      xyzx;
+			SwizzleFloat4<0x25>      yyzx;
+			SwizzleFloat4<0x26>      zyzx;
+			SwizzleFloat4<0x27>      wyzx;
+			SwizzleFloat4<0x28>      xzzx;
+			SwizzleFloat4<0x29>      yzzx;
+			SwizzleFloat4<0x2A>      zzzx;
+			SwizzleFloat4<0x2B>      wzzx;
+			SwizzleFloat4<0x2C>      xwzx;
+			SwizzleFloat4<0x2D>      ywzx;
+			SwizzleFloat4<0x2E>      zwzx;
+			SwizzleFloat4<0x2F>      wwzx;
+			SwizzleFloat4<0x30>      xxwx;
+			SwizzleFloat4<0x31>      yxwx;
+			SwizzleFloat4<0x32>      zxwx;
+			SwizzleFloat4<0x33>      wxwx;
+			SwizzleFloat4<0x34>      xywx;
+			SwizzleFloat4<0x35>      yywx;
+			SwizzleFloat4<0x36>      zywx;
+			SwizzleFloat4<0x37>      wywx;
+			SwizzleFloat4<0x38>      xzwx;
+			SwizzleFloat4<0x39>      yzwx;
+			SwizzleFloat4<0x3A>      zzwx;
+			SwizzleFloat4<0x3B>      wzwx;
+			SwizzleFloat4<0x3C>      xwwx;
+			SwizzleFloat4<0x3D>      ywwx;
+			SwizzleFloat4<0x3E>      zwwx;
+			SwizzleFloat4<0x3F>      wwwx;
+			SwizzleFloat4<0x40>      xxxy;
+			SwizzleFloat4<0x41>      yxxy;
+			SwizzleFloat4<0x42>      zxxy;
+			SwizzleFloat4<0x43>      wxxy;
+			SwizzleFloat4<0x44>      xyxy;
+			SwizzleFloat4<0x45>      yyxy;
+			SwizzleFloat4<0x46>      zyxy;
+			SwizzleFloat4<0x47>      wyxy;
+			SwizzleFloat4<0x48>      xzxy;
+			SwizzleFloat4<0x49>      yzxy;
+			SwizzleFloat4<0x4A>      zzxy;
+			SwizzleFloat4<0x4B>      wzxy;
+			SwizzleFloat4<0x4C>      xwxy;
+			SwizzleFloat4<0x4D>      ywxy;
+			SwizzleFloat4<0x4E>      zwxy;
+			SwizzleFloat4<0x4F>      wwxy;
+			SwizzleFloat4<0x50>      xxyy;
+			SwizzleFloat4<0x51>      yxyy;
+			SwizzleFloat4<0x52>      zxyy;
+			SwizzleFloat4<0x53>      wxyy;
+			SwizzleFloat4<0x54>      xyyy;
+			SwizzleFloat4<0x55>      yyyy;
+			SwizzleFloat4<0x56>      zyyy;
+			SwizzleFloat4<0x57>      wyyy;
+			SwizzleFloat4<0x58>      xzyy;
+			SwizzleFloat4<0x59>      yzyy;
+			SwizzleFloat4<0x5A>      zzyy;
+			SwizzleFloat4<0x5B>      wzyy;
+			SwizzleFloat4<0x5C>      xwyy;
+			SwizzleFloat4<0x5D>      ywyy;
+			SwizzleFloat4<0x5E>      zwyy;
+			SwizzleFloat4<0x5F>      wwyy;
+			SwizzleFloat4<0x60>      xxzy;
+			SwizzleFloat4<0x61>      yxzy;
+			SwizzleFloat4<0x62>      zxzy;
+			SwizzleFloat4<0x63>      wxzy;
+			SwizzleFloat4<0x64>      xyzy;
+			SwizzleFloat4<0x65>      yyzy;
+			SwizzleFloat4<0x66>      zyzy;
+			SwizzleFloat4<0x67>      wyzy;
+			SwizzleFloat4<0x68>      xzzy;
+			SwizzleFloat4<0x69>      yzzy;
+			SwizzleFloat4<0x6A>      zzzy;
+			SwizzleFloat4<0x6B>      wzzy;
+			SwizzleFloat4<0x6C>      xwzy;
+			SwizzleFloat4<0x6D>      ywzy;
+			SwizzleFloat4<0x6E>      zwzy;
+			SwizzleFloat4<0x6F>      wwzy;
+			SwizzleFloat4<0x70>      xxwy;
+			SwizzleFloat4<0x71>      yxwy;
+			SwizzleFloat4<0x72>      zxwy;
+			SwizzleFloat4<0x73>      wxwy;
+			SwizzleFloat4<0x74>      xywy;
+			SwizzleFloat4<0x75>      yywy;
+			SwizzleFloat4<0x76>      zywy;
+			SwizzleFloat4<0x77>      wywy;
+			SwizzleFloat4<0x78>      xzwy;
+			SwizzleFloat4<0x79>      yzwy;
+			SwizzleFloat4<0x7A>      zzwy;
+			SwizzleFloat4<0x7B>      wzwy;
+			SwizzleFloat4<0x7C>      xwwy;
+			SwizzleFloat4<0x7D>      ywwy;
+			SwizzleFloat4<0x7E>      zwwy;
+			SwizzleFloat4<0x7F>      wwwy;
+			SwizzleFloat4<0x80>      xxxz;
+			SwizzleFloat4<0x81>      yxxz;
+			SwizzleFloat4<0x82>      zxxz;
+			SwizzleFloat4<0x83>      wxxz;
+			SwizzleFloat4<0x84>      xyxz;
+			SwizzleFloat4<0x85>      yyxz;
+			SwizzleFloat4<0x86>      zyxz;
+			SwizzleFloat4<0x87>      wyxz;
+			SwizzleFloat4<0x88>      xzxz;
+			SwizzleFloat4<0x89>      yzxz;
+			SwizzleFloat4<0x8A>      zzxz;
+			SwizzleFloat4<0x8B>      wzxz;
+			SwizzleFloat4<0x8C>      xwxz;
+			SwizzleFloat4<0x8D>      ywxz;
+			SwizzleFloat4<0x8E>      zwxz;
+			SwizzleFloat4<0x8F>      wwxz;
+			SwizzleFloat4<0x90>      xxyz;
+			SwizzleFloat4<0x91>      yxyz;
+			SwizzleFloat4<0x92>      zxyz;
+			SwizzleFloat4<0x93>      wxyz;
+			SwizzleFloat4<0x94>      xyyz;
+			SwizzleFloat4<0x95>      yyyz;
+			SwizzleFloat4<0x96>      zyyz;
+			SwizzleFloat4<0x97>      wyyz;
+			SwizzleFloat4<0x98>      xzyz;
+			SwizzleFloat4<0x99>      yzyz;
+			SwizzleFloat4<0x9A>      zzyz;
+			SwizzleFloat4<0x9B>      wzyz;
+			SwizzleFloat4<0x9C>      xwyz;
+			SwizzleFloat4<0x9D>      ywyz;
+			SwizzleFloat4<0x9E>      zwyz;
+			SwizzleFloat4<0x9F>      wwyz;
+			SwizzleFloat4<0xA0>      xxzz;
+			SwizzleFloat4<0xA1>      yxzz;
+			SwizzleFloat4<0xA2>      zxzz;
+			SwizzleFloat4<0xA3>      wxzz;
+			SwizzleFloat4<0xA4>      xyzz;
+			SwizzleFloat4<0xA5>      yyzz;
+			SwizzleFloat4<0xA6>      zyzz;
+			SwizzleFloat4<0xA7>      wyzz;
+			SwizzleFloat4<0xA8>      xzzz;
+			SwizzleFloat4<0xA9>      yzzz;
+			SwizzleFloat4<0xAA>      zzzz;
+			SwizzleFloat4<0xAB>      wzzz;
+			SwizzleFloat4<0xAC>      xwzz;
+			SwizzleFloat4<0xAD>      ywzz;
+			SwizzleFloat4<0xAE>      zwzz;
+			SwizzleFloat4<0xAF>      wwzz;
+			SwizzleFloat4<0xB0>      xxwz;
+			SwizzleFloat4<0xB1>      yxwz;
+			SwizzleFloat4<0xB2>      zxwz;
+			SwizzleFloat4<0xB3>      wxwz;
+			SwizzleFloat4<0xB4>      xywz;
+			SwizzleFloat4<0xB5>      yywz;
+			SwizzleFloat4<0xB6>      zywz;
+			SwizzleFloat4<0xB7>      wywz;
+			SwizzleFloat4<0xB8>      xzwz;
+			SwizzleFloat4<0xB9>      yzwz;
+			SwizzleFloat4<0xBA>      zzwz;
+			SwizzleFloat4<0xBB>      wzwz;
+			SwizzleFloat4<0xBC>      xwwz;
+			SwizzleFloat4<0xBD>      ywwz;
+			SwizzleFloat4<0xBE>      zwwz;
+			SwizzleFloat4<0xBF>      wwwz;
+			SwizzleFloat4<0xC0>      xxxw;
+			SwizzleFloat4<0xC1>      yxxw;
+			SwizzleFloat4<0xC2>      zxxw;
+			SwizzleFloat4<0xC3>      wxxw;
+			SwizzleFloat4<0xC4>      xyxw;
+			SwizzleFloat4<0xC5>      yyxw;
+			SwizzleFloat4<0xC6>      zyxw;
+			SwizzleFloat4<0xC7>      wyxw;
+			SwizzleFloat4<0xC8>      xzxw;
+			SwizzleFloat4<0xC9>      yzxw;
+			SwizzleFloat4<0xCA>      zzxw;
+			SwizzleFloat4<0xCB>      wzxw;
+			SwizzleFloat4<0xCC>      xwxw;
+			SwizzleFloat4<0xCD>      ywxw;
+			SwizzleFloat4<0xCE>      zwxw;
+			SwizzleFloat4<0xCF>      wwxw;
+			SwizzleFloat4<0xD0>      xxyw;
+			SwizzleFloat4<0xD1>      yxyw;
+			SwizzleFloat4<0xD2>      zxyw;
+			SwizzleFloat4<0xD3>      wxyw;
+			SwizzleFloat4<0xD4>      xyyw;
+			SwizzleFloat4<0xD5>      yyyw;
+			SwizzleFloat4<0xD6>      zyyw;
+			SwizzleFloat4<0xD7>      wyyw;
+			SwizzleFloat4<0xD8>      xzyw;
+			SwizzleFloat4<0xD9>      yzyw;
+			SwizzleFloat4<0xDA>      zzyw;
+			SwizzleFloat4<0xDB>      wzyw;
+			SwizzleFloat4<0xDC>      xwyw;
+			SwizzleFloat4<0xDD>      ywyw;
+			SwizzleFloat4<0xDE>      zwyw;
+			SwizzleFloat4<0xDF>      wwyw;
+			SwizzleFloat4<0xE0>      xxzw;
+			SwizzleFloat4<0xE1>      yxzw;
+			SwizzleFloat4<0xE2>      zxzw;
+			SwizzleFloat4<0xE3>      wxzw;
+			SwizzleMaskFloat4<0xE4>  xyzw;
+			SwizzleFloat4<0xE5>      yyzw;
+			SwizzleFloat4<0xE6>      zyzw;
+			SwizzleFloat4<0xE7>      wyzw;
+			SwizzleFloat4<0xE8>      xzzw;
+			SwizzleFloat4<0xE9>      yzzw;
+			SwizzleFloat4<0xEA>      zzzw;
+			SwizzleFloat4<0xEB>      wzzw;
+			SwizzleFloat4<0xEC>      xwzw;
+			SwizzleFloat4<0xED>      ywzw;
+			SwizzleFloat4<0xEE>      zwzw;
+			SwizzleFloat4<0xEF>      wwzw;
+			SwizzleFloat4<0xF0>      xxww;
+			SwizzleFloat4<0xF1>      yxww;
+			SwizzleFloat4<0xF2>      zxww;
+			SwizzleFloat4<0xF3>      wxww;
+			SwizzleFloat4<0xF4>      xyww;
+			SwizzleFloat4<0xF5>      yyww;
+			SwizzleFloat4<0xF6>      zyww;
+			SwizzleFloat4<0xF7>      wyww;
+			SwizzleFloat4<0xF8>      xzww;
+			SwizzleFloat4<0xF9>      yzww;
+			SwizzleFloat4<0xFA>      zzww;
+			SwizzleFloat4<0xFB>      wzww;
+			SwizzleFloat4<0xFC>      xwww;
+			SwizzleFloat4<0xFD>      ywww;
+			SwizzleFloat4<0xFE>      zwww;
+			SwizzleFloat4<0xFF>      wwww;
+		};
+
+	private:
+		void constant(float x, float y, float z, float w);
+	};
+
+	RValue<Float4> operator+(RValue<Float4> lhs, RValue<Float4> rhs);
+	RValue<Float4> operator-(RValue<Float4> lhs, RValue<Float4> rhs);
+	RValue<Float4> operator*(RValue<Float4> lhs, RValue<Float4> rhs);
+	RValue<Float4> operator/(RValue<Float4> lhs, RValue<Float4> rhs);
+	RValue<Float4> operator%(RValue<Float4> lhs, RValue<Float4> rhs);
+	RValue<Float4> operator+=(const Float4 &lhs, RValue<Float4> rhs);
+	RValue<Float4> operator-=(const Float4 &lhs, RValue<Float4> rhs);
+	RValue<Float4> operator*=(const Float4 &lhs, RValue<Float4> rhs);
+	RValue<Float4> operator/=(const Float4 &lhs, RValue<Float4> rhs);
+	RValue<Float4> operator%=(const Float4 &lhs, RValue<Float4> rhs);
+	RValue<Float4> operator+(RValue<Float4> val);
+	RValue<Float4> operator-(RValue<Float4> val);
+
+	RValue<Float4> Abs(RValue<Float4> x);
+	RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y);
+	RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y);
+	RValue<Float4> Rcp_pp(RValue<Float4> val, bool exactAtPow2 = false);
+	RValue<Float4> RcpSqrt_pp(RValue<Float4> val);
+	RValue<Float4> Sqrt(RValue<Float4> x);
+	RValue<Float4> Insert(const Float4 &val, RValue<Float> element, int i);
+	RValue<Float> Extract(RValue<Float4> x, int i);
+	RValue<Float4> Swizzle(RValue<Float4> x, unsigned char select);
+	RValue<Float4> ShuffleLowHigh(RValue<Float4> x, RValue<Float4> y, unsigned char imm);
+	RValue<Float4> UnpackLow(RValue<Float4> x, RValue<Float4> y);
+	RValue<Float4> UnpackHigh(RValue<Float4> x, RValue<Float4> y);
+	RValue<Float4> Mask(Float4 &lhs, RValue<Float4> rhs, unsigned char select);
+	RValue<Int> SignMask(RValue<Float4> x);
+	RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y);
+	RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y);
+	RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y);
+	RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);
+	RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);
+	RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);
+	RValue<Float4> Round(RValue<Float4> x);
+	RValue<Float4> Trunc(RValue<Float4> x);
+	RValue<Float4> Frac(RValue<Float4> x);
+	RValue<Float4> Floor(RValue<Float4> x);
+	RValue<Float4> Ceil(RValue<Float4> x);
+
+	template<class T>
+	class Pointer : public Variable<Pointer<T>>
+	{
+	public:
+		template<class S>
+		Pointer(RValue<Pointer<S>> pointerS, int alignment = 1) : alignment(alignment)
+		{
+			llvm::Value *pointerT = Nucleus::createBitCast(pointerS.value, Nucleus::getPointerType(T::getType()));
+			LValue::storeValue(pointerT);
+		}
+
+		template<class S>
+		Pointer(const Pointer<S> &pointer, int alignment = 1) : alignment(alignment)
+		{
+			llvm::Value *pointerS = pointer.loadValue(alignment);
+			llvm::Value *pointerT = Nucleus::createBitCast(pointerS, Nucleus::getPointerType(T::getType()));
+			LValue::storeValue(pointerT);
+		}
+
+		Pointer(Argument<Pointer<T>> argument);
+		explicit Pointer(const void *external);
+
+		Pointer();
+		Pointer(RValue<Pointer<T>> rhs);
+		Pointer(const Pointer<T> &rhs);
+		Pointer(const Reference<Pointer<T>> &rhs);
+
+		RValue<Pointer<T>> operator=(RValue<Pointer<T>> rhs) const;
+		RValue<Pointer<T>> operator=(const Pointer<T> &rhs) const;
+		RValue<Pointer<T>> operator=(const Reference<Pointer<T>> &rhs) const;
+
+		Reference<T> operator*();
+
+		static llvm::Type *getType();
+
+	private:
+		const int alignment;
+	};
+
+	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset);
+	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
+	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
+	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset);
+	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<Int> offset);
+	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, RValue<UInt> offset);
+
+	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, int offset);
+	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<Int> offset);
+	RValue<Pointer<Byte>> operator-(RValue<Pointer<Byte>> lhs, RValue<UInt> offset);
+	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, int offset);
+	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<Int> offset);
+	RValue<Pointer<Byte>> operator-=(const Pointer<Byte> &lhs, RValue<UInt> offset);
+
+	template<class T, int S = 1>
+	class Array : public Variable<T>
+	{
+	public:
+		Array(int size = S);
+
+		Reference<T> operator[](int index);
+		Reference<T> operator[](RValue<Int> index);
+		Reference<T> operator[](RValue<UInt> index);
+	};
+
+//	RValue<Array<T>> operator++(const Array<T> &val, int);   // Post-increment
+//	const Array<T> &operator++(const Array<T> &val);   // Pre-increment
+//	RValue<Array<T>> operator--(const Array<T> &val, int);   // Post-decrement
+//	const Array<T> &operator--(const Array<T> &val);   // Pre-decrement
+
+	llvm::BasicBlock *beginLoop();
+	bool branch(RValue<Bool> cmp, llvm::BasicBlock *bodyBB, llvm::BasicBlock *endBB);
+	bool elseBlock(llvm::BasicBlock *falseBB);
+
+	void Return();
+	void Return(bool ret);
+	void Return(const Int &ret);
+
+	template<class T>
+	void Return(const Pointer<T> &ret);
+
+	template<class T>
+	void Return(RValue<Pointer<T>> ret);
+
+	template<unsigned int index, typename... Arguments>
+	struct ArgI;
+
+	template<typename Arg0, typename... Arguments>
+	struct ArgI<0, Arg0, Arguments...>
+	{
+		typedef Arg0 Type;
+	};
+
+	template<unsigned int index, typename Arg0, typename... Arguments>
+	struct ArgI<index, Arg0, Arguments...>
+	{
+		typedef typename ArgI<index - 1, Arguments...>::Type Type;
+	};
+
+	// Generic template, leave undefined!
+	template<typename FunctionType>
+	class Function;
+
+	// Specialized for function types
+	template<typename Return, typename... Arguments>
+	class Function<Return(Arguments...)>
+	{
+	public:
+		Function();
+
+		virtual ~Function();
+
+		template<int index>
+		Argument<typename ArgI<index, Arguments...>::Type> Arg() const
+		{
+			llvm::Value *arg = Nucleus::getArgument(function, index);
+			return Argument<typename ArgI<index, Arguments...>::Type>(arg);
+		}
+
+		Routine *operator()(const wchar_t *name, ...);
+
+	private:
+		Nucleus *core;
+		llvm::Function *function;
+		std::vector<llvm::Type*> arguments;
+	};
+
+	template<int index, typename Return, typename... Arguments>
+	Argument<typename ArgI<index, Arguments...>::Type> Arg(Function<Return(Arguments...)> &function)
+	{
+		return Argument<typename ArgI<index, Arguments...>::Type>(function.arg(index));
+	}
+
+	RValue<Long> Ticks();
+}
+
+namespace sw
+{
+	template<class T>
+	Variable<T>::Variable(int arraySize) : LValue(T::getType(), arraySize)
+	{
+	}
+
+	template<class T>
+	RValue<Pointer<T>> Variable<T>::operator&()
+	{
+		return RValue<Pointer<T>>(LValue::address);
+	}
+
+	template<class T>
+	Reference<T>::Reference(llvm::Value *pointer, int alignment) : alignment(alignment)
+	{
+		address = pointer;
+	}
+
+	template<class T>
+	RValue<T> Reference<T>::operator=(RValue<T> rhs) const
+	{
+		Nucleus::createStore(rhs.value, address, false, alignment);
+
+		return rhs;
+	}
+
+	template<class T>
+	RValue<T> Reference<T>::operator=(const Reference<T> &ref) const
+	{
+		llvm::Value *tmp = Nucleus::createLoad(ref.address, false, ref.alignment);
+		Nucleus::createStore(tmp, address, false, alignment);
+
+		return RValue<T>(tmp);
+	}
+
+	template<class T>
+	RValue<T> Reference<T>::operator+=(RValue<T> rhs) const
+	{
+		return *this = *this + rhs;
+	}
+
+	template<class T>
+	llvm::Value *Reference<T>::loadValue() const
+	{
+		return Nucleus::createLoad(address, false, alignment);
+	}
+
+	template<class T>
+	int Reference<T>::getAlignment() const
+	{
+		return alignment;
+	}
+
+	template<class T>
+	RValue<T>::RValue(llvm::Value *rvalue)
+	{
+		value = rvalue;
+	}
+
+	template<class T>
+	RValue<T>::RValue(const T &lvalue)
+	{
+		value = lvalue.loadValue();
+	}
+
+	template<class T>
+	RValue<T>::RValue(typename IntLiteral<T>::type i)
+	{
+		value = (llvm::Value*)Nucleus::createConstantInt(i);
+	}
+
+	template<class T>
+	RValue<T>::RValue(typename FloatLiteral<T>::type f)
+	{
+		value = (llvm::Value*)Nucleus::createConstantFloat(f);
+	}
+
+	template<class T>
+	RValue<T>::RValue(const Reference<T> &ref)
+	{
+		value = ref.loadValue();
+	}
+
+	template<int T>
+	Swizzle2Float4<T>::operator RValue<Float4>() const
+	{
+		llvm::Value *vector = parent->loadValue();
+
+		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
+	}
+
+	template<int T>
+	SwizzleFloat4<T>::operator RValue<Float4>() const
+	{
+		llvm::Value *vector = parent->loadValue();
+
+		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
+	}
+
+	template<int T>
+	SwizzleMaskFloat4<T>::operator RValue<Float4>() const
+	{
+		llvm::Value *vector = parent->loadValue();
+
+		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
+	}
+
+	template<int T>
+	RValue<Float4> SwizzleMaskFloat4<T>::operator=(RValue<Float4> rhs) const
+	{
+		return Mask(*parent, rhs, T);
+	}
+
+	template<int T>
+	RValue<Float4> SwizzleMaskFloat4<T>::operator=(RValue<Float> rhs) const
+	{
+		return Mask(*parent, Float4(rhs), T);
+	}
+
+	template<int T>
+	SwizzleMask1Float4<T>::operator RValue<Float>() const   // FIXME: Call a non-template function
+	{
+		return Extract(*parent, T & 0x3);
+	}
+
+	template<int T>
+	SwizzleMask1Float4<T>::operator RValue<Float4>() const
+	{
+		llvm::Value *vector = parent->loadValue();
+
+		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
+	}
+
+	template<int T>
+	RValue<Float4> SwizzleMask1Float4<T>::operator=(float x) const
+	{
+		return Insert(*parent, Float(x), T & 0x3);
+	}
+
+	template<int T>
+	RValue<Float4> SwizzleMask1Float4<T>::operator=(RValue<Float4> rhs) const
+	{
+		return Mask(*parent, Float4(rhs), T);
+	}
+
+	template<int T>
+	RValue<Float4> SwizzleMask1Float4<T>::operator=(RValue<Float> rhs) const   // FIXME: Call a non-template function
+	{
+		return Insert(*parent, rhs, T & 0x3);
+	}
+
+	template<int T>
+	SwizzleMask2Float4<T>::operator RValue<Float4>() const
+	{
+		llvm::Value *vector = parent->loadValue();
+
+		return RValue<Float4>(Nucleus::createSwizzle(vector, T));
+	}
+
+	template<int T>
+	RValue<Float4> SwizzleMask2Float4<T>::operator=(RValue<Float4> rhs) const
+	{
+		return Mask(*parent, Float4(rhs), T);
+	}
+
+	template<int T>
+	Float::Float(const SwizzleMask1Float4<T> &rhs)
+	{
+		*this = rhs.operator RValue<Float>();
+	}
+
+	template<int T>
+	RValue<Float> Float::operator=(const SwizzleMask1Float4<T> &rhs) const
+	{
+		return *this = rhs.operator RValue<Float>();
+	}
+
+	template<int T>
+	Float4::Float4(const SwizzleMask1Float4<T> &rhs)
+	{
+		xyzw.parent = this;
+
+		*this = rhs.operator RValue<Float4>();
+	}
+
+	template<int T>
+	Float4::Float4(const SwizzleFloat4<T> &rhs)
+	{
+		xyzw.parent = this;
+
+		*this = rhs.operator RValue<Float4>();
+	}
+
+	template<int X, int Y>
+	Float4::Float4(const Swizzle2Float4<X> &x, const Swizzle2Float4<Y> &y)
+	{
+		xyzw.parent = this;
+
+		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
+	}
+
+	template<int X, int Y>
+	Float4::Float4(const SwizzleMask2Float4<X> &x, const Swizzle2Float4<Y> &y)
+	{
+		xyzw.parent = this;
+
+		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
+	}
+
+	template<int X, int Y>
+	Float4::Float4(const Swizzle2Float4<X> &x, const SwizzleMask2Float4<Y> &y)
+	{
+		xyzw.parent = this;
+
+		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
+	}
+
+	template<int X, int Y>
+	Float4::Float4(const SwizzleMask2Float4<X> &x, const SwizzleMask2Float4<Y> &y)
+	{
+		xyzw.parent = this;
+
+		*this = ShuffleLowHigh(*x.parent, *y.parent, (X & 0xF) | (Y & 0xF) << 4);
+	}
+
+	template<int T>
+	RValue<Float4> Float4::operator=(const SwizzleMask1Float4<T> &rhs)
+	{
+		return *this = rhs.operator RValue<Float4>();
+	}
+
+	template<int T>
+	RValue<Float4> Float4::operator=(const SwizzleFloat4<T> &rhs)
+	{
+		return *this = rhs.operator RValue<Float4>();
+	}
+
+	template<class T>
+	Pointer<T>::Pointer(Argument<Pointer<T>> argument) : alignment(1)
+	{
+		LValue::storeValue(argument.value);
+	}
+
+	template<class T>
+	Pointer<T>::Pointer(const void *external) : alignment((intptr_t)external & 0x0000000F ? 1 : 16)
+	{
+		const llvm::GlobalValue *globalPointer = Nucleus::getGlobalValueAtAddress(const_cast<void*>(external));   // FIXME: Const
+
+		if(!globalPointer)
+		{
+			globalPointer = Nucleus::createGlobalValue(T::getType(), false, alignment);
+
+			Nucleus::addGlobalMapping(globalPointer, const_cast<void*>(external));   // FIXME: Const
+		}
+
+		LValue::storeValue((llvm::Value*)globalPointer);   // FIXME: Const
+	}
+
+	template<class T>
+	Pointer<T>::Pointer() : alignment(1)
+	{
+		LValue::storeValue(Nucleus::createNullPointer(T::getType()));
+	}
+
+	template<class T>
+	Pointer<T>::Pointer(RValue<Pointer<T>> rhs) : alignment(1)
+	{
+		LValue::storeValue(rhs.value);
+	}
+
+	template<class T>
+	Pointer<T>::Pointer(const Pointer<T> &rhs) : alignment(rhs.alignment)
+	{
+		llvm::Value *value = rhs.loadValue();
+		LValue::storeValue(value);
+	}
+
+	template<class T>
+	Pointer<T>::Pointer(const Reference<Pointer<T>> &rhs) : alignment(rhs.getAlignment())
+	{
+		llvm::Value *value = rhs.loadValue();
+		LValue::storeValue(value);
+	}
+
+	template<class T>
+	RValue<Pointer<T>> Pointer<T>::operator=(RValue<Pointer<T>> rhs) const
+	{
+		LValue::storeValue(rhs.value);
+
+		return rhs;
+	}
+
+	template<class T>
+	RValue<Pointer<T>> Pointer<T>::operator=(const Pointer<T> &rhs) const
+	{
+		llvm::Value *value = rhs.loadValue();
+		LValue::storeValue(value);
+
+		return RValue<Pointer<T>>(value);
+	}
+
+	template<class T>
+	RValue<Pointer<T>> Pointer<T>::operator=(const Reference<Pointer<T>> &rhs) const
+	{
+		llvm::Value *value = rhs.loadValue();
+		LValue::storeValue(value);
+
+		return RValue<Pointer<T>>(value);
+	}
+
+	template<class T>
+	Reference<T> Pointer<T>::operator*()
+	{
+		return Reference<T>(LValue::loadValue(), alignment);
+	}
+
+	template<class T>
+	llvm::Type *Pointer<T>::getType()
+	{
+		return Nucleus::getPointerType(T::getType());
+	}
+
+	template<class T, int S>
+	Array<T, S>::Array(int size) : Variable<T>(size)
+	{
+	}
+
+	template<class T, int S>
+	Reference<T> Array<T, S>::operator[](int index)
+	{
+		llvm::Value *element = LValue::getAddress((llvm::Value*)Nucleus::createConstantInt(index));
+
+		return Reference<T>(element);
+	}
+
+	template<class T, int S>
+	Reference<T> Array<T, S>::operator[](RValue<Int> index)
+	{
+		llvm::Value *element = LValue::getAddress(index.value);
+
+		return Reference<T>(element);
+	}
+
+	template<class T, int S>
+	Reference<T> Array<T, S>::operator[](RValue<UInt> index)
+	{
+		llvm::Value *element = LValue::getAddress(index.value);
+
+		return Reference<T>(element);
+	}
+
+//	template<class T>
+//	RValue<Array<T>> operator++(const Array<T> &val, int)
+//	{
+//		// FIXME: Requires storing the address of the array
+//	}
+
+//	template<class T>
+//	const Array<T> &operator++(const Array<T> &val)
+//	{
+//		// FIXME: Requires storing the address of the array
+//	}
+
+//	template<class T>
+//	RValue<Array<T>> operator--(const Array<T> &val, int)
+//	{
+//		// FIXME: Requires storing the address of the array
+//	}
+
+//	template<class T>
+//	const Array<T> &operator--(const Array<T> &val)
+//	{
+//		// FIXME: Requires storing the address of the array
+//	}
+
+	template<class T>
+	RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, RValue<T> ifFalse)
+	{
+		return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, ifFalse.value));
+	}
+
+	template<class T>
+	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, RValue<T> ifFalse)
+	{
+		llvm::Value *trueValue = ifTrue.loadValue();
+
+		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, ifFalse.value));
+	}
+
+	template<class T>
+	RValue<T> IfThenElse(RValue<Bool> condition, RValue<T> ifTrue, const T &ifFalse)
+	{
+		llvm::Value *falseValue = ifFalse.loadValue();
+
+		return RValue<T>(Nucleus::createSelect(condition.value, ifTrue.value, falseValue));
+	}
+
+	template<class T>
+	RValue<T> IfThenElse(RValue<Bool> condition, const T &ifTrue, const T &ifFalse)
+	{
+		llvm::Value *trueValue = ifTrue.loadValue();
+		llvm::Value *falseValue = ifFalse.loadValue();
+
+		return RValue<T>(Nucleus::createSelect(condition.value, trueValue, falseValue));
+	}
+
+	template<class T>
+	void Return(const Pointer<T> &ret)
+	{
+		Nucleus::createRet(Nucleus::createLoad(ret.address));
+		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
+	}
+
+	template<class T>
+	void Return(RValue<Pointer<T>> ret)
+	{
+		Nucleus::createRet(ret.value);
+		Nucleus::setInsertBlock(Nucleus::createBasicBlock());
+	}
+
+	template<typename Return, typename... Arguments>
+	Function<Return(Arguments...)>::Function()
+	{
+		core = new Nucleus();
+
+		llvm::Type *types[] = {Arguments::getType()...};
+		for(llvm::Type *type : types)
+		{
+			arguments.push_back(type);
+		}
+
+		function = Nucleus::createFunction(Return::getType(), arguments);
+		Nucleus::setFunction(function);
+	}
+
+	template<typename Return, typename... Arguments>
+	Function<Return(Arguments...)>::~Function()
+	{
+		delete core;
+	}
+
+	template<typename Return, typename... Arguments>
+	Routine *Function<Return(Arguments...)>::operator()(const wchar_t *name, ...)
+	{
+		wchar_t fullName[1024 + 1];
+
+		va_list vararg;
+		va_start(vararg, name);
+		vswprintf(fullName, 1024, name, vararg);
+		va_end(vararg);
+
+		return core->acquireRoutine(fullName, true);
+	}
+
+	template<class T, class S>
+	RValue<T> ReinterpretCast(RValue<S> val)
+	{
+		return RValue<T>(Nucleus::createBitCast(val.value, T::getType()));
+	}
+
+	template<class T>
+	RValue<T> ReinterpretCast(const LValue &var)
+	{
+		llvm::Value *val = var.loadValue();
+
+		return RValue<T>(Nucleus::createBitCast(val, T::getType()));
+	}
+
+	template<class T, class S>
+	RValue<T> ReinterpretCast(const Reference<S> &var)
+	{
+		return ReinterpretCast<T>(RValue<S>(var));
+	}
+
+	template<class T, class S>
+	RValue<T> As(RValue<S> val)
+	{
+		return ReinterpretCast<T>(val);
+	}
+
+	template<class T>
+	RValue<T> As(const LValue &var)
+	{
+		return ReinterpretCast<T>(var);
+	}
+
+	template<class T, class S>
+	RValue<T> As(const Reference<S> &val)
+	{
+		return ReinterpretCast<T>(val);
+	}
+}
+
+#endif   // sw_Nucleus_hpp
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 0e7538b..261d7ec 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -1,54 +1,57 @@
-// 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 "Nucleus.hpp"

-#include "Routine.hpp"

-

-namespace sw

-{

-	#define For(init, cond, inc)                     \

-	init;                                            \

-	for(llvm::BasicBlock *loopBB__ = beginLoop(),    \

-		*bodyBB__ = Nucleus::createBasicBlock(),        \

-		*endBB__ = Nucleus::createBasicBlock(),         \

-		*onceBB__ = endBB__;                         \

-		onceBB__ && branch(cond, bodyBB__, endBB__); \

-		inc, onceBB__ = 0, Nucleus::createBr(loopBB__), Nucleus::setInsertBlock(endBB__))

-

-	#define While(cond) For(((void*)0), cond, ((void*)0))

-

-	#define Do \

-	{ \

-		llvm::BasicBlock *body = Nucleus::createBasicBlock(); \

-		Nucleus::createBr(body); \

-		Nucleus::setInsertBlock(body);

-

-	#define Until(cond) \

-		llvm::BasicBlock *end = Nucleus::createBasicBlock(); \

-		Nucleus::createCondBr((cond).value, end, body); \

-		Nucleus::setInsertBlock(end); \

-	}

-

-	#define If(cond)                                                              \

-	for(llvm::BasicBlock *trueBB__ = Nucleus::createBasicBlock(), \

-		*falseBB__ = Nucleus::createBasicBlock(),                 \

-		*endBB__ = Nucleus::createBasicBlock(),                   \

-		*onceBB__ = endBB__;                                   \

-		onceBB__ && branch(cond, trueBB__, falseBB__);         \

-		onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(falseBB__), Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__))

-

-	#define Else                                            \

-	for(llvm::BasicBlock *endBB__ = Nucleus::getInsertBlock(), \

-		*falseBB__ = Nucleus::getPredecessor(endBB__),         \

-		*onceBB__ = endBB__;                                \

-		onceBB__ && elseBlock(falseBB__);                   \

-		onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__))

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Nucleus.hpp"
+#include "Routine.hpp"
+
+namespace sw
+{
+	#define For(init, cond, inc)                     \
+	init;                                            \
+	for(llvm::BasicBlock *loopBB__ = beginLoop(),    \
+		*bodyBB__ = Nucleus::createBasicBlock(),        \
+		*endBB__ = Nucleus::createBasicBlock(),         \
+		*onceBB__ = endBB__;                         \
+		onceBB__ && branch(cond, bodyBB__, endBB__); \
+		inc, onceBB__ = 0, Nucleus::createBr(loopBB__), Nucleus::setInsertBlock(endBB__))
+
+	#define While(cond) For(((void*)0), cond, ((void*)0))
+
+	#define Do \
+	{ \
+		llvm::BasicBlock *body = Nucleus::createBasicBlock(); \
+		Nucleus::createBr(body); \
+		Nucleus::setInsertBlock(body);
+
+	#define Until(cond) \
+		llvm::BasicBlock *end = Nucleus::createBasicBlock(); \
+		Nucleus::createCondBr((cond).value, end, body); \
+		Nucleus::setInsertBlock(end); \
+	}
+
+	#define If(cond)                                                              \
+	for(llvm::BasicBlock *trueBB__ = Nucleus::createBasicBlock(), \
+		*falseBB__ = Nucleus::createBasicBlock(),                 \
+		*endBB__ = Nucleus::createBasicBlock(),                   \
+		*onceBB__ = endBB__;                                   \
+		onceBB__ && branch(cond, trueBB__, falseBB__);         \
+		onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(falseBB__), Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__))
+
+	#define Else                                            \
+	for(llvm::BasicBlock *endBB__ = Nucleus::getInsertBlock(), \
+		*falseBB__ = Nucleus::getPredecessor(endBB__),         \
+		*onceBB__ = endBB__;                                \
+		onceBB__ && elseBlock(falseBB__);                   \
+		onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__))
 }
\ No newline at end of file
diff --git a/src/Reactor/Routine.cpp b/src/Reactor/Routine.cpp
index 1671abe..50c7cb3 100644
--- a/src/Reactor/Routine.cpp
+++ b/src/Reactor/Routine.cpp
@@ -1,3 +1,17 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 #include "Routine.hpp"
 
 #include "../Common/Memory.hpp"
diff --git a/src/Reactor/Routine.hpp b/src/Reactor/Routine.hpp
index 6cdc6bc..6252a7a 100644
--- a/src/Reactor/Routine.hpp
+++ b/src/Reactor/Routine.hpp
@@ -1,41 +1,55 @@
-#ifndef sw_Routine_hpp

-#define sw_Routine_hpp

-

-namespace sw

-{

-	class RoutineManager;

-

-	class Routine

-	{

-		friend class RoutineManager;

-

-	public:

-		Routine(int bufferSize);

-		Routine(void *memory, int bufferSize, int offset);

-

-		~Routine();

-

-		void setFunctionSize(int functionSize);

-

-		const void *getBuffer();

-		const void *getEntry();

-		int getBufferSize();

-		int getFunctionSize();   // Includes constants before the entry point

-		int getCodeSize();       // Executable code only

-		bool isDynamic();

-

-		void bind();

-		void unbind();

-

-	private:

-		void *buffer;

-		const void *entry;

-		int bufferSize;

-		int functionSize;

-

-		volatile int bindCount;

-		const bool dynamic;   // Generated or precompiled

-	};

-}

-

-#endif   // sw_Routine_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Routine_hpp
+#define sw_Routine_hpp
+
+namespace sw
+{
+	class RoutineManager;
+
+	class Routine
+	{
+		friend class RoutineManager;
+
+	public:
+		Routine(int bufferSize);
+		Routine(void *memory, int bufferSize, int offset);
+
+		~Routine();
+
+		void setFunctionSize(int functionSize);
+
+		const void *getBuffer();
+		const void *getEntry();
+		int getBufferSize();
+		int getFunctionSize();   // Includes constants before the entry point
+		int getCodeSize();       // Executable code only
+		bool isDynamic();
+
+		void bind();
+		void unbind();
+
+	private:
+		void *buffer;
+		const void *entry;
+		int bufferSize;
+		int functionSize;
+
+		volatile int bindCount;
+		const bool dynamic;   // Generated or precompiled
+	};
+}
+
+#endif   // sw_Routine_hpp
diff --git a/src/Reactor/RoutineManager.cpp b/src/Reactor/RoutineManager.cpp
index 7240b4d..c3636e0 100644
--- a/src/Reactor/RoutineManager.cpp
+++ b/src/Reactor/RoutineManager.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "RoutineManager.hpp"
 
@@ -113,10 +116,10 @@
 
 	void RoutineManager::deallocateExceptionTable(void *ET)
 	{
-        if(ET)
-        {
-            UNIMPLEMENTED();
-        }
+		if(ET)
+		{
+			UNIMPLEMENTED();
+		}
 	}
 
 	void RoutineManager::setMemoryWritable()
diff --git a/src/Reactor/RoutineManager.hpp b/src/Reactor/RoutineManager.hpp
index 3c813b4..fb85fe4 100644
--- a/src/Reactor/RoutineManager.hpp
+++ b/src/Reactor/RoutineManager.hpp
@@ -1,54 +1,57 @@
-// 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.

-//

-

-#ifndef sw_RoutineManager_hpp

-#define sw_RoutineManager_hpp

-

-#include "llvm/GlobalValue.h"

-#include "llvm/ExecutionEngine/JITMemoryManager.h"

-

-namespace sw

-{

-	class Routine;

-

-	class RoutineManager : public llvm::JITMemoryManager

-	{

-	public:

-		RoutineManager();

-

-		virtual ~RoutineManager();

-

-		virtual void AllocateGOT();

-

-		virtual uint8_t *allocateStub(const llvm::GlobalValue *function, unsigned stubSize, unsigned alignment);

-		virtual uint8_t *startFunctionBody(const llvm::Function *function, uintptr_t &actualSize);

-		virtual void endFunctionBody(const llvm::Function *function, uint8_t *functionStart, uint8_t *functionEnd);

-		virtual uint8_t *startExceptionTable(const llvm::Function *function, uintptr_t &ActualSize);

-		virtual void endExceptionTable(const llvm::Function *function, uint8_t *tableStart, uint8_t *tableEnd, uint8_t *frameRegister);

-		virtual uint8_t *getGOTBase() const;

-		virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);

-		virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned int Alignment);

-		virtual void deallocateFunctionBody(void *Body);

-		virtual void deallocateExceptionTable(void *ET);

-		virtual void setMemoryWritable();

-		virtual void setMemoryExecutable();

-		virtual void setPoisonMemory(bool poison);

-

-		Routine *acquireRoutine(void *entry);

-

-	private:

-		Routine *routine;

-

-		static volatile int averageInstructionSize;

-	};

-}

-

-#endif   // sw_RoutineManager_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_RoutineManager_hpp
+#define sw_RoutineManager_hpp
+
+#include "llvm/GlobalValue.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+
+namespace sw
+{
+	class Routine;
+
+	class RoutineManager : public llvm::JITMemoryManager
+	{
+	public:
+		RoutineManager();
+
+		virtual ~RoutineManager();
+
+		virtual void AllocateGOT();
+
+		virtual uint8_t *allocateStub(const llvm::GlobalValue *function, unsigned stubSize, unsigned alignment);
+		virtual uint8_t *startFunctionBody(const llvm::Function *function, uintptr_t &actualSize);
+		virtual void endFunctionBody(const llvm::Function *function, uint8_t *functionStart, uint8_t *functionEnd);
+		virtual uint8_t *startExceptionTable(const llvm::Function *function, uintptr_t &ActualSize);
+		virtual void endExceptionTable(const llvm::Function *function, uint8_t *tableStart, uint8_t *tableEnd, uint8_t *frameRegister);
+		virtual uint8_t *getGOTBase() const;
+		virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
+		virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned int Alignment);
+		virtual void deallocateFunctionBody(void *Body);
+		virtual void deallocateExceptionTable(void *ET);
+		virtual void setMemoryWritable();
+		virtual void setMemoryExecutable();
+		virtual void setPoisonMemory(bool poison);
+
+		Routine *acquireRoutine(void *entry);
+
+	private:
+		Routine *routine;
+
+		static volatile int averageInstructionSize;
+	};
+}
+
+#endif   // sw_RoutineManager_hpp
diff --git a/src/Reactor/x86.hpp b/src/Reactor/x86.hpp
index ad7cf59..e9d7edf 100644
--- a/src/Reactor/x86.hpp
+++ b/src/Reactor/x86.hpp
@@ -1,152 +1,155 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 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 "Nucleus.hpp"

-

-namespace sw

-{

-	namespace x86

-	{

-		RValue<Int> cvtss2si(RValue<Float> val);

-		RValue<Int2> cvtps2pi(RValue<Float4> val);

-		RValue<Int2> cvttps2pi(RValue<Float4> val);

-		RValue<Int4> cvtps2dq(RValue<Float4> val);

-		

-		RValue<Float> rcpss(RValue<Float> val);

-		RValue<Float> sqrtss(RValue<Float> val);

-		RValue<Float> rsqrtss(RValue<Float> val);

-

-		RValue<Float4> rcpps(RValue<Float4> val);

-		RValue<Float4> sqrtps(RValue<Float4> val);

-		RValue<Float4> rsqrtps(RValue<Float4> val);

-		RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y);

-

-		RValue<Float> roundss(RValue<Float> val, unsigned char imm);

-		RValue<Float> floorss(RValue<Float> val);

-		RValue<Float> ceilss(RValue<Float> val);

-

-		RValue<Float4> roundps(RValue<Float4> val, unsigned char imm);

-		RValue<Float4> floorps(RValue<Float4> val);

-		RValue<Float4> ceilps(RValue<Float4> val);

-

-		RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm);

-		RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y);

-		RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y);

-

-		RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm);

-		RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y);

-		RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y);

-		RValue<Float> cmpless(RValue<Float> x, RValue<Float> y);

-		RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y);

-		RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y);

-		RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y);

-		RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y);

-		RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y);

-

-		RValue<Int4> pabsd(RValue<Int4> x);

-

-		RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y);

-		RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y);

-		RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y);

-		RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y);

-		RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y);

-		RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y);

-		RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y);

-

-		RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> por(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> pshufw(RValue<Short4> x, unsigned char y);

-		RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y);

-		RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i);

-		RValue<Int> pextrw(RValue<Short4> x, unsigned int i);

-		RValue<Long1> punpckldq(RValue<Int2> x, RValue<Int2> y);

-		RValue<Long1> punpckhdq(RValue<Int2> x, RValue<Int2> y);

-		RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y);

-		RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y);

-		RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y);

-		RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y);

-		RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y);

-		RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y);

-

-		RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y);

-

-		RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y);

-

-		RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y);

-		RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y);

-		RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y);

-		RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y);

-

-		RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y);

-		RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y);

-		RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y);

-		RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y);

-

-		RValue<UShort8> packusdw(RValue<UInt4> x, RValue<UInt4> y);

-

-		RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y);

-		RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y);

-		RValue<Short4> psraw(RValue<Short4> x, unsigned char y);

-		RValue<Short8> psraw(RValue<Short8> x, unsigned char y);

-		RValue<Short4> psllw(RValue<Short4> x, unsigned char y);

-		RValue<Short8> psllw(RValue<Short8> x, unsigned char y);

-		RValue<Int2> pslld(RValue<Int2> x, unsigned char y);

-		RValue<Int4> pslld(RValue<Int4> x, unsigned char y);

-		RValue<Int2> psrad(RValue<Int2> x, unsigned char y);

-		RValue<Int4> psrad(RValue<Int4> x, unsigned char y);

-		RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y);

-		RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y);

-

-		RValue<UShort4> psrlw(RValue<UShort4> x, RValue<Long1> y);

-		RValue<Short4> psraw(RValue<Short4> x, RValue<Long1> y);

-		RValue<Short4> psllw(RValue<Short4> x, RValue<Long1> y);

-		RValue<Int2> pslld(RValue<Int2> x, RValue<Long1> y);

-		RValue<UInt2> psrld(RValue<UInt2> x, RValue<Long1> y);

-		RValue<Int2> psrad(RValue<Int2> x, RValue<Long1> y);

-

-		RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y);

-		RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y);

-		RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y);

-		RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y);

-

-		RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y);

-		RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y);

-		RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y);

-

-		RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y);

-		RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y);

-		RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y);

-

-		RValue<Int> movmskps(RValue<Float4> x);

-		RValue<Int> pmovmskb(RValue<Byte8> x);

-

-		RValue<Int4> pmovzxbd(RValue<Int4> x);

-		RValue<Int4> pmovsxbd(RValue<Int4> x);

-		RValue<Int4> pmovzxwd(RValue<Int4> x);

-		RValue<Int4> pmovsxwd(RValue<Int4> x);

-

-		void emms();

-	}

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Nucleus.hpp"
+
+namespace sw
+{
+	namespace x86
+	{
+		RValue<Int> cvtss2si(RValue<Float> val);
+		RValue<Int2> cvtps2pi(RValue<Float4> val);
+		RValue<Int2> cvttps2pi(RValue<Float4> val);
+		RValue<Int4> cvtps2dq(RValue<Float4> val);
+
+		RValue<Float> rcpss(RValue<Float> val);
+		RValue<Float> sqrtss(RValue<Float> val);
+		RValue<Float> rsqrtss(RValue<Float> val);
+
+		RValue<Float4> rcpps(RValue<Float4> val);
+		RValue<Float4> sqrtps(RValue<Float4> val);
+		RValue<Float4> rsqrtps(RValue<Float4> val);
+		RValue<Float4> maxps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> minps(RValue<Float4> x, RValue<Float4> y);
+
+		RValue<Float> roundss(RValue<Float> val, unsigned char imm);
+		RValue<Float> floorss(RValue<Float> val);
+		RValue<Float> ceilss(RValue<Float> val);
+
+		RValue<Float4> roundps(RValue<Float4> val, unsigned char imm);
+		RValue<Float4> floorps(RValue<Float4> val);
+		RValue<Float4> ceilps(RValue<Float4> val);
+
+		RValue<Float4> cmpps(RValue<Float4> x, RValue<Float4> y, unsigned char imm);
+		RValue<Float4> cmpeqps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> cmpltps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> cmpleps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> cmpunordps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> cmpneqps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> cmpnltps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> cmpnleps(RValue<Float4> x, RValue<Float4> y);
+		RValue<Float4> cmpordps(RValue<Float4> x, RValue<Float4> y);
+
+		RValue<Float> cmpss(RValue<Float> x, RValue<Float> y, unsigned char imm);
+		RValue<Float> cmpeqss(RValue<Float> x, RValue<Float> y);
+		RValue<Float> cmpltss(RValue<Float> x, RValue<Float> y);
+		RValue<Float> cmpless(RValue<Float> x, RValue<Float> y);
+		RValue<Float> cmpunordss(RValue<Float> x, RValue<Float> y);
+		RValue<Float> cmpneqss(RValue<Float> x, RValue<Float> y);
+		RValue<Float> cmpnltss(RValue<Float> x, RValue<Float> y);
+		RValue<Float> cmpnless(RValue<Float> x, RValue<Float> y);
+		RValue<Float> cmpordss(RValue<Float> x, RValue<Float> y);
+
+		RValue<Int4> pabsd(RValue<Int4> x);
+
+		RValue<Short4> paddsw(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> psubsw(RValue<Short4> x, RValue<Short4> y);
+		RValue<UShort4> paddusw(RValue<UShort4> x, RValue<UShort4> y);
+		RValue<UShort4> psubusw(RValue<UShort4> x, RValue<UShort4> y);
+		RValue<SByte8> paddsb(RValue<SByte8> x, RValue<SByte8> y);
+		RValue<SByte8> psubsb(RValue<SByte8> x, RValue<SByte8> y);
+		RValue<Byte8> paddusb(RValue<Byte8> x, RValue<Byte8> y);
+		RValue<Byte8> psubusb(RValue<Byte8> x, RValue<Byte8> y);
+
+		RValue<Short4> paddw(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> psubw(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> pmullw(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> pand(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> por(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> pxor(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> pshufw(RValue<Short4> x, unsigned char y);
+		RValue<Int2> punpcklwd(RValue<Short4> x, RValue<Short4> y);
+		RValue<Int2> punpckhwd(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> pinsrw(RValue<Short4> x, RValue<Int> y, unsigned int i);
+		RValue<Int> pextrw(RValue<Short4> x, unsigned int i);
+		RValue<Long1> punpckldq(RValue<Int2> x, RValue<Int2> y);
+		RValue<Long1> punpckhdq(RValue<Int2> x, RValue<Int2> y);
+		RValue<Short4> punpcklbw(RValue<Byte8> x, RValue<Byte8> y);
+		RValue<Short4> punpckhbw(RValue<Byte8> x, RValue<Byte8> y);
+		RValue<Byte8> paddb(RValue<Byte8> x, RValue<Byte8> y);
+		RValue<Byte8> psubb(RValue<Byte8> x, RValue<Byte8> y);
+		RValue<Int2> paddd(RValue<Int2> x, RValue<Int2> y);
+		RValue<Int2> psubd(RValue<Int2> x, RValue<Int2> y);
+
+		RValue<UShort4> pavgw(RValue<UShort4> x, RValue<UShort4> y);
+
+		RValue<Short4> pmaxsw(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> pminsw(RValue<Short4> x, RValue<Short4> y);
+
+		RValue<Short4> pcmpgtw(RValue<Short4> x, RValue<Short4> y);
+		RValue<Short4> pcmpeqw(RValue<Short4> x, RValue<Short4> y);
+		RValue<Byte8> pcmpgtb(RValue<SByte8> x, RValue<SByte8> y);
+		RValue<Byte8> pcmpeqb(RValue<Byte8> x, RValue<Byte8> y);
+
+		RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y);
+		RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y);
+		RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y);
+		RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y);
+
+		RValue<UShort8> packusdw(RValue<UInt4> x, RValue<UInt4> y);
+
+		RValue<UShort4> psrlw(RValue<UShort4> x, unsigned char y);
+		RValue<UShort8> psrlw(RValue<UShort8> x, unsigned char y);
+		RValue<Short4> psraw(RValue<Short4> x, unsigned char y);
+		RValue<Short8> psraw(RValue<Short8> x, unsigned char y);
+		RValue<Short4> psllw(RValue<Short4> x, unsigned char y);
+		RValue<Short8> psllw(RValue<Short8> x, unsigned char y);
+		RValue<Int2> pslld(RValue<Int2> x, unsigned char y);
+		RValue<Int4> pslld(RValue<Int4> x, unsigned char y);
+		RValue<Int2> psrad(RValue<Int2> x, unsigned char y);
+		RValue<Int4> psrad(RValue<Int4> x, unsigned char y);
+		RValue<UInt2> psrld(RValue<UInt2> x, unsigned char y);
+		RValue<UInt4> psrld(RValue<UInt4> x, unsigned char y);
+
+		RValue<UShort4> psrlw(RValue<UShort4> x, RValue<Long1> y);
+		RValue<Short4> psraw(RValue<Short4> x, RValue<Long1> y);
+		RValue<Short4> psllw(RValue<Short4> x, RValue<Long1> y);
+		RValue<Int2> pslld(RValue<Int2> x, RValue<Long1> y);
+		RValue<UInt2> psrld(RValue<UInt2> x, RValue<Long1> y);
+		RValue<Int2> psrad(RValue<Int2> x, RValue<Long1> y);
+
+		RValue<Int4> pmaxsd(RValue<Int4> x, RValue<Int4> y);
+		RValue<Int4> pminsd(RValue<Int4> x, RValue<Int4> y);
+		RValue<UInt4> pmaxud(RValue<UInt4> x, RValue<UInt4> y);
+		RValue<UInt4> pminud(RValue<UInt4> x, RValue<UInt4> y);
+
+		RValue<Short4> pmulhw(RValue<Short4> x, RValue<Short4> y);
+		RValue<UShort4> pmulhuw(RValue<UShort4> x, RValue<UShort4> y);
+		RValue<Int2> pmaddwd(RValue<Short4> x, RValue<Short4> y);
+
+		RValue<Short8> pmulhw(RValue<Short8> x, RValue<Short8> y);
+		RValue<UShort8> pmulhuw(RValue<UShort8> x, RValue<UShort8> y);
+		RValue<Int4> pmaddwd(RValue<Short8> x, RValue<Short8> y);
+
+		RValue<Int> movmskps(RValue<Float4> x);
+		RValue<Int> pmovmskb(RValue<Byte8> x);
+
+		RValue<Int4> pmovzxbd(RValue<Int4> x);
+		RValue<Int4> pmovsxbd(RValue<Int4> x);
+		RValue<Int4> pmovzxwd(RValue<Int4> x);
+		RValue<Int4> pmovsxwd(RValue<Int4> x);
+
+		void emms();
+	}
+}
diff --git a/src/Readme.txt b/src/Readme.txt
deleted file mode 100644
index 87f0151..0000000
--- a/src/Readme.txt
+++ /dev/null
@@ -1,160 +0,0 @@
-###########################################################################
-
-                               TransGaming Inc.
-
-                     SwiftShader Software GPU Toolkit
-
-                                 Build 5171
-
-                                June 11, 2013
-  
-           SwiftShader is Copyright(c) 2003-2013 TransGaming Inc.
-###########################################################################
-
-
-Thank you for purchasing TransGaming's SwiftShader Software GPU Toolkit, 
-TransGaming's high-speed pure-software 3D renderer. This release includes
-support for the OpenGL ES 2.0 and EGL 1.4 APIs on Windows and Linux.
-
-TransGaming's SwiftShader Software GPU Toolkit is the world's fastest
-and most flexible general-purpose pure software 3D rendering technology.
-SwiftShader's modular architecture is capable of supporting multiple 
-application programming interfaces, such as DirectX(tm) 9.0, and OpenGL(tm) 
-ES 2.0, the same APIs that developers are already using for existing 
-games and applications. This makes it possible to directly integrate
-SwiftShader into applications without any changes to source code. 
-SwiftShader technology can also support custom front-end APIs that have 
-been explicitly built for a specific application. 
-
-Rendering features available in SwiftShader range from basic fixed 
-function rendering through to Shader Model 3.0 level capabilities such 
-as advanced shaders, floating point rendering, multi-sample anti-aliasing, 
-and much more. 
-
-SwiftShader performs as much as 100 times faster than traditional 
-software renderers such as Microsoft's Direct3D(tm) Reference Rasterizer. 
-In benchmark tests on a modern CPU, SwiftShader-based renderers can 
-achieve performance that surpasses integrated graphics hardware -
-a modern quad-core Core i7 CPU at 3.2 GHz running SwiftShader scores 
-620 in 3DMark2006. SwiftShader achieves this unprecedented level of 
-performance by dynamically compiling highly optimized code specific to 
-an application's 3D rendering needs, and executing that code across all 
-available CPU cores in parallel.
-
-NOTE: Use of SwiftShader is subject to the the SwiftShader License 
-agreement signed between TransGaming Inc. and your company.
-
-
-System requirements
--------------------
-
-* x86 CPU, SSE support required
-* Basic 2D video card - no 3D card necessary!
-* Operating systems:
- - Microsoft Windows 98SE, Windows 2000, Windows XP, Windows Vista, or Windows 7
- - Linux
-* 128 MB RAM
-* 10 MB free hard disk space
-
-
-Compilation and Installation - OpenGL ES 2.0
---------------------------------------------
-
-* Windows:
-Open the SwiftShader.sln file using Visual C++ 2010. Select the "Release" solution
-configuration for builds which show the SwiftShader logo on non-licensed
-applications. Build all the projects (by pressing F7). After compilation has
-completed, you will find libEGL.dll and libGLESv2.dll in lib\Release\.
-
-These DLLs can be copied into the directory of an OpenGL ES 2.0 application, or
-can be loaded explicitly using the Win32 LoadLibrary function.
-
-* Linux:
-Install a recent nightly of Code::Blocks and open SwiftShader.workspace. Select the
-"Release" target and build the entire workspace. After compilation has completed,
-you will find libEGL.so and libGLESv2.so in bin\Release\.
-
-To use these with existing binaries, such as the PowerVR SDK samples, you can use
-the 'patchelf' tool to change the RPATH to ".\". This way you can place the .so
-files in the same directory and have the application use them instead of the
-default libraries. 
-
-License Authentication - C/C++
---------------------------------------
-
-Your licensed version of SwiftShader requires your application to provide 
-an authorization key to disable the SwiftShader Demonstration Logo Overlay.
-
-Incorporating the license check in your C/C++ application requires a small 
-change in your application's startup sequence. The "Register" function is
-exported from the libGLESv2 library. It has the following signature:
-
-    void GL_APIENTRY Register(char *licenseKey)
-
-Calling this function with your license key as a C string parameter will ensure
-that the logo rendering is disabled.
-
-
-Copyright & Logo Requirement
-----------------------------
-
-Your SwiftShader license includes a requirement that your application 
-display the SwiftShader logo and include appropriate Copyright notices 
-in its associated documentation.
-
-The enclosed SwiftShader_Logo.png is a high resolution transparent 
-PNG of the SwiftShader logo that you may use for this purpose.
-
-The documentation or license file for your application must include
-the following text:
-
-  This product includes SwiftShader Software GPU Tookit,
-  Copyright(c)2003-2013 TransGaming Inc.
-
-
-Changes since previous version
-------------------------------
-
-Build 5171 - June 11, 2013
-- Fixed a rare deadlock on using the renderbuffer of a deleted texture.
-- Fixed an infinite loop on shader loops containing both break and return statements.
-- Validate matching uniform precisions during program link.
-- Validate the call stack depth.
-- Restored the use of the __stdcall calling convention for the Register function on Windows.
-- Enabled base address randomization (ASLR). 
-
-Build 5139 - February 6, 2013
-- 64-bit Linux compatible.
-- Adopted the new shader preprocessor from ANGLE.
-- Fixed declaring used samplers.
-- Fixed enabling SSE3 support.
-- Fixed varying/uniform count robustness.
-- Fixed buffer update synchronization.
-- Implemented native 8-bit ALPHA texture support.
-- Implemented GL_OES_depth_texture.
-- Implemented GL_OES_depth_texture_cube_map.
-- Implemented GL_EXT_texture_filter_anisotropic.
-
-Build 5086 - August 10, 2012
-- Initial port to Linux.
-
-Build 4079 - April 18, 2012
-- Eliminated the use of the Microsoft HLSL compiler.
-- Added support for CPUs without SSE2 extensions.
-- Optimized the renderer for OpenGL operations.
-
-
-CONTACTS
---------
-
-For more information regarding SwiftShader or other TransGaming 
-products, please contact us as follows:
-
-Sales and Licensing Inquiries:
-
-  sales@transgaming.com
-
-
-Technical Questions and Information:
-
-  swiftshader@transgaming.com
diff --git a/src/Renderer/Blitter.cpp b/src/Renderer/Blitter.cpp
index 64ad6d0..95590ef 100644
--- a/src/Renderer/Blitter.cpp
+++ b/src/Renderer/Blitter.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Blitter.hpp"
 
diff --git a/src/Renderer/Blitter.hpp b/src/Renderer/Blitter.hpp
index 25c837d..52d3cee 100644
--- a/src/Renderer/Blitter.hpp
+++ b/src/Renderer/Blitter.hpp
@@ -1,97 +1,100 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Blitter_hpp

-#define sw_Blitter_hpp

-

-#include "Surface.hpp"

-#include "RoutineCache.hpp"

-#include "Reactor/Nucleus.hpp"

-

-#include <string.h>

-

-namespace sw

-{

-	class Blitter

-	{

-		enum Options : unsigned char

-		{

-			FILTER_POINT = 0x00,

-			WRITE_RED = 0x01,

-			WRITE_GREEN = 0x02,

-			WRITE_BLUE = 0x04,

-			WRITE_ALPHA = 0x08,

-			WRITE_RGBA = WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA,

-			FILTER_LINEAR = 0x10,

-			CLEAR_OPERATION = 0x20

-		};

-

-		struct BlitState

-		{

-			bool operator==(const BlitState &state) const

-			{

-				return memcmp(this, &state, sizeof(BlitState)) == 0;

-			}

-

-			Format sourceFormat;

-			Format destFormat;

-			Blitter::Options options;

-		};

-

-		struct BlitData

-		{

-			void *source;

-			void *dest;

-			int sPitchB;

-			int dPitchB;

-

-			float x0;

-			float y0;

-			float w;

-			float h;

-

-			int y0d;

-			int y1d;

-			int x0d;

-			int x1d;

-

-			int sWidth;

-			int sHeight;

-		};

-

-	public:

-		Blitter();

-

-		virtual ~Blitter();

-

-		void clear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);

-		void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter);

-		void blit3D(Surface *source, Surface *dest);

-

-	private:

-		bool read(Float4 &color, Pointer<Byte> element, Format format);

-		bool write(Float4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);

-		bool read(Int4 &color, Pointer<Byte> element, Format format);

-		bool write(Int4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);

-		static bool GetScale(float4& scale, Format format);

-		static bool ApplyScaleAndClamp(Float4& value, const BlitState& state);

-		void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);

-		bool blitReactor(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);

-		Routine *generate(BlitState &state);

-

-		RoutineCache<BlitState> *blitCache;

-		BackoffLock criticalSection;

-	};

-

-	extern Blitter blitter;

-}

-

-#endif   // sw_Blitter_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Blitter_hpp
+#define sw_Blitter_hpp
+
+#include "Surface.hpp"
+#include "RoutineCache.hpp"
+#include "Reactor/Nucleus.hpp"
+
+#include <string.h>
+
+namespace sw
+{
+	class Blitter
+	{
+		enum Options : unsigned char
+		{
+			FILTER_POINT = 0x00,
+			WRITE_RED = 0x01,
+			WRITE_GREEN = 0x02,
+			WRITE_BLUE = 0x04,
+			WRITE_ALPHA = 0x08,
+			WRITE_RGBA = WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA,
+			FILTER_LINEAR = 0x10,
+			CLEAR_OPERATION = 0x20
+		};
+
+		struct BlitState
+		{
+			bool operator==(const BlitState &state) const
+			{
+				return memcmp(this, &state, sizeof(BlitState)) == 0;
+			}
+
+			Format sourceFormat;
+			Format destFormat;
+			Blitter::Options options;
+		};
+
+		struct BlitData
+		{
+			void *source;
+			void *dest;
+			int sPitchB;
+			int dPitchB;
+
+			float x0;
+			float y0;
+			float w;
+			float h;
+
+			int y0d;
+			int y1d;
+			int x0d;
+			int x1d;
+
+			int sWidth;
+			int sHeight;
+		};
+
+	public:
+		Blitter();
+
+		virtual ~Blitter();
+
+		void clear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
+		void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter);
+		void blit3D(Surface *source, Surface *dest);
+
+	private:
+		bool read(Float4 &color, Pointer<Byte> element, Format format);
+		bool write(Float4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);
+		bool read(Int4 &color, Pointer<Byte> element, Format format);
+		bool write(Int4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);
+		static bool GetScale(float4& scale, Format format);
+		static bool ApplyScaleAndClamp(Float4& value, const BlitState& state);
+		void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);
+		bool blitReactor(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);
+		Routine *generate(BlitState &state);
+
+		RoutineCache<BlitState> *blitCache;
+		BackoffLock criticalSection;
+	};
+
+	extern Blitter blitter;
+}
+
+#endif   // sw_Blitter_hpp
diff --git a/src/Renderer/Clipper.cpp b/src/Renderer/Clipper.cpp
index d575bc3..d5aeaed 100644
--- a/src/Renderer/Clipper.cpp
+++ b/src/Renderer/Clipper.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Clipper.hpp"
 
diff --git a/src/Renderer/Clipper.hpp b/src/Renderer/Clipper.hpp
index fca7b0c..ad1af93e 100644
--- a/src/Renderer/Clipper.hpp
+++ b/src/Renderer/Clipper.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_Clipper_hpp
 #define sw_Clipper_hpp
diff --git a/src/Renderer/Color.cpp b/src/Renderer/Color.cpp
index 5565460..9ad6767 100644
--- a/src/Renderer/Color.cpp
+++ b/src/Renderer/Color.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Color.hpp"
 
diff --git a/src/Renderer/Color.hpp b/src/Renderer/Color.hpp
index 51e8015..7afe61f 100644
--- a/src/Renderer/Color.hpp
+++ b/src/Renderer/Color.hpp
@@ -1,469 +1,472 @@
-// 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.

-//

-

-#ifndef sw_Color_hpp

-#define sw_Color_hpp

-

-#include "Common/Types.hpp"

-#include "Common/Math.hpp"

-

-namespace sw

-{

-	template<class T>

-	struct Color

-	{

-		Color();

-		

-		Color(const Color<byte> &c);

-		Color(const Color<short> &c);

-		Color(const Color<float> &c);

-		

-		Color(int c);

-		Color(unsigned short c);

-		Color(unsigned long c);

-		Color(unsigned int c);

-		

-		Color(T r, T g, T b, T a = 1);

-

-		operator unsigned int() const;

-

-		T &operator[](int i);

-		const T &operator[](int i) const;

-

-		Color<T> operator+() const;

-		Color<T> operator-() const;

-

-		Color<T>& operator=(const Color<T>& c);

-

-		Color<T> &operator+=(const Color<T> &c);

-		Color<T> &operator*=(float l);

-

-		static Color<T> gradient(const Color<T> &c1, const Color<T>  &c2, float d);

-		static Color<T> shade(const Color<T> &c1, const Color<T>  &c2, float d);

-

-		template<class S>

-		friend Color<S> operator+(const Color<S> &c1, const Color<S> &c2);

-		template<class S>

-		friend Color<S> operator-(const Color<S> &c1, const Color<S> &c2);

-

-		template<class S>

-		friend Color<S> operator*(float l, const Color<S> &c);

-		template<class S>

-		friend Color<S> operator*(const Color<S> &c1, const Color<S> &c2);

-		template<class S>

-		friend Color<S> operator/(const Color<S> &c, float l);

-

-		T r;

-		T g;

-		T b;

-		T a;

-	};

-}

-

-#include "Common/Math.hpp"

-

-namespace sw

-{

-	template<class T>

-	inline Color<T>::Color()

-	{

-	}

-

-	template<>

-	inline Color<byte>::Color(const Color<byte> &c)

-	{

-		r = c.r;

-		g = c.g;

-		b = c.b;

-		a = c.a;

-	}

-

-	template<>

-	inline Color<byte>::Color(const Color<short> &c)

-	{

-		r = clamp(c.r >> 4, 0, 255);

-		g = clamp(c.g >> 4, 0, 255);

-		b = clamp(c.b >> 4, 0, 255);

-		a = clamp(c.a >> 4, 0, 255);

-	}

-

-	template<>

-	inline Color<byte>::Color(const Color<float> &c)

-	{

-		r = ifloor(clamp(c.r * 256.0f, 0.0f, 255.0f));

-		g = ifloor(clamp(c.g * 256.0f, 0.0f, 255.0f));

-		b = ifloor(clamp(c.b * 256.0f, 0.0f, 255.0f));

-		a = ifloor(clamp(c.a * 256.0f, 0.0f, 255.0f));

-	}

-

-	template<>

-	inline Color<short>::Color(const Color<short> &c)

-	{

-		r = c.r;

-		g = c.g;

-		b = c.b;

-		a = c.a;

-	}

-

-	template<>

-	inline Color<short>::Color(const Color<byte> &c)

-	{

-		r = c.r << 4;

-		g = c.g << 4;

-		b = c.b << 4;

-		a = c.a << 4;

-	}

-

-	template<>

-	inline Color<float>::Color(const Color<float> &c)

-	{

-		r = c.r;

-		g = c.g;

-		b = c.b;

-		a = c.a;

-	}

-

-	template<>

-	inline Color<short>::Color(const Color<float> &c)

-	{

-		r = iround(clamp(c.r * 4095.0f, -4096.0f, 4095.0f));

-		g = iround(clamp(c.g * 4095.0f, -4096.0f, 4095.0f));

-		b = iround(clamp(c.b * 4095.0f, -4096.0f, 4095.0f));

-		a = iround(clamp(c.a * 4095.0f, -4096.0f, 4095.0f));

-	}

-

-	template<>

-	inline Color<float>::Color(const Color<byte> &c)

-	{

-		r = c.r / 255.0f;

-		g = c.g / 255.0f;

-		b = c.b / 255.0f;

-		a = c.a / 255.0f;

-	}

-

-	template<>

-	inline Color<float>::Color(const Color<short> &c)

-	{

-		r = c.r / 4095.0f;

-		g = c.g / 4095.0f;

-		b = c.b / 4095.0f;

-		a = c.a / 4095.0f;

-	}

-

-	template<>

-	inline Color<float>::Color(unsigned short c)

-	{

-		r = (float)(c & 0xF800) / (float)0xF800;

-		g = (float)(c & 0x07E0) / (float)0x07E0;

-		b = (float)(c & 0x001F) / (float)0x001F;

-		a = 1;

-	}

-

-	template<>

-	inline Color<short>::Color(unsigned short c)

-	{

-		// 4.12 fixed-point format

-		r = ((c & 0xF800) >> 4) + ((c & 0xF800) >> 9) + ((c & 0xF800) >> 14);

-		g = ((c & 0x07E0) << 1) + ((c & 0x07E0) >> 5);

-		b = ((c & 0x001F) << 7) + ((c & 0x001F) << 2) + ((c & 0x001F) >> 3);

-		a = 0x1000;

-	}

-

-	template<>

-	inline Color<byte>::Color(unsigned short c)

-	{

-		r = (byte)(((c & 0xF800) >> 8) + ((c & 0xE000) >> 13));

-		g = (byte)(((c & 0x07E0) >> 3) + ((c & 0x0600) >> 9));

-		b = (byte)(((c & 0x001F) << 3) + ((c & 0x001C) >> 2));

-		a = 0xFF;

-	}

-

-	template<>

-	inline Color<float>::Color(int c)

-	{

-		const float d = 1.0f / 255.0f;

-

-		r = (float)((c & 0x00FF0000) >> 16) * d;

-		g = (float)((c & 0x0000FF00) >> 8) * d;

-		b = (float)((c & 0x000000FF) >> 0) * d;

-		a = (float)((c & 0xFF000000) >> 24) * d;

-	}

-

-	template<>

-	inline Color<short>::Color(int c)

-	{

-		// 4.12 fixed-point format

-		r = (short)((c & 0x00FF0000) >> 12);

-		g = (short)((c & 0x0000FF00) >> 4);

-		b = (short)((c & 0x000000FF) << 4);

-		a = (short)((c & 0xFF000000) >> 20);

-	}

-

-	template<>

-	inline Color<byte>::Color(int c)

-	{

-		r = (byte)((c & 0x00FF0000) >> 16);

-		g = (byte)((c & 0x0000FF00) >> 8);

-		b = (byte)((c & 0x000000FF) >> 0);

-		a = (byte)((c & 0xFF000000) >> 24);

-	}

-

-	template<>

-	inline Color<float>::Color(unsigned int c)

-	{

-		const float d = 1.0f / 255.0f;

-

-		r = (float)((c & 0x00FF0000) >> 16) * d;

-		g = (float)((c & 0x0000FF00) >> 8) * d;

-		b = (float)((c & 0x000000FF) >> 0) * d;

-		a = (float)((c & 0xFF000000) >> 24) * d;

-	}

-

-	template<>

-	inline Color<short>::Color(unsigned int c)

-	{

-		// 4.12 fixed-point format

-		r = (short)((c & 0x00FF0000) >> 12);

-		g = (short)((c & 0x0000FF00) >> 4);

-		b = (short)((c & 0x000000FF) << 4);

-		a = (short)((c & 0xFF000000) >> 20);

-	}

-

-	template<>

-	inline Color<byte>::Color(unsigned int c)

-	{

-		r = (byte)((c & 0x00FF0000) >> 16);

-		g = (byte)((c & 0x0000FF00) >> 8);

-		b = (byte)((c & 0x000000FF) >> 0);

-		a = (byte)((c & 0xFF000000) >> 24);

-	}

-

-	template<>

-	inline Color<float>::Color(unsigned long c)

-	{

-		const float d = 1.0f / 255.0f;

-

-		r = (float)((c & 0x00FF0000) >> 16) * d;

-		g = (float)((c & 0x0000FF00) >> 8) * d;

-		b = (float)((c & 0x000000FF) >> 0) * d;

-		a = (float)((c & 0xFF000000) >> 24) * d;

-	}

-

-	template<>

-	inline Color<short>::Color(unsigned long c)

-	{

-		// 4.12 fixed-point format

-		r = (short)((c & 0x00FF0000) >> 12);

-		g = (short)((c & 0x0000FF00) >> 4);

-		b = (short)((c & 0x000000FF) << 4);

-		a = (short)((c & 0xFF000000) >> 20);

-	}

-

-	template<>

-	inline Color<byte>::Color(unsigned long c)

-	{

-		r = (byte)((c & 0x00FF0000) >> 16);

-		g = (byte)((c & 0x0000FF00) >> 8);

-		b = (byte)((c & 0x000000FF) >> 0);

-		a = (byte)((c & 0xFF000000) >> 24);

-	}

-

-	template<class T>

-	inline Color<T>::Color(T r_, T g_, T b_, T a_)

-	{

-		r = r_;

-		g = g_;

-		b = b_;

-		a = a_;

-	}

-

-	template<>

-	inline Color<float>::operator unsigned int() const

-	{

-		return ((unsigned int)min(b * 255.0f, 255.0f) << 0) |

-		       ((unsigned int)min(g * 255.0f, 255.0f) << 8) |

-		       ((unsigned int)min(r * 255.0f, 255.0f) << 16) |

-		       ((unsigned int)min(a * 255.0f, 255.0f) << 24);

-	}

-

-	template<>

-	inline Color<short>::operator unsigned int() const

-	{

-		return ((unsigned int)min(b >> 4, 255) << 0) |

-		       ((unsigned int)min(g >> 4, 255) << 8) |

-		       ((unsigned int)min(r >> 4, 255) << 16) |

-		       ((unsigned int)min(a >> 4, 255) << 24);

-	}

-

-	template<>

-	inline Color<byte>::operator unsigned int() const

-	{

-		return (b << 0) +

-		       (g << 8) +

-		       (r << 16) +

-			   (a << 24);

-	}

-

-	template<class T>

-	inline T &Color<T>::operator[](int i)

-	{

-		return (&r)[i];

-	}

-

-	template<class T>

-	inline const T &Color<T>::operator[](int i) const

-	{

-		return (&r)[i];

-	}

-

-	template<class T>

-	inline Color<T> Color<T>::operator+() const

-	{

-		return *this;

-	}

-

-	template<class T>

-	inline Color<T> Color<T>::operator-() const

-	{

-		return Color(-r, -g, -b, -a);

-	}

-

-	template<class T>

-	inline Color<T> &Color<T>::operator=(const Color& c)

-	{

-		r = c.r;

-		g = c.g;

-		b = c.b;

-		a = c.a;

-

-		return *this;

-	}

-

-	template<class T>

-	inline Color<T> &Color<T>::operator+=(const Color &c)

-	{

-		r += c.r;

-		g += c.g;

-		b += c.b;

-		a += c.a;

-

-		return *this;

-	}

-

-	template<class T>

-	inline Color<T> &Color<T>::operator*=(float l)

-	{

-		*this = l * *this;

-

-		return *this;

-	}

-

-	template<class T>

-	inline Color<T> operator+(const Color<T> &c1, const Color<T> &c2)

-	{

-		return Color<T>(c1.r + c2.r,

-		                c1.g + c2.g,

-		                c1.b + c2.b,

-		                c1.a + c2.a);	

-	}

-

-	template<class T>

-	inline Color<T> operator-(const Color<T> &c1, const Color<T> &c2)

-	{

-		return Color<T>(c1.r - c2.r,

-		                c1.g - c2.g,

-		                c1.b - c2.b,

-		                c1.a - c2.a);	

-	}

-

-	template<class T>

-	inline Color<T> operator*(float l, const Color<T> &c)

-	{

-		T r = (T)(l * c.r);

-		T g = (T)(l * c.g);

-		T b = (T)(l * c.b);

-		T a = (T)(l * c.a);

-

-		return Color<T>(r, g, b, a);

-	}

-

-	template<class T>

-	inline Color<T> operator*(const Color<T> &c1, const Color<T> &c2)

-	{

-		T r = c1.r * c2.r;

-		T g = c1.g * c2.g;

-		T b = c1.b * c2.b;

-		T a = c1.a * c2.a;

-

-		return Color<T>(r, g, b, a);

-	}

-

-	template<>

-	inline Color<short> operator*(const Color<short> &c1, const Color<short> &c2)

-	{

-		short r = c1.r * c2.r >> 12;

-		short g = c1.g * c2.g >> 12;

-		short b = c1.b * c2.b >> 12;

-		short a = c1.a * c2.a >> 12;

-

-		return Color<short>(r, g, b, a);

-	}

-

-	template<>

-	inline Color<byte> operator*(const Color<byte> &c1, const Color<byte> &c2)

-	{

-		byte r = c1.r * c2.r >> 8;

-		byte g = c1.g * c2.g >> 8;

-		byte b = c1.b * c2.b >> 8;

-		byte a = c1.a * c2.a >> 8;

-

-		return Color<byte>(r, g, b, a);

-	}

-

-	template<class T>

-	inline Color<T> operator/(const Color<T> &c, float l)

-	{

-		l = 1.0f / l; 

-

-		T r = (T)(l * c.r);

-		T g = (T)(l * c.g);

-		T b = (T)(l * c.b);

-		T a = (T)(l * c.a);

-

-		return Color<T>(r, g, b, a);

-	}

-

-	template<class T>

-	inline Color<T> Color<T>::gradient(const Color<T> &c1, const Color<T> &c2, float d)

-	{

-		d = 1.0f / d; 

-

-		T r = (c2.r - c1.r) * d;

-		T g = (c2.g - c1.g) * d;

-		T b = (c2.b - c1.b) * d;

-		T a = (c2.a - c1.a) * d;

-

-		return Color<T>(r, g, b, a);

-	}

-

-	template<class T>

-	inline Color<T> Color<T>::shade(const Color<T> &c1, const Color<T>  &c2, float d)

-	{

-		T r = c1.r + (T)(d * (c2.r - c1.r));

-		T g = c1.g + (T)(d * (c2.g - c1.g));

-		T b = c1.b + (T)(d * (c2.b - c1.b));

-		T a = c1.a + (T)(d * (c2.a - c1.a));

-

-		return Color<T>(r, g, b, a);

-	}

-}

-

-#endif   // sw_Color_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Color_hpp
+#define sw_Color_hpp
+
+#include "Common/Types.hpp"
+#include "Common/Math.hpp"
+
+namespace sw
+{
+	template<class T>
+	struct Color
+	{
+		Color();
+	
+		Color(const Color<byte> &c);
+		Color(const Color<short> &c);
+		Color(const Color<float> &c);
+		
+		Color(int c);
+		Color(unsigned short c);
+		Color(unsigned long c);
+		Color(unsigned int c);
+		
+		Color(T r, T g, T b, T a = 1);
+
+		operator unsigned int() const;
+
+		T &operator[](int i);
+		const T &operator[](int i) const;
+
+		Color<T> operator+() const;
+		Color<T> operator-() const;
+
+		Color<T>& operator=(const Color<T>& c);
+
+		Color<T> &operator+=(const Color<T> &c);
+		Color<T> &operator*=(float l);
+
+		static Color<T> gradient(const Color<T> &c1, const Color<T>  &c2, float d);
+		static Color<T> shade(const Color<T> &c1, const Color<T>  &c2, float d);
+
+		template<class S>
+		friend Color<S> operator+(const Color<S> &c1, const Color<S> &c2);
+		template<class S>
+		friend Color<S> operator-(const Color<S> &c1, const Color<S> &c2);
+
+		template<class S>
+		friend Color<S> operator*(float l, const Color<S> &c);
+		template<class S>
+		friend Color<S> operator*(const Color<S> &c1, const Color<S> &c2);
+		template<class S>
+		friend Color<S> operator/(const Color<S> &c, float l);
+
+		T r;
+		T g;
+		T b;
+		T a;
+	};
+}
+
+#include "Common/Math.hpp"
+
+namespace sw
+{
+	template<class T>
+	inline Color<T>::Color()
+	{
+	}
+
+	template<>
+	inline Color<byte>::Color(const Color<byte> &c)
+	{
+		r = c.r;
+		g = c.g;
+		b = c.b;
+		a = c.a;
+	}
+
+	template<>
+	inline Color<byte>::Color(const Color<short> &c)
+	{
+		r = clamp(c.r >> 4, 0, 255);
+		g = clamp(c.g >> 4, 0, 255);
+		b = clamp(c.b >> 4, 0, 255);
+		a = clamp(c.a >> 4, 0, 255);
+	}
+
+	template<>
+	inline Color<byte>::Color(const Color<float> &c)
+	{
+		r = ifloor(clamp(c.r * 256.0f, 0.0f, 255.0f));
+		g = ifloor(clamp(c.g * 256.0f, 0.0f, 255.0f));
+		b = ifloor(clamp(c.b * 256.0f, 0.0f, 255.0f));
+		a = ifloor(clamp(c.a * 256.0f, 0.0f, 255.0f));
+	}
+
+	template<>
+	inline Color<short>::Color(const Color<short> &c)
+	{
+		r = c.r;
+		g = c.g;
+		b = c.b;
+		a = c.a;
+	}
+
+	template<>
+	inline Color<short>::Color(const Color<byte> &c)
+	{
+		r = c.r << 4;
+		g = c.g << 4;
+		b = c.b << 4;
+		a = c.a << 4;
+	}
+
+	template<>
+	inline Color<float>::Color(const Color<float> &c)
+	{
+		r = c.r;
+		g = c.g;
+		b = c.b;
+		a = c.a;
+	}
+
+	template<>
+	inline Color<short>::Color(const Color<float> &c)
+	{
+		r = iround(clamp(c.r * 4095.0f, -4096.0f, 4095.0f));
+		g = iround(clamp(c.g * 4095.0f, -4096.0f, 4095.0f));
+		b = iround(clamp(c.b * 4095.0f, -4096.0f, 4095.0f));
+		a = iround(clamp(c.a * 4095.0f, -4096.0f, 4095.0f));
+	}
+
+	template<>
+	inline Color<float>::Color(const Color<byte> &c)
+	{
+		r = c.r / 255.0f;
+		g = c.g / 255.0f;
+		b = c.b / 255.0f;
+		a = c.a / 255.0f;
+	}
+
+	template<>
+	inline Color<float>::Color(const Color<short> &c)
+	{
+		r = c.r / 4095.0f;
+		g = c.g / 4095.0f;
+		b = c.b / 4095.0f;
+		a = c.a / 4095.0f;
+	}
+
+	template<>
+	inline Color<float>::Color(unsigned short c)
+	{
+		r = (float)(c & 0xF800) / (float)0xF800;
+		g = (float)(c & 0x07E0) / (float)0x07E0;
+		b = (float)(c & 0x001F) / (float)0x001F;
+		a = 1;
+	}
+
+	template<>
+	inline Color<short>::Color(unsigned short c)
+	{
+		// 4.12 fixed-point format
+		r = ((c & 0xF800) >> 4) + ((c & 0xF800) >> 9) + ((c & 0xF800) >> 14);
+		g = ((c & 0x07E0) << 1) + ((c & 0x07E0) >> 5);
+		b = ((c & 0x001F) << 7) + ((c & 0x001F) << 2) + ((c & 0x001F) >> 3);
+		a = 0x1000;
+	}
+
+	template<>
+	inline Color<byte>::Color(unsigned short c)
+	{
+		r = (byte)(((c & 0xF800) >> 8) + ((c & 0xE000) >> 13));
+		g = (byte)(((c & 0x07E0) >> 3) + ((c & 0x0600) >> 9));
+		b = (byte)(((c & 0x001F) << 3) + ((c & 0x001C) >> 2));
+		a = 0xFF;
+	}
+
+	template<>
+	inline Color<float>::Color(int c)
+	{
+		const float d = 1.0f / 255.0f;
+
+		r = (float)((c & 0x00FF0000) >> 16) * d;
+		g = (float)((c & 0x0000FF00) >> 8) * d;
+		b = (float)((c & 0x000000FF) >> 0) * d;
+		a = (float)((c & 0xFF000000) >> 24) * d;
+	}
+
+	template<>
+	inline Color<short>::Color(int c)
+	{
+		// 4.12 fixed-point format
+		r = (short)((c & 0x00FF0000) >> 12);
+		g = (short)((c & 0x0000FF00) >> 4);
+		b = (short)((c & 0x000000FF) << 4);
+		a = (short)((c & 0xFF000000) >> 20);
+	}
+
+	template<>
+	inline Color<byte>::Color(int c)
+	{
+		r = (byte)((c & 0x00FF0000) >> 16);
+		g = (byte)((c & 0x0000FF00) >> 8);
+		b = (byte)((c & 0x000000FF) >> 0);
+		a = (byte)((c & 0xFF000000) >> 24);
+	}
+
+	template<>
+	inline Color<float>::Color(unsigned int c)
+	{
+		const float d = 1.0f / 255.0f;
+
+		r = (float)((c & 0x00FF0000) >> 16) * d;
+		g = (float)((c & 0x0000FF00) >> 8) * d;
+		b = (float)((c & 0x000000FF) >> 0) * d;
+		a = (float)((c & 0xFF000000) >> 24) * d;
+	}
+
+	template<>
+	inline Color<short>::Color(unsigned int c)
+	{
+		// 4.12 fixed-point format
+		r = (short)((c & 0x00FF0000) >> 12);
+		g = (short)((c & 0x0000FF00) >> 4);
+		b = (short)((c & 0x000000FF) << 4);
+		a = (short)((c & 0xFF000000) >> 20);
+	}
+
+	template<>
+	inline Color<byte>::Color(unsigned int c)
+	{
+		r = (byte)((c & 0x00FF0000) >> 16);
+		g = (byte)((c & 0x0000FF00) >> 8);
+		b = (byte)((c & 0x000000FF) >> 0);
+		a = (byte)((c & 0xFF000000) >> 24);
+	}
+
+	template<>
+	inline Color<float>::Color(unsigned long c)
+	{
+		const float d = 1.0f / 255.0f;
+
+		r = (float)((c & 0x00FF0000) >> 16) * d;
+		g = (float)((c & 0x0000FF00) >> 8) * d;
+		b = (float)((c & 0x000000FF) >> 0) * d;
+		a = (float)((c & 0xFF000000) >> 24) * d;
+	}
+
+	template<>
+	inline Color<short>::Color(unsigned long c)
+	{
+		// 4.12 fixed-point format
+		r = (short)((c & 0x00FF0000) >> 12);
+		g = (short)((c & 0x0000FF00) >> 4);
+		b = (short)((c & 0x000000FF) << 4);
+		a = (short)((c & 0xFF000000) >> 20);
+	}
+
+	template<>
+	inline Color<byte>::Color(unsigned long c)
+	{
+		r = (byte)((c & 0x00FF0000) >> 16);
+		g = (byte)((c & 0x0000FF00) >> 8);
+		b = (byte)((c & 0x000000FF) >> 0);
+		a = (byte)((c & 0xFF000000) >> 24);
+	}
+
+	template<class T>
+	inline Color<T>::Color(T r_, T g_, T b_, T a_)
+	{
+		r = r_;
+		g = g_;
+		b = b_;
+		a = a_;
+	}
+
+	template<>
+	inline Color<float>::operator unsigned int() const
+	{
+		return ((unsigned int)min(b * 255.0f, 255.0f) << 0) |
+		       ((unsigned int)min(g * 255.0f, 255.0f) << 8) |
+		       ((unsigned int)min(r * 255.0f, 255.0f) << 16) |
+		       ((unsigned int)min(a * 255.0f, 255.0f) << 24);
+	}
+
+	template<>
+	inline Color<short>::operator unsigned int() const
+	{
+		return ((unsigned int)min(b >> 4, 255) << 0) |
+		       ((unsigned int)min(g >> 4, 255) << 8) |
+		       ((unsigned int)min(r >> 4, 255) << 16) |
+		       ((unsigned int)min(a >> 4, 255) << 24);
+	}
+
+	template<>
+	inline Color<byte>::operator unsigned int() const
+	{
+		return (b << 0) +
+		       (g << 8) +
+		       (r << 16) +
+			   (a << 24);
+	}
+
+	template<class T>
+	inline T &Color<T>::operator[](int i)
+	{
+		return (&r)[i];
+	}
+
+	template<class T>
+	inline const T &Color<T>::operator[](int i) const
+	{
+		return (&r)[i];
+	}
+
+	template<class T>
+	inline Color<T> Color<T>::operator+() const
+	{
+		return *this;
+	}
+
+	template<class T>
+	inline Color<T> Color<T>::operator-() const
+	{
+		return Color(-r, -g, -b, -a);
+	}
+
+	template<class T>
+	inline Color<T> &Color<T>::operator=(const Color& c)
+	{
+		r = c.r;
+		g = c.g;
+		b = c.b;
+		a = c.a;
+
+		return *this;
+	}
+
+	template<class T>
+	inline Color<T> &Color<T>::operator+=(const Color &c)
+	{
+		r += c.r;
+		g += c.g;
+		b += c.b;
+		a += c.a;
+
+		return *this;
+	}
+
+	template<class T>
+	inline Color<T> &Color<T>::operator*=(float l)
+	{
+		*this = l * *this;
+
+		return *this;
+	}
+
+	template<class T>
+	inline Color<T> operator+(const Color<T> &c1, const Color<T> &c2)
+	{
+		return Color<T>(c1.r + c2.r,
+		                c1.g + c2.g,
+		                c1.b + c2.b,
+		                c1.a + c2.a);	
+	}
+
+	template<class T>
+	inline Color<T> operator-(const Color<T> &c1, const Color<T> &c2)
+	{
+		return Color<T>(c1.r - c2.r,
+		                c1.g - c2.g,
+		                c1.b - c2.b,
+		                c1.a - c2.a);	
+	}
+
+	template<class T>
+	inline Color<T> operator*(float l, const Color<T> &c)
+	{
+		T r = (T)(l * c.r);
+		T g = (T)(l * c.g);
+		T b = (T)(l * c.b);
+		T a = (T)(l * c.a);
+
+		return Color<T>(r, g, b, a);
+	}
+
+	template<class T>
+	inline Color<T> operator*(const Color<T> &c1, const Color<T> &c2)
+	{
+		T r = c1.r * c2.r;
+		T g = c1.g * c2.g;
+		T b = c1.b * c2.b;
+		T a = c1.a * c2.a;
+
+		return Color<T>(r, g, b, a);
+	}
+
+	template<>
+	inline Color<short> operator*(const Color<short> &c1, const Color<short> &c2)
+	{
+		short r = c1.r * c2.r >> 12;
+		short g = c1.g * c2.g >> 12;
+		short b = c1.b * c2.b >> 12;
+		short a = c1.a * c2.a >> 12;
+
+		return Color<short>(r, g, b, a);
+	}
+
+	template<>
+	inline Color<byte> operator*(const Color<byte> &c1, const Color<byte> &c2)
+	{
+		byte r = c1.r * c2.r >> 8;
+		byte g = c1.g * c2.g >> 8;
+		byte b = c1.b * c2.b >> 8;
+		byte a = c1.a * c2.a >> 8;
+
+		return Color<byte>(r, g, b, a);
+	}
+
+	template<class T>
+	inline Color<T> operator/(const Color<T> &c, float l)
+	{
+		l = 1.0f / l; 
+
+		T r = (T)(l * c.r);
+		T g = (T)(l * c.g);
+		T b = (T)(l * c.b);
+		T a = (T)(l * c.a);
+
+		return Color<T>(r, g, b, a);
+	}
+
+	template<class T>
+	inline Color<T> Color<T>::gradient(const Color<T> &c1, const Color<T> &c2, float d)
+	{
+		d = 1.0f / d; 
+
+		T r = (c2.r - c1.r) * d;
+		T g = (c2.g - c1.g) * d;
+		T b = (c2.b - c1.b) * d;
+		T a = (c2.a - c1.a) * d;
+
+		return Color<T>(r, g, b, a);
+	}
+
+	template<class T>
+	inline Color<T> Color<T>::shade(const Color<T> &c1, const Color<T>  &c2, float d)
+	{
+		T r = c1.r + (T)(d * (c2.r - c1.r));
+		T g = c1.g + (T)(d * (c2.g - c1.g));
+		T b = c1.b + (T)(d * (c2.b - c1.b));
+		T a = c1.a + (T)(d * (c2.a - c1.a));
+
+		return Color<T>(r, g, b, a);
+	}
+}
+
+#endif   // sw_Color_hpp
diff --git a/src/Renderer/Context.cpp b/src/Renderer/Context.cpp
index b1891b2..1edecd8 100644
--- a/src/Renderer/Context.cpp
+++ b/src/Renderer/Context.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Context.hpp"
 
@@ -95,8 +98,8 @@
 		case DRAW_INDEXEDTRIANGLESTRIP32:
 		case DRAW_INDEXEDTRIANGLEFAN32:
 			return fillModeAware ? fillMode == FILL_VERTEX : false;
-        case DRAW_QUADLIST:
-            return false;
+		case DRAW_QUADLIST:
+			return false;
 		default:
 			ASSERT(false);
 		}
@@ -139,8 +142,8 @@
 		case DRAW_INDEXEDTRIANGLESTRIP32:
 		case DRAW_INDEXEDTRIANGLEFAN32:
 			return fillModeAware ? fillMode == FILL_WIREFRAME : false;
-        case DRAW_QUADLIST:
-            return false;
+		case DRAW_QUADLIST:
+			return false;
 		default:
 			ASSERT(false);
 		}
@@ -183,9 +186,9 @@
 		case DRAW_INDEXEDTRIANGLESTRIP32:
 		case DRAW_INDEXEDTRIANGLEFAN32:
 			return fillModeAware ? fillMode == FILL_SOLID : true;
-        case DRAW_QUADLIST:
+		case DRAW_QUADLIST:
 			// Quads are broken up into triangles
-            return fillModeAware ? fillMode == FILL_SOLID : true;
+			return fillModeAware ? fillMode == FILL_SOLID : true;
 		default:
 			ASSERT(false);
 		}
@@ -603,8 +606,8 @@
 	{
 		return texCoordActive(coordinate, 0) ||
 		       texCoordActive(coordinate, 1) ||
-			   texCoordActive(coordinate, 2) ||
-			   texCoordActive(coordinate, 3);
+		       texCoordActive(coordinate, 2) ||
+		       texCoordActive(coordinate, 3);
 	}
 
 	bool Context::isProjectionComponent(unsigned int coordinate, int component)
diff --git a/src/Renderer/Context.hpp b/src/Renderer/Context.hpp
index c8f9624..6e68ecb 100644
--- a/src/Renderer/Context.hpp
+++ b/src/Renderer/Context.hpp
@@ -1,531 +1,534 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Context_hpp

-#define sw_Context_hpp

-

-#include "Sampler.hpp"

-#include "TextureStage.hpp"

-#include "Stream.hpp"

-#include "Point.hpp"

-#include "Vertex.hpp"

-

-namespace sw

-{

-	class Sampler;

-	class Surface;

-	class PixelShader;

-	class VertexShader;

-	struct Triangle;

-	struct Primitive;

-	struct Vertex;

-	class Resource;

-

-	enum In   // Default input stream semantic

-	{

-		Position = 0,

-		BlendWeight = 1,

-		BlendIndices = 2,

-		Normal = 3,

-		PointSize = 4,

-		Color0 = 5,

-		Color1 = 6,

-		TexCoord0 = 7,

-		TexCoord1 = 8,

-		TexCoord2 = 9,

-		TexCoord3 = 10,

-		TexCoord4 = 11,

-		TexCoord5 = 12,

-		TexCoord6 = 13,

-		TexCoord7 = 14,

-		PositionT = 15

-	};

-

-	enum DrawType : unsigned int

-	{

-		// These types must stay ordered by vertices per primitive. Also, if these basic types

-		// are modified, verify the value assigned to task->verticesPerPrimitive in Renderer.cpp

-		DRAW_POINTLIST     = 0x00,

-		DRAW_LINELIST      = 0x01,

-		DRAW_LINESTRIP     = 0x02,

-		DRAW_LINELOOP      = 0x03,

-		DRAW_TRIANGLELIST  = 0x04,

-		DRAW_TRIANGLESTRIP = 0x05,

-		DRAW_TRIANGLEFAN   = 0x06,

-		DRAW_QUADLIST      = 0x07,

-

-		DRAW_NONINDEXED = 0x00,

-		DRAW_INDEXED8   = 0x10,

-		DRAW_INDEXED16  = 0x20,

-		DRAW_INDEXED32  = 0x30,

-

-		DRAW_INDEXEDPOINTLIST8 = DRAW_POINTLIST | DRAW_INDEXED8,

-		DRAW_INDEXEDLINELIST8  = DRAW_LINELIST  | DRAW_INDEXED8,

-		DRAW_INDEXEDLINESTRIP8 = DRAW_LINESTRIP | DRAW_INDEXED8,

-		DRAW_INDEXEDLINELOOP8  = DRAW_LINELOOP  | DRAW_INDEXED8,

-		DRAW_INDEXEDTRIANGLELIST8  = DRAW_TRIANGLELIST  | DRAW_INDEXED8,

-		DRAW_INDEXEDTRIANGLESTRIP8 = DRAW_TRIANGLESTRIP | DRAW_INDEXED8,

-		DRAW_INDEXEDTRIANGLEFAN8   = DRAW_TRIANGLEFAN   | DRAW_INDEXED8,

-

-		DRAW_INDEXEDPOINTLIST16 = DRAW_POINTLIST | DRAW_INDEXED16,

-		DRAW_INDEXEDLINELIST16  = DRAW_LINELIST  | DRAW_INDEXED16,

-		DRAW_INDEXEDLINESTRIP16 = DRAW_LINESTRIP | DRAW_INDEXED16,

-		DRAW_INDEXEDLINELOOP16  = DRAW_LINELOOP  | DRAW_INDEXED16,

-		DRAW_INDEXEDTRIANGLELIST16  = DRAW_TRIANGLELIST  | DRAW_INDEXED16,

-		DRAW_INDEXEDTRIANGLESTRIP16 = DRAW_TRIANGLESTRIP | DRAW_INDEXED16,

-		DRAW_INDEXEDTRIANGLEFAN16   = DRAW_TRIANGLEFAN   | DRAW_INDEXED16,

-

-		DRAW_INDEXEDPOINTLIST32 = DRAW_POINTLIST | DRAW_INDEXED32,

-		DRAW_INDEXEDLINELIST32  = DRAW_LINELIST  | DRAW_INDEXED32,

-		DRAW_INDEXEDLINESTRIP32 = DRAW_LINESTRIP | DRAW_INDEXED32,

-		DRAW_INDEXEDLINELOOP32  = DRAW_LINELOOP  | DRAW_INDEXED32,

-		DRAW_INDEXEDTRIANGLELIST32  = DRAW_TRIANGLELIST  | DRAW_INDEXED32,

-		DRAW_INDEXEDTRIANGLESTRIP32 = DRAW_TRIANGLESTRIP | DRAW_INDEXED32,

-		DRAW_INDEXEDTRIANGLEFAN32   = DRAW_TRIANGLEFAN   | DRAW_INDEXED32,

-

-		DRAW_LAST = DRAW_INDEXEDTRIANGLEFAN32

-	};

-

-	enum FillMode : unsigned int

-	{

-		FILL_SOLID,

-		FILL_WIREFRAME,

-		FILL_VERTEX,

-

-		FILL_LAST = FILL_VERTEX

-	};

-

-	enum ShadingMode : unsigned int

-	{

-		SHADING_FLAT,

-		SHADING_GOURAUD,

-

-		SHADING_LAST = SHADING_GOURAUD

-	};

-

-	enum DepthCompareMode : unsigned int

-	{

-		DEPTH_ALWAYS,

-		DEPTH_NEVER,

-		DEPTH_EQUAL,

-		DEPTH_NOTEQUAL,

-		DEPTH_LESS,

-		DEPTH_LESSEQUAL,

-		DEPTH_GREATER,

-		DEPTH_GREATEREQUAL,

-

-		DEPTH_LAST = DEPTH_GREATEREQUAL

-	};

-

-	enum StencilCompareMode : unsigned int

-	{

-		STENCIL_ALWAYS,

-		STENCIL_NEVER,

-		STENCIL_EQUAL,

-		STENCIL_NOTEQUAL,

-		STENCIL_LESS,

-		STENCIL_LESSEQUAL,

-		STENCIL_GREATER,

-		STENCIL_GREATEREQUAL,

-

-		STENCIL_LAST = STENCIL_GREATEREQUAL

-	};

-

-	enum StencilOperation : unsigned int

-	{

-		OPERATION_KEEP,

-		OPERATION_ZERO,

-		OPERATION_REPLACE,

-		OPERATION_INCRSAT,

-		OPERATION_DECRSAT,

-		OPERATION_INVERT,

-		OPERATION_INCR,

-		OPERATION_DECR,

-

-		OPERATION_LAST = OPERATION_DECR

-	};

-

-	enum AlphaCompareMode : unsigned int

-	{

-		ALPHA_ALWAYS,

-		ALPHA_NEVER,

-		ALPHA_EQUAL,

-		ALPHA_NOTEQUAL,

-		ALPHA_LESS,

-		ALPHA_LESSEQUAL,

-		ALPHA_GREATER,

-		ALPHA_GREATEREQUAL,

-

-		ALPHA_LAST = ALPHA_GREATEREQUAL

-	};

-

-	enum CullMode : unsigned int

-	{

-		CULL_NONE,

-		CULL_CLOCKWISE,

-		CULL_COUNTERCLOCKWISE,

-

-		CULL_LAST = CULL_COUNTERCLOCKWISE

-	};

-

-	enum BlendFactor : unsigned int

-	{

-		BLEND_ZERO,

-		BLEND_ONE,

-		BLEND_SOURCE,

-		BLEND_INVSOURCE,

-		BLEND_DEST,

-		BLEND_INVDEST,

-		BLEND_SOURCEALPHA,

-		BLEND_INVSOURCEALPHA,

-		BLEND_DESTALPHA,

-		BLEND_INVDESTALPHA,

-		BLEND_SRCALPHASAT,

-		BLEND_CONSTANT,

-		BLEND_INVCONSTANT,

-		BLEND_CONSTANTALPHA,

-		BLEND_INVCONSTANTALPHA,

-

-		BLEND_LAST = BLEND_INVCONSTANT

-	};

-

-	enum BlendOperation : unsigned int

-	{

-		BLENDOP_ADD,

-		BLENDOP_SUB,

-		BLENDOP_INVSUB,

-		BLENDOP_MIN,

-		BLENDOP_MAX,

-

-		BLENDOP_SOURCE,   // Copy source

-		BLENDOP_DEST,     // Copy dest

-		BLENDOP_NULL,     // Nullify result

-

-		BLENDOP_LAST = BLENDOP_NULL

-	};

-

-	enum LogicalOperation : unsigned int

-	{

-		LOGICALOP_CLEAR,

-		LOGICALOP_SET,

-		LOGICALOP_COPY,

-		LOGICALOP_COPY_INVERTED,

-		LOGICALOP_NOOP,

-		LOGICALOP_INVERT,

-		LOGICALOP_AND,

-		LOGICALOP_NAND,

-		LOGICALOP_OR,

-		LOGICALOP_NOR,

-		LOGICALOP_XOR,

-		LOGICALOP_EQUIV,

-		LOGICALOP_AND_REVERSE,

-		LOGICALOP_AND_INVERTED,

-		LOGICALOP_OR_REVERSE,

-		LOGICALOP_OR_INVERTED,

-

-		LOGICALOP_LAST = LOGICALOP_OR_INVERTED

-	};

-

-	enum MaterialSource : unsigned int

-	{

-		MATERIAL_MATERIAL,

-		MATERIAL_COLOR1,

-		MATERIAL_COLOR2,

-

-		MATERIAL_LAST = MATERIAL_COLOR2

-	};

-

-	enum FogMode : unsigned int

-	{

-		FOG_NONE,

-		FOG_LINEAR,

-		FOG_EXP,

-		FOG_EXP2,

-

-		FOG_LAST = FOG_EXP2

-	};

-

-	enum TexGen : unsigned int

-	{

-		TEXGEN_PASSTHRU,

-		TEXGEN_NORMAL,

-		TEXGEN_POSITION,

-		TEXGEN_REFLECTION,

-		TEXGEN_SPHEREMAP,

-		TEXGEN_NONE,

-

-		TEXGEN_LAST = TEXGEN_NONE

-	};

-

-	enum TransparencyAntialiasing : unsigned int

-	{

-		TRANSPARENCY_NONE,

-		TRANSPARENCY_ALPHA_TO_COVERAGE,

-

-		TRANSPARENCY_LAST = TRANSPARENCY_ALPHA_TO_COVERAGE

-	};

-

-	class Context

-	{

-	public:

-		Context();

-

-		~Context();

-

-		void *operator new(size_t bytes);

-		void operator delete(void *pointer, size_t bytes);

-

-		bool isDrawPoint(bool fillModeAware = false) const;

-		bool isDrawLine(bool fillModeAware = false) const;

-		bool isDrawTriangle(bool fillModeAware = false) const;

-

-		void init();

-

-		const float &exp2Bias();   // NOTE: Needs address for JIT

-

-		const Point &getLightPosition(int light);

-

-		void setGlobalMipmapBias(float bias);

-

-		// Set fixed-function vertex pipeline states

-		void setLightingEnable(bool lightingEnable);

-		void setSpecularEnable(bool specularEnable);

-		void setLightEnable(int light, bool lightEnable);

-		void setLightPosition(int light, Point worldLightPosition);

-

-		void setColorVertexEnable(bool colorVertexEnable);

-		void setAmbientMaterialSource(MaterialSource ambientMaterialSource);

-		void setDiffuseMaterialSource(MaterialSource diffuseMaterialSource);

-		void setSpecularMaterialSource(MaterialSource specularMaterialSource);

-		void setEmissiveMaterialSource(MaterialSource emissiveMaterialSource);

-

-		void setPointSpriteEnable(bool pointSpriteEnable);

-		void setPointScaleEnable(bool pointScaleEnable);

-

-		// Set fixed-function pixel pipeline states, return true when modified

-		bool setDepthBufferEnable(bool depthBufferEnable);

-

-		bool setAlphaBlendEnable(bool alphaBlendEnable);

-		bool setSourceBlendFactor(BlendFactor sourceBlendFactor);

-		bool setDestBlendFactor(BlendFactor destBlendFactor);

-		bool setBlendOperation(BlendOperation blendOperation);

-

-		bool setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable);

-		bool setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha);

-		bool setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha);

-		bool setBlendOperationAlpha(BlendOperation blendOperationAlpha);

-

-		bool setColorWriteMask(int index, int colorWriteMask);

-		bool setWriteSRGB(bool sRGB);

-

-		bool setColorLogicOpEnabled(bool colorLogicOpEnabled);

-		bool setLogicalOperation(LogicalOperation logicalOperation);

-

-		// Active fixed-function pixel pipeline states

-		bool fogActive();

-		bool pointSizeActive();

-		FogMode pixelFogActive();

-		bool depthWriteActive();

-		bool alphaTestActive();

-		bool depthBufferActive();

-		bool stencilActive();

-

-		bool perspectiveActive();

-

-		// Active fixed-function vertex pipeline states

-		bool vertexLightingActive();

-		bool texCoordActive(int coordinate, int component);

-		bool texCoordActive(int coordinate);

-		bool isProjectionComponent(unsigned int coordinate, int component);

-		bool vertexSpecularInputActive();

-		bool vertexSpecularActive();

-		bool vertexNormalActive();

-		bool vertexLightActive();

-		bool vertexLightActive(int i);

-		MaterialSource vertexDiffuseMaterialSourceActive();

-		MaterialSource vertexSpecularMaterialSourceActive();

-		MaterialSource vertexAmbientMaterialSourceActive();

-		MaterialSource vertexEmissiveMaterialSourceActive();

-

-		bool pointSpriteActive();

-		bool pointScaleActive();

-

-		bool alphaBlendActive();

-		BlendFactor sourceBlendFactor();

-		BlendFactor destBlendFactor();

-		BlendOperation blendOperation();

-

-		BlendFactor sourceBlendFactorAlpha();

-		BlendFactor destBlendFactorAlpha();

-		BlendOperation blendOperationAlpha();

-

-		LogicalOperation colorLogicOp();

-		LogicalOperation indexLogicOp();

-

-		bool indexedVertexBlendActive();

-		int vertexBlendMatrixCountActive();

-		bool localViewerActive();

-		bool normalizeNormalsActive();

-		FogMode vertexFogModeActive();

-		bool rangeFogActive();

-

-		TexGen texGenActive(int stage);

-		int textureTransformCountActive(int stage);

-		int texCoordIndexActive(int stage);

-

-		// Active context states

-		bool diffuseUsed();     // Used by pixel processor but not provided by vertex processor

-		bool diffuseUsed(int component);     // Used by pixel processor but not provided by vertex processor

-		bool diffuseActive();

-		bool diffuseActive(int component);

-		bool specularUsed();

-		bool specularUsed(int component);

-		bool specularActive();

-		bool specularActive(int component);

-		bool colorActive(int color, int component);

-		bool textureActive();

-		bool textureActive(int coordinate);

-		bool textureActive(int coordinate, int component);

-

-		unsigned short pixelShaderVersion() const;

-		unsigned short vertexShaderVersion() const;

-

-		int getMultiSampleCount() const;

-		int getSuperSampleCount() const;

-

-		DrawType drawType;

-

-		bool stencilEnable;

-		StencilCompareMode stencilCompareMode;

-		int stencilReference;

-		int stencilMask;

-		StencilOperation stencilFailOperation;

-		StencilOperation stencilPassOperation;

-		StencilOperation stencilZFailOperation;

-		int stencilWriteMask;

-

-		bool twoSidedStencil;

-		StencilCompareMode stencilCompareModeCCW;

-		int stencilReferenceCCW;

-		int stencilMaskCCW;

-		StencilOperation stencilFailOperationCCW;

-		StencilOperation stencilPassOperationCCW;

-		StencilOperation stencilZFailOperationCCW;

-		int stencilWriteMaskCCW;

-

-		// Pixel processor states

-		AlphaCompareMode alphaCompareMode;

-		bool alphaTestEnable;

-		FillMode fillMode;

-		ShadingMode shadingMode;

-

-		CullMode cullMode;

-		float alphaReference;

-

-		TextureStage textureStage[8];

-		Sampler sampler[TOTAL_IMAGE_UNITS];

-

-		Format renderTargetInternalFormat(int index);

-		int colorWriteActive();

-		int colorWriteActive(int index);

-		bool colorUsed();

-

-		Resource *texture[TOTAL_IMAGE_UNITS];

-		Stream input[VERTEX_ATTRIBUTES];

-		Resource *indexBuffer;

-

-		bool preTransformed;   // FIXME: Private

-

-		float fogStart;

-		float fogEnd;

-

-		void computeIllumination();

-

-		bool textureWrapActive;

-		unsigned char textureWrap[TEXTURE_IMAGE_UNITS];

-		TexGen texGen[8];

-		bool localViewer;

-		bool normalizeNormals;

-		int textureTransformCount[8];

-		bool textureTransformProject[8];

-

-		Surface *renderTarget[RENDERTARGETS];

-		Surface *depthBuffer;

-		Surface *stencilBuffer;

-

-		// Fog

-		bool fogEnable;

-		FogMode pixelFogMode;

-		FogMode vertexFogMode;

-		bool wBasedFog;

-		bool rangeFogEnable;

-

-		// Vertex blending

-		bool indexedVertexBlendEnable;

-		int vertexBlendMatrixCount;

-

-		// Shaders

-		const PixelShader *pixelShader;

-		const VertexShader *vertexShader;

-

-		// Global mipmap bias

-		float bias;

-

-		// Instancing

-		int instanceID;

-

-		// Fixed-function vertex pipeline state

-		bool lightingEnable;

-		bool specularEnable;

-		bool lightEnable[8];

-		Point worldLightPosition[8];

-

-		MaterialSource ambientMaterialSource;

-		MaterialSource diffuseMaterialSource;

-		MaterialSource specularMaterialSource;

-		MaterialSource emissiveMaterialSource;

-		bool colorVertexEnable;

-

-		bool occlusionEnabled;

-		bool transformFeedbackQueryEnabled;

-		uint64_t transformFeedbackEnabled;

-

-		// Pixel processor states

-		bool rasterizerDiscard;

-		bool depthBufferEnable;

-		DepthCompareMode depthCompareMode;

-		bool depthWriteEnable;

-

-		bool alphaBlendEnable;

-		BlendFactor sourceBlendFactorState;

-		BlendFactor destBlendFactorState;

-		BlendOperation blendOperationState;

-

-		bool separateAlphaBlendEnable;

-		BlendFactor sourceBlendFactorStateAlpha;

-		BlendFactor destBlendFactorStateAlpha;

-		BlendOperation blendOperationStateAlpha;

-

-		bool pointSpriteEnable;

-		bool pointScaleEnable;

-		float lineWidth;

-

-		int colorWriteMask[RENDERTARGETS];   // RGBA

-		bool writeSRGB;

-		unsigned int sampleMask;

-		unsigned int multiSampleMask;

-

-		bool colorLogicOpEnabled;

-		LogicalOperation logicalOperation;

-	};

-}

-

-#endif   // sw_Context_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Context_hpp
+#define sw_Context_hpp
+
+#include "Sampler.hpp"
+#include "TextureStage.hpp"
+#include "Stream.hpp"
+#include "Point.hpp"
+#include "Vertex.hpp"
+
+namespace sw
+{
+	class Sampler;
+	class Surface;
+	class PixelShader;
+	class VertexShader;
+	struct Triangle;
+	struct Primitive;
+	struct Vertex;
+	class Resource;
+
+	enum In   // Default input stream semantic
+	{
+		Position = 0,
+		BlendWeight = 1,
+		BlendIndices = 2,
+		Normal = 3,
+		PointSize = 4,
+		Color0 = 5,
+		Color1 = 6,
+		TexCoord0 = 7,
+		TexCoord1 = 8,
+		TexCoord2 = 9,
+		TexCoord3 = 10,
+		TexCoord4 = 11,
+		TexCoord5 = 12,
+		TexCoord6 = 13,
+		TexCoord7 = 14,
+		PositionT = 15
+	};
+
+	enum DrawType : unsigned int
+	{
+		// These types must stay ordered by vertices per primitive. Also, if these basic types
+		// are modified, verify the value assigned to task->verticesPerPrimitive in Renderer.cpp
+		DRAW_POINTLIST     = 0x00,
+		DRAW_LINELIST      = 0x01,
+		DRAW_LINESTRIP     = 0x02,
+		DRAW_LINELOOP      = 0x03,
+		DRAW_TRIANGLELIST  = 0x04,
+		DRAW_TRIANGLESTRIP = 0x05,
+		DRAW_TRIANGLEFAN   = 0x06,
+		DRAW_QUADLIST      = 0x07,
+
+		DRAW_NONINDEXED = 0x00,
+		DRAW_INDEXED8   = 0x10,
+		DRAW_INDEXED16  = 0x20,
+		DRAW_INDEXED32  = 0x30,
+
+		DRAW_INDEXEDPOINTLIST8 = DRAW_POINTLIST | DRAW_INDEXED8,
+		DRAW_INDEXEDLINELIST8  = DRAW_LINELIST  | DRAW_INDEXED8,
+		DRAW_INDEXEDLINESTRIP8 = DRAW_LINESTRIP | DRAW_INDEXED8,
+		DRAW_INDEXEDLINELOOP8  = DRAW_LINELOOP  | DRAW_INDEXED8,
+		DRAW_INDEXEDTRIANGLELIST8  = DRAW_TRIANGLELIST  | DRAW_INDEXED8,
+		DRAW_INDEXEDTRIANGLESTRIP8 = DRAW_TRIANGLESTRIP | DRAW_INDEXED8,
+		DRAW_INDEXEDTRIANGLEFAN8   = DRAW_TRIANGLEFAN   | DRAW_INDEXED8,
+
+		DRAW_INDEXEDPOINTLIST16 = DRAW_POINTLIST | DRAW_INDEXED16,
+		DRAW_INDEXEDLINELIST16  = DRAW_LINELIST  | DRAW_INDEXED16,
+		DRAW_INDEXEDLINESTRIP16 = DRAW_LINESTRIP | DRAW_INDEXED16,
+		DRAW_INDEXEDLINELOOP16  = DRAW_LINELOOP  | DRAW_INDEXED16,
+		DRAW_INDEXEDTRIANGLELIST16  = DRAW_TRIANGLELIST  | DRAW_INDEXED16,
+		DRAW_INDEXEDTRIANGLESTRIP16 = DRAW_TRIANGLESTRIP | DRAW_INDEXED16,
+		DRAW_INDEXEDTRIANGLEFAN16   = DRAW_TRIANGLEFAN   | DRAW_INDEXED16,
+
+		DRAW_INDEXEDPOINTLIST32 = DRAW_POINTLIST | DRAW_INDEXED32,
+		DRAW_INDEXEDLINELIST32  = DRAW_LINELIST  | DRAW_INDEXED32,
+		DRAW_INDEXEDLINESTRIP32 = DRAW_LINESTRIP | DRAW_INDEXED32,
+		DRAW_INDEXEDLINELOOP32  = DRAW_LINELOOP  | DRAW_INDEXED32,
+		DRAW_INDEXEDTRIANGLELIST32  = DRAW_TRIANGLELIST  | DRAW_INDEXED32,
+		DRAW_INDEXEDTRIANGLESTRIP32 = DRAW_TRIANGLESTRIP | DRAW_INDEXED32,
+		DRAW_INDEXEDTRIANGLEFAN32   = DRAW_TRIANGLEFAN   | DRAW_INDEXED32,
+
+		DRAW_LAST = DRAW_INDEXEDTRIANGLEFAN32
+	};
+
+	enum FillMode : unsigned int
+	{
+		FILL_SOLID,
+		FILL_WIREFRAME,
+		FILL_VERTEX,
+
+		FILL_LAST = FILL_VERTEX
+	};
+
+	enum ShadingMode : unsigned int
+	{
+		SHADING_FLAT,
+		SHADING_GOURAUD,
+
+		SHADING_LAST = SHADING_GOURAUD
+	};
+
+	enum DepthCompareMode : unsigned int
+	{
+		DEPTH_ALWAYS,
+		DEPTH_NEVER,
+		DEPTH_EQUAL,
+		DEPTH_NOTEQUAL,
+		DEPTH_LESS,
+		DEPTH_LESSEQUAL,
+		DEPTH_GREATER,
+		DEPTH_GREATEREQUAL,
+
+		DEPTH_LAST = DEPTH_GREATEREQUAL
+	};
+
+	enum StencilCompareMode : unsigned int
+	{
+		STENCIL_ALWAYS,
+		STENCIL_NEVER,
+		STENCIL_EQUAL,
+		STENCIL_NOTEQUAL,
+		STENCIL_LESS,
+		STENCIL_LESSEQUAL,
+		STENCIL_GREATER,
+		STENCIL_GREATEREQUAL,
+
+		STENCIL_LAST = STENCIL_GREATEREQUAL
+	};
+
+	enum StencilOperation : unsigned int
+	{
+		OPERATION_KEEP,
+		OPERATION_ZERO,
+		OPERATION_REPLACE,
+		OPERATION_INCRSAT,
+		OPERATION_DECRSAT,
+		OPERATION_INVERT,
+		OPERATION_INCR,
+		OPERATION_DECR,
+
+		OPERATION_LAST = OPERATION_DECR
+	};
+
+	enum AlphaCompareMode : unsigned int
+	{
+		ALPHA_ALWAYS,
+		ALPHA_NEVER,
+		ALPHA_EQUAL,
+		ALPHA_NOTEQUAL,
+		ALPHA_LESS,
+		ALPHA_LESSEQUAL,
+		ALPHA_GREATER,
+		ALPHA_GREATEREQUAL,
+
+		ALPHA_LAST = ALPHA_GREATEREQUAL
+	};
+
+	enum CullMode : unsigned int
+	{
+		CULL_NONE,
+		CULL_CLOCKWISE,
+		CULL_COUNTERCLOCKWISE,
+
+		CULL_LAST = CULL_COUNTERCLOCKWISE
+	};
+
+	enum BlendFactor : unsigned int
+	{
+		BLEND_ZERO,
+		BLEND_ONE,
+		BLEND_SOURCE,
+		BLEND_INVSOURCE,
+		BLEND_DEST,
+		BLEND_INVDEST,
+		BLEND_SOURCEALPHA,
+		BLEND_INVSOURCEALPHA,
+		BLEND_DESTALPHA,
+		BLEND_INVDESTALPHA,
+		BLEND_SRCALPHASAT,
+		BLEND_CONSTANT,
+		BLEND_INVCONSTANT,
+		BLEND_CONSTANTALPHA,
+		BLEND_INVCONSTANTALPHA,
+
+		BLEND_LAST = BLEND_INVCONSTANT
+	};
+
+	enum BlendOperation : unsigned int
+	{
+		BLENDOP_ADD,
+		BLENDOP_SUB,
+		BLENDOP_INVSUB,
+		BLENDOP_MIN,
+		BLENDOP_MAX,
+
+		BLENDOP_SOURCE,   // Copy source
+		BLENDOP_DEST,     // Copy dest
+		BLENDOP_NULL,     // Nullify result
+
+		BLENDOP_LAST = BLENDOP_NULL
+	};
+
+	enum LogicalOperation : unsigned int
+	{
+		LOGICALOP_CLEAR,
+		LOGICALOP_SET,
+		LOGICALOP_COPY,
+		LOGICALOP_COPY_INVERTED,
+		LOGICALOP_NOOP,
+		LOGICALOP_INVERT,
+		LOGICALOP_AND,
+		LOGICALOP_NAND,
+		LOGICALOP_OR,
+		LOGICALOP_NOR,
+		LOGICALOP_XOR,
+		LOGICALOP_EQUIV,
+		LOGICALOP_AND_REVERSE,
+		LOGICALOP_AND_INVERTED,
+		LOGICALOP_OR_REVERSE,
+		LOGICALOP_OR_INVERTED,
+
+		LOGICALOP_LAST = LOGICALOP_OR_INVERTED
+	};
+
+	enum MaterialSource : unsigned int
+	{
+		MATERIAL_MATERIAL,
+		MATERIAL_COLOR1,
+		MATERIAL_COLOR2,
+
+		MATERIAL_LAST = MATERIAL_COLOR2
+	};
+
+	enum FogMode : unsigned int
+	{
+		FOG_NONE,
+		FOG_LINEAR,
+		FOG_EXP,
+		FOG_EXP2,
+
+		FOG_LAST = FOG_EXP2
+	};
+
+	enum TexGen : unsigned int
+	{
+		TEXGEN_PASSTHRU,
+		TEXGEN_NORMAL,
+		TEXGEN_POSITION,
+		TEXGEN_REFLECTION,
+		TEXGEN_SPHEREMAP,
+		TEXGEN_NONE,
+
+		TEXGEN_LAST = TEXGEN_NONE
+	};
+
+	enum TransparencyAntialiasing : unsigned int
+	{
+		TRANSPARENCY_NONE,
+		TRANSPARENCY_ALPHA_TO_COVERAGE,
+
+		TRANSPARENCY_LAST = TRANSPARENCY_ALPHA_TO_COVERAGE
+	};
+
+	class Context
+	{
+	public:
+		Context();
+
+		~Context();
+
+		void *operator new(size_t bytes);
+		void operator delete(void *pointer, size_t bytes);
+
+		bool isDrawPoint(bool fillModeAware = false) const;
+		bool isDrawLine(bool fillModeAware = false) const;
+		bool isDrawTriangle(bool fillModeAware = false) const;
+
+		void init();
+
+		const float &exp2Bias();   // NOTE: Needs address for JIT
+
+		const Point &getLightPosition(int light);
+
+		void setGlobalMipmapBias(float bias);
+
+		// Set fixed-function vertex pipeline states
+		void setLightingEnable(bool lightingEnable);
+		void setSpecularEnable(bool specularEnable);
+		void setLightEnable(int light, bool lightEnable);
+		void setLightPosition(int light, Point worldLightPosition);
+
+		void setColorVertexEnable(bool colorVertexEnable);
+		void setAmbientMaterialSource(MaterialSource ambientMaterialSource);
+		void setDiffuseMaterialSource(MaterialSource diffuseMaterialSource);
+		void setSpecularMaterialSource(MaterialSource specularMaterialSource);
+		void setEmissiveMaterialSource(MaterialSource emissiveMaterialSource);
+
+		void setPointSpriteEnable(bool pointSpriteEnable);
+		void setPointScaleEnable(bool pointScaleEnable);
+
+		// Set fixed-function pixel pipeline states, return true when modified
+		bool setDepthBufferEnable(bool depthBufferEnable);
+
+		bool setAlphaBlendEnable(bool alphaBlendEnable);
+		bool setSourceBlendFactor(BlendFactor sourceBlendFactor);
+		bool setDestBlendFactor(BlendFactor destBlendFactor);
+		bool setBlendOperation(BlendOperation blendOperation);
+
+		bool setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable);
+		bool setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha);
+		bool setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha);
+		bool setBlendOperationAlpha(BlendOperation blendOperationAlpha);
+
+		bool setColorWriteMask(int index, int colorWriteMask);
+		bool setWriteSRGB(bool sRGB);
+
+		bool setColorLogicOpEnabled(bool colorLogicOpEnabled);
+		bool setLogicalOperation(LogicalOperation logicalOperation);
+
+		// Active fixed-function pixel pipeline states
+		bool fogActive();
+		bool pointSizeActive();
+		FogMode pixelFogActive();
+		bool depthWriteActive();
+		bool alphaTestActive();
+		bool depthBufferActive();
+		bool stencilActive();
+
+		bool perspectiveActive();
+
+		// Active fixed-function vertex pipeline states
+		bool vertexLightingActive();
+		bool texCoordActive(int coordinate, int component);
+		bool texCoordActive(int coordinate);
+		bool isProjectionComponent(unsigned int coordinate, int component);
+		bool vertexSpecularInputActive();
+		bool vertexSpecularActive();
+		bool vertexNormalActive();
+		bool vertexLightActive();
+		bool vertexLightActive(int i);
+		MaterialSource vertexDiffuseMaterialSourceActive();
+		MaterialSource vertexSpecularMaterialSourceActive();
+		MaterialSource vertexAmbientMaterialSourceActive();
+		MaterialSource vertexEmissiveMaterialSourceActive();
+
+		bool pointSpriteActive();
+		bool pointScaleActive();
+
+		bool alphaBlendActive();
+		BlendFactor sourceBlendFactor();
+		BlendFactor destBlendFactor();
+		BlendOperation blendOperation();
+
+		BlendFactor sourceBlendFactorAlpha();
+		BlendFactor destBlendFactorAlpha();
+		BlendOperation blendOperationAlpha();
+
+		LogicalOperation colorLogicOp();
+		LogicalOperation indexLogicOp();
+
+		bool indexedVertexBlendActive();
+		int vertexBlendMatrixCountActive();
+		bool localViewerActive();
+		bool normalizeNormalsActive();
+		FogMode vertexFogModeActive();
+		bool rangeFogActive();
+
+		TexGen texGenActive(int stage);
+		int textureTransformCountActive(int stage);
+		int texCoordIndexActive(int stage);
+
+		// Active context states
+		bool diffuseUsed();     // Used by pixel processor but not provided by vertex processor
+		bool diffuseUsed(int component);     // Used by pixel processor but not provided by vertex processor
+		bool diffuseActive();
+		bool diffuseActive(int component);
+		bool specularUsed();
+		bool specularUsed(int component);
+		bool specularActive();
+		bool specularActive(int component);
+		bool colorActive(int color, int component);
+		bool textureActive();
+		bool textureActive(int coordinate);
+		bool textureActive(int coordinate, int component);
+
+		unsigned short pixelShaderVersion() const;
+		unsigned short vertexShaderVersion() const;
+
+		int getMultiSampleCount() const;
+		int getSuperSampleCount() const;
+
+		DrawType drawType;
+
+		bool stencilEnable;
+		StencilCompareMode stencilCompareMode;
+		int stencilReference;
+		int stencilMask;
+		StencilOperation stencilFailOperation;
+		StencilOperation stencilPassOperation;
+		StencilOperation stencilZFailOperation;
+		int stencilWriteMask;
+
+		bool twoSidedStencil;
+		StencilCompareMode stencilCompareModeCCW;
+		int stencilReferenceCCW;
+		int stencilMaskCCW;
+		StencilOperation stencilFailOperationCCW;
+		StencilOperation stencilPassOperationCCW;
+		StencilOperation stencilZFailOperationCCW;
+		int stencilWriteMaskCCW;
+
+		// Pixel processor states
+		AlphaCompareMode alphaCompareMode;
+		bool alphaTestEnable;
+		FillMode fillMode;
+		ShadingMode shadingMode;
+
+		CullMode cullMode;
+		float alphaReference;
+
+		TextureStage textureStage[8];
+		Sampler sampler[TOTAL_IMAGE_UNITS];
+
+		Format renderTargetInternalFormat(int index);
+		int colorWriteActive();
+		int colorWriteActive(int index);
+		bool colorUsed();
+
+		Resource *texture[TOTAL_IMAGE_UNITS];
+		Stream input[VERTEX_ATTRIBUTES];
+		Resource *indexBuffer;
+
+		bool preTransformed;   // FIXME: Private
+
+		float fogStart;
+		float fogEnd;
+
+		void computeIllumination();
+
+		bool textureWrapActive;
+		unsigned char textureWrap[TEXTURE_IMAGE_UNITS];
+		TexGen texGen[8];
+		bool localViewer;
+		bool normalizeNormals;
+		int textureTransformCount[8];
+		bool textureTransformProject[8];
+
+		Surface *renderTarget[RENDERTARGETS];
+		Surface *depthBuffer;
+		Surface *stencilBuffer;
+
+		// Fog
+		bool fogEnable;
+		FogMode pixelFogMode;
+		FogMode vertexFogMode;
+		bool wBasedFog;
+		bool rangeFogEnable;
+
+		// Vertex blending
+		bool indexedVertexBlendEnable;
+		int vertexBlendMatrixCount;
+
+		// Shaders
+		const PixelShader *pixelShader;
+		const VertexShader *vertexShader;
+
+		// Global mipmap bias
+		float bias;
+
+		// Instancing
+		int instanceID;
+
+		// Fixed-function vertex pipeline state
+		bool lightingEnable;
+		bool specularEnable;
+		bool lightEnable[8];
+		Point worldLightPosition[8];
+
+		MaterialSource ambientMaterialSource;
+		MaterialSource diffuseMaterialSource;
+		MaterialSource specularMaterialSource;
+		MaterialSource emissiveMaterialSource;
+		bool colorVertexEnable;
+
+		bool occlusionEnabled;
+		bool transformFeedbackQueryEnabled;
+		uint64_t transformFeedbackEnabled;
+
+		// Pixel processor states
+		bool rasterizerDiscard;
+		bool depthBufferEnable;
+		DepthCompareMode depthCompareMode;
+		bool depthWriteEnable;
+
+		bool alphaBlendEnable;
+		BlendFactor sourceBlendFactorState;
+		BlendFactor destBlendFactorState;
+		BlendOperation blendOperationState;
+
+		bool separateAlphaBlendEnable;
+		BlendFactor sourceBlendFactorStateAlpha;
+		BlendFactor destBlendFactorStateAlpha;
+		BlendOperation blendOperationStateAlpha;
+
+		bool pointSpriteEnable;
+		bool pointScaleEnable;
+		float lineWidth;
+
+		int colorWriteMask[RENDERTARGETS];   // RGBA
+		bool writeSRGB;
+		unsigned int sampleMask;
+		unsigned int multiSampleMask;
+
+		bool colorLogicOpEnabled;
+		LogicalOperation logicalOperation;
+	};
+}
+
+#endif   // sw_Context_hpp
diff --git a/src/Renderer/ETC_Decoder.cpp b/src/Renderer/ETC_Decoder.cpp
index 6d98aa2..8e109f3 100644
--- a/src/Renderer/ETC_Decoder.cpp
+++ b/src/Renderer/ETC_Decoder.cpp
@@ -1,709 +1,712 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google 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 "ETC_Decoder.hpp"

-

-namespace

-{

-	inline int clampByte(int value)

-	{

-		return (value < 0) ? 0 : ((value > 255) ? 255 : value);

-	}

-

-	inline int clampSByte(int value)

-	{

-		return (value < -128) ? -128 : ((value > 127) ? 127 : value);

-	}

-

-	struct bgra8

-	{

-		unsigned char b;

-		unsigned char g;

-		unsigned char r;

-		unsigned char a;

-

-		inline bgra8()

-		{

-		}

-

-		inline void set(int red, int green, int blue)

-		{

-			r = static_cast<unsigned char>(clampByte(red));

-			g = static_cast<unsigned char>(clampByte(green));

-			b = static_cast<unsigned char>(clampByte(blue));

-		}

-

-		inline void set(int red, int green, int blue, int alpha)

-		{

-			r = static_cast<unsigned char>(clampByte(red));

-			g = static_cast<unsigned char>(clampByte(green));

-			b = static_cast<unsigned char>(clampByte(blue));

-			a = static_cast<unsigned char>(clampByte(alpha));

-		}

-

-		const bgra8& addA(int alpha)

-		{

-			a = alpha;

-			return *this;

-		}

-	};

-

-	inline int extend_4to8bits(int x)

-	{

-		return (x << 4) | x;

-	}

-

-	inline int extend_5to8bits(int x)

-	{

-		return (x << 3) | (x >> 2);

-	}

-

-	inline int extend_6to8bits(int x)

-	{

-		return (x << 2) | (x >> 4);

-	}

-

-	inline int extend_7to8bits(int x)

-	{

-		return (x << 1) | (x >> 6);

-	}

-

-	struct ETC2

-	{

-		// Decodes unsigned single or dual channel block to bytes

-		static void DecodeBlock(const ETC2** sources, unsigned char *dest, int nbChannels, int x, int y, int w, int h, int pitch, bool isSigned)

-		{

-			if(isSigned)

-			{

-				signed char* sDst = reinterpret_cast<signed char*>(dest);

-				for(int j = 0; j < 4 && (y + j) < h; j++)

-				{

-					for(int i = 0; i < 4 && (x + i) < w; i++)

-					{

-						for(int c = nbChannels - 1; c >= 0; c--)

-						{

-							sDst[i * nbChannels + c] = clampSByte(sources[c]->getSingleChannel(i, j, isSigned));

-						}

-					}

-					sDst += pitch;

-				}

-			}

-			else

-			{

-				for(int j = 0; j < 4 && (y + j) < h; j++)

-				{

-					for(int i = 0; i < 4 && (x + i) < w; i++)

-					{

-						for(int c = nbChannels - 1; c >= 0; c--)

-						{

-							dest[i * nbChannels + c] = clampByte(sources[c]->getSingleChannel(i, j, isSigned));

-						}

-					}

-					dest += pitch;

-				}

-			}

-		}

-

-		// Decodes RGB block to bgra8

-		void decodeBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool punchThroughAlpha) const

-		{

-			bool opaqueBit = diffbit;

-			bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit;

-

-			// Select mode

-			if(diffbit || punchThroughAlpha)

-			{

-				int r = (R + dR);

-				int g = (G + dG);

-				int b = (B + dB);

-				if(r < 0 || r > 31)

-				{

-					decodeTBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);

-				}

-				else if(g < 0 || g > 31)

-				{

-					decodeHBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);

-				}

-				else if(b < 0 || b > 31)

-				{

-					decodePlanarBlock(dest, x, y, w, h, pitch, alphaValues);

-				}

-				else

-				{

-					decodeDifferentialBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);

-				}

-			}

-			else

-			{

-				decodeIndividualBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);

-			}

-		}

-

-	private:

-		struct

-		{

-			union

-			{

-				// Individual, differential, H and T modes

-				struct

-				{

-					union

-					{

-						// Individual and differential modes

-						struct

-						{

-							union

-							{

-								struct   // Individual colors

-								{

-									unsigned char R2 : 4;

-									unsigned char R1 : 4;

-									unsigned char G2 : 4;

-									unsigned char G1 : 4;

-									unsigned char B2 : 4;

-									unsigned char B1 : 4;

-								};

-

-								struct   // Differential colors

-								{

-									signed char dR : 3;

-									unsigned char R : 5;

-									signed char dG : 3;

-									unsigned char G : 5;

-									signed char dB : 3;

-									unsigned char B : 5;

-								};

-							};

-

-							bool flipbit : 1;

-							bool diffbit : 1;

-							unsigned char cw2 : 3;

-							unsigned char cw1 : 3;

-						};

-

-						// T mode

-						struct

-						{

-							// Byte 1

-							unsigned char TR1b : 2;

-							unsigned char TdummyB : 1;

-							unsigned char TR1a : 2;

-							unsigned char TdummyA : 3;

-

-							// Byte 2

-							unsigned char TB1 : 4;

-							unsigned char TG1 : 4;

-

-							// Byte 3

-							unsigned char TG2 : 4;

-							unsigned char TR2 : 4;

-

-							// Byte 4

-							unsigned char Tdb : 1;

-							bool Tflipbit : 1;

-							unsigned char Tda : 2;

-							unsigned char TB2 : 4;

-						};

-

-						// H mode

-						struct

-						{

-							// Byte 1

-							unsigned char HG1a : 3;

-							unsigned char HR1 : 4;

-							unsigned char HdummyA : 1;

-

-							// Byte 2

-							unsigned char HB1b : 2;

-							unsigned char HdummyC : 1;

-							unsigned char HB1a : 1;

-							unsigned char HG1b : 1;

-							unsigned char HdummyB : 3;

-

-							// Byte 3

-							unsigned char HG2a : 3;

-							unsigned char HR2 : 4;

-							unsigned char HB1c : 1;

-

-							// Byte 4

-							unsigned char Hdb : 1;

-							bool Hflipbit : 1;

-							unsigned char Hda : 1;

-							unsigned char HB2 : 4;

-							unsigned char HG2b : 1;

-						};

-					};

-

-					unsigned char pixelIndexMSB[2];

-					unsigned char pixelIndexLSB[2];

-				};

-

-				// planar mode

-				struct

-				{

-					// Byte 1

-					unsigned char GO1 : 1;

-					unsigned char RO : 6;

-					unsigned char PdummyA : 1;

-

-					// Byte 2

-					unsigned char BO1 : 1;

-					unsigned char GO2 : 6;

-					unsigned char PdummyB : 1;

-

-					// Byte 3

-					unsigned char BO3a : 2;

-					unsigned char PdummyD : 1;

-					unsigned char BO2 : 2;

-					unsigned char PdummyC : 3;

-

-					// Byte 4

-					unsigned char RH2 : 1;

-					bool Pflipbit : 1;

-					unsigned char RH1 : 5;

-					unsigned char BO3b : 1;

-

-					// Byte 5

-					unsigned char BHa : 1;

-					unsigned char GH : 7;

-

-					// Byte 6

-					unsigned char RVa : 3;

-					unsigned char BHb : 5;

-

-					// Byte 7

-					unsigned char GVa : 5;

-					unsigned char RVb : 3;

-

-					// Byte 8

-					unsigned char BV : 6;

-					unsigned char GVb : 2;

-				};

-

-				// Single channel block

-				struct

-				{

-					union

-					{

-						unsigned char base_codeword;

-						signed char signed_base_codeword;

-					};

-

-					unsigned char table_index : 4;

-					unsigned char multiplier : 4;

-

-					unsigned char mc1 : 2;

-					unsigned char mb : 3;

-					unsigned char ma : 3;

-

-					unsigned char mf1 : 1;

-					unsigned char me : 3;

-					unsigned char md : 3;

-					unsigned char mc2 : 1;

-

-					unsigned char mh : 3;

-					unsigned char mg : 3;

-					unsigned char mf2 : 2;

-

-					unsigned char mk1 : 2;

-					unsigned char mj : 3;

-					unsigned char mi : 3;

-

-					unsigned char mn1 : 1;

-					unsigned char mm : 3;

-					unsigned char ml : 3;

-					unsigned char mk2 : 1;

-

-					unsigned char mp : 3;

-					unsigned char mo : 3;

-					unsigned char mn2 : 2;

-				};

-			};

-		};

-

-		void decodeIndividualBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const

-		{

-			int r1 = extend_4to8bits(R1);

-			int g1 = extend_4to8bits(G1);

-			int b1 = extend_4to8bits(B1);

-

-			int r2 = extend_4to8bits(R2);

-			int g2 = extend_4to8bits(G2);

-			int b2 = extend_4to8bits(B2);

-

-			decodeIndividualOrDifferentialBlock(dest, x, y, w, h, pitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha);

-		}

-

-		void decodeDifferentialBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const

-		{

-			int b1 = extend_5to8bits(B);

-			int g1 = extend_5to8bits(G);

-			int r1 = extend_5to8bits(R);

-

-			int r2 = extend_5to8bits(R + dR);

-			int g2 = extend_5to8bits(G + dG);

-			int b2 = extend_5to8bits(B + dB);

-

-			decodeIndividualOrDifferentialBlock(dest, x, y, w, h, pitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha);

-		}

-

-		void decodeIndividualOrDifferentialBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, int r1, int g1, int b1, int r2, int g2, int b2, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const

-		{

-			// Table 3.17.2 sorted according to table 3.17.3

-			static const int intensityModifierDefault[8][4] =

-			{

-				{ 2, 8, -2, -8 },

-				{ 5, 17, -5, -17 },

-				{ 9, 29, -9, -29 },

-				{ 13, 42, -13, -42 },

-				{ 18, 60, -18, -60 },

-				{ 24, 80, -24, -80 },

-				{ 33, 106, -33, -106 },

-				{ 47, 183, -47, -183 }

-			};

-

-			// Table C.12, intensity modifier for non opaque punchthrough alpha

-			static const int intensityModifierNonOpaque[8][4] =

-			{

-				{ 0, 8, 0, -8 },

-				{ 0, 17, 0, -17 },

-				{ 0, 29, 0, -29 },

-				{ 0, 42, 0, -42 },

-				{ 0, 60, 0, -60 },

-				{ 0, 80, 0, -80 },

-				{ 0, 106, 0, -106 },

-				{ 0, 183, 0, -183 }

-			};

-

-			const int(&intensityModifier)[8][4] = nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;

-

-			bgra8 subblockColors0[4];

-			bgra8 subblockColors1[4];

-

-			const int i10 = intensityModifier[cw1][0];

-			const int i11 = intensityModifier[cw1][1];

-			const int i12 = intensityModifier[cw1][2];

-			const int i13 = intensityModifier[cw1][3];

-

-			subblockColors0[0].set(r1 + i10, g1 + i10, b1 + i10);

-			subblockColors0[1].set(r1 + i11, g1 + i11, b1 + i11);

-			subblockColors0[2].set(r1 + i12, g1 + i12, b1 + i12);

-			subblockColors0[3].set(r1 + i13, g1 + i13, b1 + i13);

-

-			const int i20 = intensityModifier[cw2][0];

-			const int i21 = intensityModifier[cw2][1];

-			const int i22 = intensityModifier[cw2][2];

-			const int i23 = intensityModifier[cw2][3];

-

-			subblockColors1[0].set(r2 + i20, g2 + i20, b2 + i20);

-			subblockColors1[1].set(r2 + i21, g2 + i21, b2 + i21);

-			subblockColors1[2].set(r2 + i22, g2 + i22, b2 + i22);

-			subblockColors1[3].set(r2 + i23, g2 + i23, b2 + i23);

-

-			unsigned char* destStart = dest;

-

-			if(flipbit)

-			{

-				for(int j = 0; j < 2 && (y + j) < h; j++)

-				{

-					bgra8* color = (bgra8*)dest;

-					if((x + 0) < w) color[0] = subblockColors0[getIndex(0, j)].addA(alphaValues[j][0]);

-					if((x + 1) < w) color[1] = subblockColors0[getIndex(1, j)].addA(alphaValues[j][1]);

-					if((x + 2) < w) color[2] = subblockColors0[getIndex(2, j)].addA(alphaValues[j][2]);

-					if((x + 3) < w) color[3] = subblockColors0[getIndex(3, j)].addA(alphaValues[j][3]);

-					dest += pitch;

-				}

-

-				for(int j = 2; j < 4 && (y + j) < h; j++)

-				{

-					bgra8* color = (bgra8*)dest;

-					if((x + 0) < w) color[0] = subblockColors1[getIndex(0, j)].addA(alphaValues[j][0]);

-					if((x + 1) < w) color[1] = subblockColors1[getIndex(1, j)].addA(alphaValues[j][1]);

-					if((x + 2) < w) color[2] = subblockColors1[getIndex(2, j)].addA(alphaValues[j][2]);

-					if((x + 3) < w) color[3] = subblockColors1[getIndex(3, j)].addA(alphaValues[j][3]);

-					dest += pitch;

-				}

-			}

-			else

-			{

-				for(int j = 0; j < 4 && (y + j) < h; j++)

-				{

-					bgra8* color = (bgra8*)dest;

-					if((x + 0) < w) color[0] = subblockColors0[getIndex(0, j)].addA(alphaValues[j][0]);

-					if((x + 1) < w) color[1] = subblockColors0[getIndex(1, j)].addA(alphaValues[j][1]);

-					if((x + 2) < w) color[2] = subblockColors1[getIndex(2, j)].addA(alphaValues[j][2]);

-					if((x + 3) < w) color[3] = subblockColors1[getIndex(3, j)].addA(alphaValues[j][3]);

-					dest += pitch;

-				}

-			}

-

-			if(nonOpaquePunchThroughAlpha)

-			{

-				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);

-			}

-		}

-

-		void decodeTBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const

-		{

-			// Table C.8, distance index fot T and H modes

-			static const int distance[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };

-

-			bgra8 paintColors[4];

-

-			int r1 = extend_4to8bits(TR1a << 2 | TR1b);

-			int g1 = extend_4to8bits(TG1);

-			int b1 = extend_4to8bits(TB1);

-

-			int r2 = extend_4to8bits(TR2);

-			int g2 = extend_4to8bits(TG2);

-			int b2 = extend_4to8bits(TB2);

-

-			const int d = distance[Tda << 1 | Tdb];

-

-			paintColors[0].set(r1, g1, b1);

-			paintColors[1].set(r2 + d, g2 + d, b2 + d);

-			paintColors[2].set(r2, g2, b2);

-			paintColors[3].set(r2 - d, g2 - d, b2 - d);

-

-			unsigned char* destStart = dest;

-

-			for(int j = 0; j < 4 && (y + j) < h; j++)

-			{

-				bgra8* color = (bgra8*)dest;

-				if((x + 0) < w) color[0] = paintColors[getIndex(0, j)].addA(alphaValues[j][0]);

-				if((x + 1) < w) color[1] = paintColors[getIndex(1, j)].addA(alphaValues[j][1]);

-				if((x + 2) < w) color[2] = paintColors[getIndex(2, j)].addA(alphaValues[j][2]);

-				if((x + 3) < w) color[3] = paintColors[getIndex(3, j)].addA(alphaValues[j][3]);

-				dest += pitch;

-			}

-

-			if(nonOpaquePunchThroughAlpha)

-			{

-				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);

-			}

-		}

-

-		void decodeHBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const

-		{

-			// Table C.8, distance index fot T and H modes

-			static const int distance[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };

-

-			bgra8 paintColors[4];

-

-			int r1 = extend_4to8bits(HR1);

-			int g1 = extend_4to8bits(HG1a << 1 | HG1b);

-			int b1 = extend_4to8bits(HB1a << 3 | HB1b << 1 | HB1c);

-

-			int r2 = extend_4to8bits(HR2);

-			int g2 = extend_4to8bits(HG2a << 1 | HG2b);

-			int b2 = extend_4to8bits(HB2);

-

-			const int d = distance[(Hda << 2) | (Hdb << 1) | ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0)];

-

-			paintColors[0].set(r1 + d, g1 + d, b1 + d);

-			paintColors[1].set(r1 - d, g1 - d, b1 - d);

-			paintColors[2].set(r2 + d, g2 + d, b2 + d);

-			paintColors[3].set(r2 - d, g2 - d, b2 - d);

-

-			unsigned char* destStart = dest;

-

-			for(int j = 0; j < 4 && (y + j) < h; j++)

-			{

-				bgra8* color = (bgra8*)dest;

-				if((x + 0) < w) color[0] = paintColors[getIndex(0, j)].addA(alphaValues[j][0]);

-				if((x + 1) < w) color[1] = paintColors[getIndex(1, j)].addA(alphaValues[j][1]);

-				if((x + 2) < w) color[2] = paintColors[getIndex(2, j)].addA(alphaValues[j][2]);

-				if((x + 3) < w) color[3] = paintColors[getIndex(3, j)].addA(alphaValues[j][3]);

-				dest += pitch;

-			}

-

-			if(nonOpaquePunchThroughAlpha)

-			{

-				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);

-			}

-		}

-

-		void decodePlanarBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4]) const

-		{

-			int ro = extend_6to8bits(RO);

-			int go = extend_7to8bits(GO1 << 6 | GO2);

-			int bo = extend_6to8bits(BO1 << 5 | BO2 << 3 | BO3a << 1 | BO3b);

-

-			int rh = extend_6to8bits(RH1 << 1 | RH2);

-			int gh = extend_7to8bits(GH);

-			int bh = extend_6to8bits(BHa << 5 | BHb);

-

-			int rv = extend_6to8bits(RVa << 3 | RVb);

-			int gv = extend_7to8bits(GVa << 2 | GVb);

-			int bv = extend_6to8bits(BV);

-

-			for(int j = 0; j < 4 && (y + j) < h; j++)

-			{

-				int ry = j * (rv - ro) + 2;

-				int gy = j * (gv - go) + 2;

-				int by = j * (bv - bo) + 2;

-				for(int i = 0; i < 4 && (x + i) < w; i++)

-				{

-					((bgra8*)(dest))[i].set(((i * (rh - ro) + ry) >> 2) + ro,

-						((i * (gh - go) + gy) >> 2) + go,

-						((i * (bh - bo) + by) >> 2) + bo,

-						alphaValues[j][i]);

-				}

-				dest += pitch;

-			}

-		}

-

-		// Index for individual, differential, H and T modes

-		inline int getIndex(int x, int y) const

-		{

-			int bitIndex = x * 4 + y;

-			int bitOffset = bitIndex & 7;

-			int lsb = (pixelIndexLSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;

-			int msb = (pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;

-

-			return (msb << 1) | lsb;

-		}

-

-		void decodePunchThroughAlphaBlock(unsigned char *dest, int x, int y, int w, int h, int pitch) const

-		{

-			for(int j = 0; j < 4 && (y + j) < h; j++)

-			{

-				for(int i = 0; i < 4 && (x + i) < w; i++)

-				{

-					if(getIndex(i, j) == 2) //  msb == 1 && lsb == 0

-					{

-						((bgra8*)dest)[i].set(0, 0, 0, 0);

-					}

-				}

-				dest += pitch;

-			}

-		}

-

-		// Single channel utility functions

-		inline int getSingleChannel(int x, int y, bool isSigned) const

-		{

-			int codeword = isSigned ? signed_base_codeword : base_codeword;

-			return codeword + getSingleChannelModifier(x, y) * multiplier;

-		}

-

-		inline int getSingleChannelIndex(int x, int y) const

-		{

-			switch(x * 4 + y)

-			{

-			case 0: return ma;

-			case 1: return mb;

-			case 2: return mc1 << 1 | mc2;

-			case 3: return md;

-			case 4: return me;

-			case 5: return mf1 << 2 | mf2;

-			case 6: return mg;

-			case 7: return mh;

-			case 8: return mi;

-			case 9: return mj;

-			case 10: return mk1 << 1 | mk2;

-			case 11: return ml;

-			case 12: return mm;

-			case 13: return mn1 << 2 | mn2;

-			case 14: return mo;

-			default: return mp; // 15

-			}

-		}

-

-		inline int getSingleChannelModifier(int x, int y) const

-		{

-			static const int modifierTable[16][8] = { { -3, -6, -9, -15, 2, 5, 8, 14 },

-			{ -3, -7, -10, -13, 2, 6, 9, 12 },

-			{ -2, -5, -8, -13, 1, 4, 7, 12 },

-			{ -2, -4, -6, -13, 1, 3, 5, 12 },

-			{ -3, -6, -8, -12, 2, 5, 7, 11 },

-			{ -3, -7, -9, -11, 2, 6, 8, 10 },

-			{ -4, -7, -8, -11, 3, 6, 7, 10 },

-			{ -3, -5, -8, -11, 2, 4, 7, 10 },

-			{ -2, -6, -8, -10, 1, 5, 7, 9 },

-			{ -2, -5, -8, -10, 1, 4, 7, 9 },

-			{ -2, -4, -8, -10, 1, 3, 7, 9 },

-			{ -2, -5, -7, -10, 1, 4, 6, 9 },

-			{ -3, -4, -7, -10, 2, 3, 6, 9 },

-			{ -1, -2, -3, -10, 0, 1, 2, 9 },

-			{ -4, -6, -8, -9, 3, 5, 7, 8 },

-			{ -3, -5, -7, -9, 2, 4, 6, 8 } };

-

-			return modifierTable[table_index][getSingleChannelIndex(x, y)];

-		}

-	};

-}

-

-// Decodes 1 to 4 channel images to 8 bit output

-bool ETC_Decoder::Decode(const unsigned char* src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType)

-{

-	const ETC2* sources[2];

-	sources[0] = (const ETC2*)src;

-

-	unsigned char alphaValues[4][4] = { { 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 } };

-

-	switch(inputType)

-	{

-	case ETC_R_SIGNED:

-	case ETC_R_UNSIGNED:

-		for(int y = 0; y < h; y += 4)

-		{

-			unsigned char *dstRow = dst + (y * dstPitch);

-			for(int x = 0; x < w; x += 4, sources[0]++)

-			{

-				ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 1, x, y, dstW, dstH, dstPitch, inputType == ETC_R_SIGNED);

-			}

-		}

-		break;

-	case ETC_RG_SIGNED:

-	case ETC_RG_UNSIGNED:

-		sources[1] = sources[0] + 1;

-		for(int y = 0; y < h; y += 4)

-		{

-			unsigned char *dstRow = dst + (y * dstPitch);

-			for(int x = 0; x < w; x += 4, sources[0] += 2, sources[1] += 2)

-			{

-				ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 2, x, y, dstW, dstH, dstPitch, inputType == ETC_RG_SIGNED);

-			}

-		}

-		break;

-	case ETC_RGB:

-	case ETC_RGB_PUNCHTHROUGH_ALPHA:

-		for(int y = 0; y < h; y += 4)

-		{

-			unsigned char *dstRow = dst + (y * dstPitch);

-			for(int x = 0; x < w; x += 4, sources[0]++)

-			{

-				sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, inputType == ETC_RGB_PUNCHTHROUGH_ALPHA);

-			}

-		}

-		break;

-	case ETC_RGBA:

-		for(int y = 0; y < h; y += 4)

-		{

-			unsigned char *dstRow = dst + (y * dstPitch);

-			for(int x = 0; x < w; x += 4)

-			{

-				// Decode Alpha

-				ETC2::DecodeBlock(&sources[0], &(alphaValues[0][0]), 1, x, y, dstW, dstH, 4, false);

-				sources[0]++; // RGBA packets are 128 bits, so move on to the next 64 bit packet to decode the RGB color

-

-				// Decode RGB

-				sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, false);

-				sources[0]++;

-			}

-		}

-		break;

-	default:

-		return false;

-	}

-

-	return true;

-}

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "ETC_Decoder.hpp"
+
+namespace
+{
+	inline int clampByte(int value)
+	{
+		return (value < 0) ? 0 : ((value > 255) ? 255 : value);
+	}
+
+	inline int clampSByte(int value)
+	{
+		return (value < -128) ? -128 : ((value > 127) ? 127 : value);
+	}
+
+	struct bgra8
+	{
+		unsigned char b;
+		unsigned char g;
+		unsigned char r;
+		unsigned char a;
+
+		inline bgra8()
+		{
+		}
+
+		inline void set(int red, int green, int blue)
+		{
+			r = static_cast<unsigned char>(clampByte(red));
+			g = static_cast<unsigned char>(clampByte(green));
+			b = static_cast<unsigned char>(clampByte(blue));
+		}
+
+		inline void set(int red, int green, int blue, int alpha)
+		{
+			r = static_cast<unsigned char>(clampByte(red));
+			g = static_cast<unsigned char>(clampByte(green));
+			b = static_cast<unsigned char>(clampByte(blue));
+			a = static_cast<unsigned char>(clampByte(alpha));
+		}
+
+		const bgra8& addA(int alpha)
+		{
+			a = alpha;
+			return *this;
+		}
+	};
+
+	inline int extend_4to8bits(int x)
+	{
+		return (x << 4) | x;
+	}
+
+	inline int extend_5to8bits(int x)
+	{
+		return (x << 3) | (x >> 2);
+	}
+
+	inline int extend_6to8bits(int x)
+	{
+		return (x << 2) | (x >> 4);
+	}
+
+	inline int extend_7to8bits(int x)
+	{
+		return (x << 1) | (x >> 6);
+	}
+
+	struct ETC2
+	{
+		// Decodes unsigned single or dual channel block to bytes
+		static void DecodeBlock(const ETC2** sources, unsigned char *dest, int nbChannels, int x, int y, int w, int h, int pitch, bool isSigned)
+		{
+			if(isSigned)
+			{
+				signed char* sDst = reinterpret_cast<signed char*>(dest);
+				for(int j = 0; j < 4 && (y + j) < h; j++)
+				{
+					for(int i = 0; i < 4 && (x + i) < w; i++)
+					{
+						for(int c = nbChannels - 1; c >= 0; c--)
+						{
+							sDst[i * nbChannels + c] = clampSByte(sources[c]->getSingleChannel(i, j, isSigned));
+						}
+					}
+					sDst += pitch;
+				}
+			}
+			else
+			{
+				for(int j = 0; j < 4 && (y + j) < h; j++)
+				{
+					for(int i = 0; i < 4 && (x + i) < w; i++)
+					{
+						for(int c = nbChannels - 1; c >= 0; c--)
+						{
+							dest[i * nbChannels + c] = clampByte(sources[c]->getSingleChannel(i, j, isSigned));
+						}
+					}
+					dest += pitch;
+				}
+			}
+		}
+
+		// Decodes RGB block to bgra8
+		void decodeBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool punchThroughAlpha) const
+		{
+			bool opaqueBit = diffbit;
+			bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit;
+
+			// Select mode
+			if(diffbit || punchThroughAlpha)
+			{
+				int r = (R + dR);
+				int g = (G + dG);
+				int b = (B + dB);
+				if(r < 0 || r > 31)
+				{
+					decodeTBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
+				}
+				else if(g < 0 || g > 31)
+				{
+					decodeHBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
+				}
+				else if(b < 0 || b > 31)
+				{
+					decodePlanarBlock(dest, x, y, w, h, pitch, alphaValues);
+				}
+				else
+				{
+					decodeDifferentialBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
+				}
+			}
+			else
+			{
+				decodeIndividualBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
+			}
+		}
+
+	private:
+		struct
+		{
+			union
+			{
+				// Individual, differential, H and T modes
+				struct
+				{
+					union
+					{
+						// Individual and differential modes
+						struct
+						{
+							union
+							{
+								struct   // Individual colors
+								{
+									unsigned char R2 : 4;
+									unsigned char R1 : 4;
+									unsigned char G2 : 4;
+									unsigned char G1 : 4;
+									unsigned char B2 : 4;
+									unsigned char B1 : 4;
+								};
+
+								struct   // Differential colors
+								{
+									signed char dR : 3;
+									unsigned char R : 5;
+									signed char dG : 3;
+									unsigned char G : 5;
+									signed char dB : 3;
+									unsigned char B : 5;
+								};
+							};
+
+							bool flipbit : 1;
+							bool diffbit : 1;
+							unsigned char cw2 : 3;
+							unsigned char cw1 : 3;
+						};
+
+						// T mode
+						struct
+						{
+							// Byte 1
+							unsigned char TR1b : 2;
+							unsigned char TdummyB : 1;
+							unsigned char TR1a : 2;
+							unsigned char TdummyA : 3;
+
+							// Byte 2
+							unsigned char TB1 : 4;
+							unsigned char TG1 : 4;
+
+							// Byte 3
+							unsigned char TG2 : 4;
+							unsigned char TR2 : 4;
+
+							// Byte 4
+							unsigned char Tdb : 1;
+							bool Tflipbit : 1;
+							unsigned char Tda : 2;
+							unsigned char TB2 : 4;
+						};
+
+						// H mode
+						struct
+						{
+							// Byte 1
+							unsigned char HG1a : 3;
+							unsigned char HR1 : 4;
+							unsigned char HdummyA : 1;
+
+							// Byte 2
+							unsigned char HB1b : 2;
+							unsigned char HdummyC : 1;
+							unsigned char HB1a : 1;
+							unsigned char HG1b : 1;
+							unsigned char HdummyB : 3;
+
+							// Byte 3
+							unsigned char HG2a : 3;
+							unsigned char HR2 : 4;
+							unsigned char HB1c : 1;
+
+							// Byte 4
+							unsigned char Hdb : 1;
+							bool Hflipbit : 1;
+							unsigned char Hda : 1;
+							unsigned char HB2 : 4;
+							unsigned char HG2b : 1;
+						};
+					};
+
+					unsigned char pixelIndexMSB[2];
+					unsigned char pixelIndexLSB[2];
+				};
+
+				// planar mode
+				struct
+				{
+					// Byte 1
+					unsigned char GO1 : 1;
+					unsigned char RO : 6;
+					unsigned char PdummyA : 1;
+
+					// Byte 2
+					unsigned char BO1 : 1;
+					unsigned char GO2 : 6;
+					unsigned char PdummyB : 1;
+
+					// Byte 3
+					unsigned char BO3a : 2;
+					unsigned char PdummyD : 1;
+					unsigned char BO2 : 2;
+					unsigned char PdummyC : 3;
+
+					// Byte 4
+					unsigned char RH2 : 1;
+					bool Pflipbit : 1;
+					unsigned char RH1 : 5;
+					unsigned char BO3b : 1;
+
+					// Byte 5
+					unsigned char BHa : 1;
+					unsigned char GH : 7;
+
+					// Byte 6
+					unsigned char RVa : 3;
+					unsigned char BHb : 5;
+
+					// Byte 7
+					unsigned char GVa : 5;
+					unsigned char RVb : 3;
+
+					// Byte 8
+					unsigned char BV : 6;
+					unsigned char GVb : 2;
+				};
+
+				// Single channel block
+				struct
+				{
+					union
+					{
+						unsigned char base_codeword;
+						signed char signed_base_codeword;
+					};
+
+					unsigned char table_index : 4;
+					unsigned char multiplier : 4;
+
+					unsigned char mc1 : 2;
+					unsigned char mb : 3;
+					unsigned char ma : 3;
+
+					unsigned char mf1 : 1;
+					unsigned char me : 3;
+					unsigned char md : 3;
+					unsigned char mc2 : 1;
+
+					unsigned char mh : 3;
+					unsigned char mg : 3;
+					unsigned char mf2 : 2;
+
+					unsigned char mk1 : 2;
+					unsigned char mj : 3;
+					unsigned char mi : 3;
+
+					unsigned char mn1 : 1;
+					unsigned char mm : 3;
+					unsigned char ml : 3;
+					unsigned char mk2 : 1;
+
+					unsigned char mp : 3;
+					unsigned char mo : 3;
+					unsigned char mn2 : 2;
+				};
+			};
+		};
+
+		void decodeIndividualBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
+		{
+			int r1 = extend_4to8bits(R1);
+			int g1 = extend_4to8bits(G1);
+			int b1 = extend_4to8bits(B1);
+
+			int r2 = extend_4to8bits(R2);
+			int g2 = extend_4to8bits(G2);
+			int b2 = extend_4to8bits(B2);
+
+			decodeIndividualOrDifferentialBlock(dest, x, y, w, h, pitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha);
+		}
+
+		void decodeDifferentialBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
+		{
+			int b1 = extend_5to8bits(B);
+			int g1 = extend_5to8bits(G);
+			int r1 = extend_5to8bits(R);
+
+			int r2 = extend_5to8bits(R + dR);
+			int g2 = extend_5to8bits(G + dG);
+			int b2 = extend_5to8bits(B + dB);
+
+			decodeIndividualOrDifferentialBlock(dest, x, y, w, h, pitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha);
+		}
+
+		void decodeIndividualOrDifferentialBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, int r1, int g1, int b1, int r2, int g2, int b2, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
+		{
+			// Table 3.17.2 sorted according to table 3.17.3
+			static const int intensityModifierDefault[8][4] =
+			{
+				{ 2, 8, -2, -8 },
+				{ 5, 17, -5, -17 },
+				{ 9, 29, -9, -29 },
+				{ 13, 42, -13, -42 },
+				{ 18, 60, -18, -60 },
+				{ 24, 80, -24, -80 },
+				{ 33, 106, -33, -106 },
+				{ 47, 183, -47, -183 }
+			};
+
+			// Table C.12, intensity modifier for non opaque punchthrough alpha
+			static const int intensityModifierNonOpaque[8][4] =
+			{
+				{ 0, 8, 0, -8 },
+				{ 0, 17, 0, -17 },
+				{ 0, 29, 0, -29 },
+				{ 0, 42, 0, -42 },
+				{ 0, 60, 0, -60 },
+				{ 0, 80, 0, -80 },
+				{ 0, 106, 0, -106 },
+				{ 0, 183, 0, -183 }
+			};
+
+			const int(&intensityModifier)[8][4] = nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;
+
+			bgra8 subblockColors0[4];
+			bgra8 subblockColors1[4];
+
+			const int i10 = intensityModifier[cw1][0];
+			const int i11 = intensityModifier[cw1][1];
+			const int i12 = intensityModifier[cw1][2];
+			const int i13 = intensityModifier[cw1][3];
+
+			subblockColors0[0].set(r1 + i10, g1 + i10, b1 + i10);
+			subblockColors0[1].set(r1 + i11, g1 + i11, b1 + i11);
+			subblockColors0[2].set(r1 + i12, g1 + i12, b1 + i12);
+			subblockColors0[3].set(r1 + i13, g1 + i13, b1 + i13);
+
+			const int i20 = intensityModifier[cw2][0];
+			const int i21 = intensityModifier[cw2][1];
+			const int i22 = intensityModifier[cw2][2];
+			const int i23 = intensityModifier[cw2][3];
+
+			subblockColors1[0].set(r2 + i20, g2 + i20, b2 + i20);
+			subblockColors1[1].set(r2 + i21, g2 + i21, b2 + i21);
+			subblockColors1[2].set(r2 + i22, g2 + i22, b2 + i22);
+			subblockColors1[3].set(r2 + i23, g2 + i23, b2 + i23);
+
+			unsigned char* destStart = dest;
+
+			if(flipbit)
+			{
+				for(int j = 0; j < 2 && (y + j) < h; j++)
+				{
+					bgra8* color = (bgra8*)dest;
+					if((x + 0) < w) color[0] = subblockColors0[getIndex(0, j)].addA(alphaValues[j][0]);
+					if((x + 1) < w) color[1] = subblockColors0[getIndex(1, j)].addA(alphaValues[j][1]);
+					if((x + 2) < w) color[2] = subblockColors0[getIndex(2, j)].addA(alphaValues[j][2]);
+					if((x + 3) < w) color[3] = subblockColors0[getIndex(3, j)].addA(alphaValues[j][3]);
+					dest += pitch;
+				}
+
+				for(int j = 2; j < 4 && (y + j) < h; j++)
+				{
+					bgra8* color = (bgra8*)dest;
+					if((x + 0) < w) color[0] = subblockColors1[getIndex(0, j)].addA(alphaValues[j][0]);
+					if((x + 1) < w) color[1] = subblockColors1[getIndex(1, j)].addA(alphaValues[j][1]);
+					if((x + 2) < w) color[2] = subblockColors1[getIndex(2, j)].addA(alphaValues[j][2]);
+					if((x + 3) < w) color[3] = subblockColors1[getIndex(3, j)].addA(alphaValues[j][3]);
+					dest += pitch;
+				}
+			}
+			else
+			{
+				for(int j = 0; j < 4 && (y + j) < h; j++)
+				{
+					bgra8* color = (bgra8*)dest;
+					if((x + 0) < w) color[0] = subblockColors0[getIndex(0, j)].addA(alphaValues[j][0]);
+					if((x + 1) < w) color[1] = subblockColors0[getIndex(1, j)].addA(alphaValues[j][1]);
+					if((x + 2) < w) color[2] = subblockColors1[getIndex(2, j)].addA(alphaValues[j][2]);
+					if((x + 3) < w) color[3] = subblockColors1[getIndex(3, j)].addA(alphaValues[j][3]);
+					dest += pitch;
+				}
+			}
+
+			if(nonOpaquePunchThroughAlpha)
+			{
+				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);
+			}
+		}
+
+		void decodeTBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
+		{
+			// Table C.8, distance index fot T and H modes
+			static const int distance[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
+
+			bgra8 paintColors[4];
+
+			int r1 = extend_4to8bits(TR1a << 2 | TR1b);
+			int g1 = extend_4to8bits(TG1);
+			int b1 = extend_4to8bits(TB1);
+
+			int r2 = extend_4to8bits(TR2);
+			int g2 = extend_4to8bits(TG2);
+			int b2 = extend_4to8bits(TB2);
+
+			const int d = distance[Tda << 1 | Tdb];
+
+			paintColors[0].set(r1, g1, b1);
+			paintColors[1].set(r2 + d, g2 + d, b2 + d);
+			paintColors[2].set(r2, g2, b2);
+			paintColors[3].set(r2 - d, g2 - d, b2 - d);
+
+			unsigned char* destStart = dest;
+
+			for(int j = 0; j < 4 && (y + j) < h; j++)
+			{
+				bgra8* color = (bgra8*)dest;
+				if((x + 0) < w) color[0] = paintColors[getIndex(0, j)].addA(alphaValues[j][0]);
+				if((x + 1) < w) color[1] = paintColors[getIndex(1, j)].addA(alphaValues[j][1]);
+				if((x + 2) < w) color[2] = paintColors[getIndex(2, j)].addA(alphaValues[j][2]);
+				if((x + 3) < w) color[3] = paintColors[getIndex(3, j)].addA(alphaValues[j][3]);
+				dest += pitch;
+			}
+
+			if(nonOpaquePunchThroughAlpha)
+			{
+				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);
+			}
+		}
+
+		void decodeHBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
+		{
+			// Table C.8, distance index fot T and H modes
+			static const int distance[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
+
+			bgra8 paintColors[4];
+
+			int r1 = extend_4to8bits(HR1);
+			int g1 = extend_4to8bits(HG1a << 1 | HG1b);
+			int b1 = extend_4to8bits(HB1a << 3 | HB1b << 1 | HB1c);
+
+			int r2 = extend_4to8bits(HR2);
+			int g2 = extend_4to8bits(HG2a << 1 | HG2b);
+			int b2 = extend_4to8bits(HB2);
+
+			const int d = distance[(Hda << 2) | (Hdb << 1) | ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0)];
+
+			paintColors[0].set(r1 + d, g1 + d, b1 + d);
+			paintColors[1].set(r1 - d, g1 - d, b1 - d);
+			paintColors[2].set(r2 + d, g2 + d, b2 + d);
+			paintColors[3].set(r2 - d, g2 - d, b2 - d);
+
+			unsigned char* destStart = dest;
+
+			for(int j = 0; j < 4 && (y + j) < h; j++)
+			{
+				bgra8* color = (bgra8*)dest;
+				if((x + 0) < w) color[0] = paintColors[getIndex(0, j)].addA(alphaValues[j][0]);
+				if((x + 1) < w) color[1] = paintColors[getIndex(1, j)].addA(alphaValues[j][1]);
+				if((x + 2) < w) color[2] = paintColors[getIndex(2, j)].addA(alphaValues[j][2]);
+				if((x + 3) < w) color[3] = paintColors[getIndex(3, j)].addA(alphaValues[j][3]);
+				dest += pitch;
+			}
+
+			if(nonOpaquePunchThroughAlpha)
+			{
+				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);
+			}
+		}
+
+		void decodePlanarBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4]) const
+		{
+			int ro = extend_6to8bits(RO);
+			int go = extend_7to8bits(GO1 << 6 | GO2);
+			int bo = extend_6to8bits(BO1 << 5 | BO2 << 3 | BO3a << 1 | BO3b);
+
+			int rh = extend_6to8bits(RH1 << 1 | RH2);
+			int gh = extend_7to8bits(GH);
+			int bh = extend_6to8bits(BHa << 5 | BHb);
+
+			int rv = extend_6to8bits(RVa << 3 | RVb);
+			int gv = extend_7to8bits(GVa << 2 | GVb);
+			int bv = extend_6to8bits(BV);
+
+			for(int j = 0; j < 4 && (y + j) < h; j++)
+			{
+				int ry = j * (rv - ro) + 2;
+				int gy = j * (gv - go) + 2;
+				int by = j * (bv - bo) + 2;
+				for(int i = 0; i < 4 && (x + i) < w; i++)
+				{
+					((bgra8*)(dest))[i].set(((i * (rh - ro) + ry) >> 2) + ro,
+						((i * (gh - go) + gy) >> 2) + go,
+						((i * (bh - bo) + by) >> 2) + bo,
+						alphaValues[j][i]);
+				}
+				dest += pitch;
+			}
+		}
+
+		// Index for individual, differential, H and T modes
+		inline int getIndex(int x, int y) const
+		{
+			int bitIndex = x * 4 + y;
+			int bitOffset = bitIndex & 7;
+			int lsb = (pixelIndexLSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;
+			int msb = (pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;
+
+			return (msb << 1) | lsb;
+		}
+
+		void decodePunchThroughAlphaBlock(unsigned char *dest, int x, int y, int w, int h, int pitch) const
+		{
+			for(int j = 0; j < 4 && (y + j) < h; j++)
+			{
+				for(int i = 0; i < 4 && (x + i) < w; i++)
+				{
+					if(getIndex(i, j) == 2) //  msb == 1 && lsb == 0
+					{
+						((bgra8*)dest)[i].set(0, 0, 0, 0);
+					}
+				}
+				dest += pitch;
+			}
+		}
+
+		// Single channel utility functions
+		inline int getSingleChannel(int x, int y, bool isSigned) const
+		{
+			int codeword = isSigned ? signed_base_codeword : base_codeword;
+			return codeword + getSingleChannelModifier(x, y) * multiplier;
+		}
+
+		inline int getSingleChannelIndex(int x, int y) const
+		{
+			switch(x * 4 + y)
+			{
+			case 0: return ma;
+			case 1: return mb;
+			case 2: return mc1 << 1 | mc2;
+			case 3: return md;
+			case 4: return me;
+			case 5: return mf1 << 2 | mf2;
+			case 6: return mg;
+			case 7: return mh;
+			case 8: return mi;
+			case 9: return mj;
+			case 10: return mk1 << 1 | mk2;
+			case 11: return ml;
+			case 12: return mm;
+			case 13: return mn1 << 2 | mn2;
+			case 14: return mo;
+			default: return mp; // 15
+			}
+		}
+
+		inline int getSingleChannelModifier(int x, int y) const
+		{
+			static const int modifierTable[16][8] = { { -3, -6, -9, -15, 2, 5, 8, 14 },
+			{ -3, -7, -10, -13, 2, 6, 9, 12 },
+			{ -2, -5, -8, -13, 1, 4, 7, 12 },
+			{ -2, -4, -6, -13, 1, 3, 5, 12 },
+			{ -3, -6, -8, -12, 2, 5, 7, 11 },
+			{ -3, -7, -9, -11, 2, 6, 8, 10 },
+			{ -4, -7, -8, -11, 3, 6, 7, 10 },
+			{ -3, -5, -8, -11, 2, 4, 7, 10 },
+			{ -2, -6, -8, -10, 1, 5, 7, 9 },
+			{ -2, -5, -8, -10, 1, 4, 7, 9 },
+			{ -2, -4, -8, -10, 1, 3, 7, 9 },
+			{ -2, -5, -7, -10, 1, 4, 6, 9 },
+			{ -3, -4, -7, -10, 2, 3, 6, 9 },
+			{ -1, -2, -3, -10, 0, 1, 2, 9 },
+			{ -4, -6, -8, -9, 3, 5, 7, 8 },
+			{ -3, -5, -7, -9, 2, 4, 6, 8 } };
+
+			return modifierTable[table_index][getSingleChannelIndex(x, y)];
+		}
+	};
+}
+
+// Decodes 1 to 4 channel images to 8 bit output
+bool ETC_Decoder::Decode(const unsigned char* src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType)
+{
+	const ETC2* sources[2];
+	sources[0] = (const ETC2*)src;
+
+	unsigned char alphaValues[4][4] = { { 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 } };
+
+	switch(inputType)
+	{
+	case ETC_R_SIGNED:
+	case ETC_R_UNSIGNED:
+		for(int y = 0; y < h; y += 4)
+		{
+			unsigned char *dstRow = dst + (y * dstPitch);
+			for(int x = 0; x < w; x += 4, sources[0]++)
+			{
+				ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 1, x, y, dstW, dstH, dstPitch, inputType == ETC_R_SIGNED);
+			}
+		}
+		break;
+	case ETC_RG_SIGNED:
+	case ETC_RG_UNSIGNED:
+		sources[1] = sources[0] + 1;
+		for(int y = 0; y < h; y += 4)
+		{
+			unsigned char *dstRow = dst + (y * dstPitch);
+			for(int x = 0; x < w; x += 4, sources[0] += 2, sources[1] += 2)
+			{
+				ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 2, x, y, dstW, dstH, dstPitch, inputType == ETC_RG_SIGNED);
+			}
+		}
+		break;
+	case ETC_RGB:
+	case ETC_RGB_PUNCHTHROUGH_ALPHA:
+		for(int y = 0; y < h; y += 4)
+		{
+			unsigned char *dstRow = dst + (y * dstPitch);
+			for(int x = 0; x < w; x += 4, sources[0]++)
+			{
+				sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, inputType == ETC_RGB_PUNCHTHROUGH_ALPHA);
+			}
+		}
+		break;
+	case ETC_RGBA:
+		for(int y = 0; y < h; y += 4)
+		{
+			unsigned char *dstRow = dst + (y * dstPitch);
+			for(int x = 0; x < w; x += 4)
+			{
+				// Decode Alpha
+				ETC2::DecodeBlock(&sources[0], &(alphaValues[0][0]), 1, x, y, dstW, dstH, 4, false);
+				sources[0]++; // RGBA packets are 128 bits, so move on to the next 64 bit packet to decode the RGB color
+
+				// Decode RGB
+				sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, false);
+				sources[0]++;
+			}
+		}
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
diff --git a/src/Renderer/ETC_Decoder.hpp b/src/Renderer/ETC_Decoder.hpp
index 11b1395..1039b37 100644
--- a/src/Renderer/ETC_Decoder.hpp
+++ b/src/Renderer/ETC_Decoder.hpp
@@ -1,38 +1,41 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-class ETC_Decoder

-{

-public:

-	enum InputType

-	{

-		ETC_R_SIGNED,

-		ETC_R_UNSIGNED,

-		ETC_RG_SIGNED,

-		ETC_RG_UNSIGNED,

-		ETC_RGB,

-		ETC_RGB_PUNCHTHROUGH_ALPHA,

-		ETC_RGBA

-	};

-

-	/// ETC_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output

-	/// @param src            Pointer to ETC2 encoded image

-	/// @param dst            Pointer to BGRA, 8 bit output

-	/// @param w              src image width

-	/// @param h              src image height

-	/// @param dstW           dst image width

-	/// @param dstH           dst image height

-	/// @param dstPitch       dst image pitch (bytes per row)

-	/// @param dstBpp         dst image bytes per pixel

-	/// @param inputType      src's format

-	/// @return               true if the decoding was performed

-	static bool Decode(const unsigned char* src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType);

-};

+// 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.
+
+class ETC_Decoder
+{
+public:
+	enum InputType
+	{
+		ETC_R_SIGNED,
+		ETC_R_UNSIGNED,
+		ETC_RG_SIGNED,
+		ETC_RG_UNSIGNED,
+		ETC_RGB,
+		ETC_RGB_PUNCHTHROUGH_ALPHA,
+		ETC_RGBA
+	};
+
+	/// ETC_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output
+	/// @param src            Pointer to ETC2 encoded image
+	/// @param dst            Pointer to BGRA, 8 bit output
+	/// @param w              src image width
+	/// @param h              src image height
+	/// @param dstW           dst image width
+	/// @param dstH           dst image height
+	/// @param dstPitch       dst image pitch (bytes per row)
+	/// @param dstBpp         dst image bytes per pixel
+	/// @param inputType      src's format
+	/// @return               true if the decoding was performed
+	static bool Decode(const unsigned char* src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType);
+};
diff --git a/src/Renderer/LRUCache.hpp b/src/Renderer/LRUCache.hpp
index 3ce15fb..77f9ab7 100644
--- a/src/Renderer/LRUCache.hpp
+++ b/src/Renderer/LRUCache.hpp
@@ -1,142 +1,145 @@
-// 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.

-//

-

-#ifndef sw_LRUCache_hpp

-#define sw_LRUCache_hpp

-

-#include "Common/Math.hpp"

-

-namespace sw

-{

-	template<class Key, class Data>

-	class LRUCache

-	{

-	public:

-		LRUCache(int n);

-

-		~LRUCache();

-

-		Data *query(const Key &key) const;

-		Data *add(const Key &key, Data *data);

-		

-		int getSize() {return size;}

-		Key &getKey(int i) {return key[i];}

-

-	private:

-		int size;

-		int mask;

-		int top;

-		int fill;

-

-		Key *key;

-		Key **ref;

-		Data **data;

-	};

-}

-

-namespace sw

-{

-	template<class Key, class Data>

-	LRUCache<Key, Data>::LRUCache(int n)

-	{

-		size = ceilPow2(n);

-		mask = size - 1;

-		top = 0;

-		fill = 0;

-

-		key = new Key[size];

-		ref = new Key*[size];

-		data = new Data*[size];

-		

-		for(int i = 0; i < size; i++)

-		{

-			data[i] = 0;

-

-			ref[i] = &key[i];

-		}

-	}

-

-	template<class Key, class Data>

-	LRUCache<Key, Data>::~LRUCache()

-	{

-		delete[] key;

-		key = 0;

-

-		delete[] ref;

-		ref = 0;

-

-		for(int i = 0; i < size; i++)

-		{

-			if(data[i])

-			{

-				data[i]->unbind();

-				data[i] = 0;

-			}

-		}

-

-		delete[] data;

-		data = 0;

-	}

-

-	template<class Key, class Data>

-	Data *LRUCache<Key, Data>::query(const Key &key) const

-	{

-		for(int i = top; i > top - fill; i--)

-		{

-			int j = i & mask;

-

-			if(key == *ref[j])

-			{

-				Data *hit = data[j];

-

-				if(i != top)

-				{

-					// Move one up

-					int k = (j + 1) & mask;

-

-					Data *swapD = data[k];

-					data[k] = data[j];

-					data[j] = swapD;

-

-					Key *swapK = ref[k];

-					ref[k] = ref[j];

-					ref[j] = swapK;

-				}

-

-				return hit;

-			}

-		}

-

-		return 0;   // Not found

-	}

-	

-	template<class Key, class Data>

-	Data *LRUCache<Key, Data>::add(const Key &key, Data *data)

-	{

-		top = (top + 1) & mask;

-		fill = fill + 1 < size ? fill + 1 : size;

-

-		*ref[top] = key;

-	

-		data->bind();

-		

-		if(this->data[top])

-		{

-			this->data[top]->unbind();

-		}

-

-		this->data[top] = data;

-

-		return data;

-	}

-}

-

-#endif   // sw_LRUCache_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_LRUCache_hpp
+#define sw_LRUCache_hpp
+
+#include "Common/Math.hpp"
+
+namespace sw
+{
+	template<class Key, class Data>
+	class LRUCache
+	{
+	public:
+		LRUCache(int n);
+
+		~LRUCache();
+
+		Data *query(const Key &key) const;
+		Data *add(const Key &key, Data *data);
+	
+		int getSize() {return size;}
+		Key &getKey(int i) {return key[i];}
+
+	private:
+		int size;
+		int mask;
+		int top;
+		int fill;
+
+		Key *key;
+		Key **ref;
+		Data **data;
+	};
+}
+
+namespace sw
+{
+	template<class Key, class Data>
+	LRUCache<Key, Data>::LRUCache(int n)
+	{
+		size = ceilPow2(n);
+		mask = size - 1;
+		top = 0;
+		fill = 0;
+
+		key = new Key[size];
+		ref = new Key*[size];
+		data = new Data*[size];
+		
+		for(int i = 0; i < size; i++)
+		{
+			data[i] = 0;
+
+			ref[i] = &key[i];
+		}
+	}
+
+	template<class Key, class Data>
+	LRUCache<Key, Data>::~LRUCache()
+	{
+		delete[] key;
+		key = 0;
+
+		delete[] ref;
+		ref = 0;
+
+		for(int i = 0; i < size; i++)
+		{
+			if(data[i])
+			{
+				data[i]->unbind();
+				data[i] = 0;
+			}
+		}
+
+		delete[] data;
+		data = 0;
+	}
+
+	template<class Key, class Data>
+	Data *LRUCache<Key, Data>::query(const Key &key) const
+	{
+		for(int i = top; i > top - fill; i--)
+		{
+			int j = i & mask;
+
+			if(key == *ref[j])
+			{
+				Data *hit = data[j];
+
+				if(i != top)
+				{
+					// Move one up
+					int k = (j + 1) & mask;
+
+					Data *swapD = data[k];
+					data[k] = data[j];
+					data[j] = swapD;
+
+					Key *swapK = ref[k];
+					ref[k] = ref[j];
+					ref[j] = swapK;
+				}
+
+				return hit;
+			}
+		}
+
+		return 0;   // Not found
+	}
+	
+	template<class Key, class Data>
+	Data *LRUCache<Key, Data>::add(const Key &key, Data *data)
+	{
+		top = (top + 1) & mask;
+		fill = fill + 1 < size ? fill + 1 : size;
+
+		*ref[top] = key;
+	
+		data->bind();
+		
+		if(this->data[top])
+		{
+			this->data[top]->unbind();
+		}
+
+		this->data[top] = data;
+
+		return data;
+	}
+}
+
+#endif   // sw_LRUCache_hpp
diff --git a/src/Renderer/Matrix.cpp b/src/Renderer/Matrix.cpp
index 3c3567a..1b27bf8 100644
--- a/src/Renderer/Matrix.cpp
+++ b/src/Renderer/Matrix.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Matrix.hpp"
 
diff --git a/src/Renderer/Matrix.hpp b/src/Renderer/Matrix.hpp
index fe93ae2..41281a6 100644
--- a/src/Renderer/Matrix.hpp
+++ b/src/Renderer/Matrix.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef Matrix_hpp
 #define Matrix_hpp
@@ -91,7 +94,7 @@
 
 		static Matrix eulerRotate(const Vector &v);
 		static Matrix eulerRotate(float x, float y, float z);
-		
+	
 		static Matrix translate(const Vector &v);
 		static Matrix translate(float x, float y, float z);
 		
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index 636351a..0c90cbc 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "PixelProcessor.hpp"
 
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp
index 104f377..88fd654 100644
--- a/src/Renderer/PixelProcessor.hpp
+++ b/src/Renderer/PixelProcessor.hpp
@@ -1,331 +1,334 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_PixelProcessor_hpp

-#define sw_PixelProcessor_hpp

-

-#include "Context.hpp"

-#include "RoutineCache.hpp"

-

-namespace sw

-{

-	class PixelShader;

-	class Rasterizer;

-	struct Texture;

-	struct DrawData;

-

-	class PixelProcessor

-	{

-	public:

-		struct States

-		{

-			unsigned int computeHash();

-

-			int shaderID;

-

-			bool depthOverride                        : 1;

-			bool shaderContainsKill                   : 1;

-

-			DepthCompareMode depthCompareMode         : BITS(DEPTH_LAST);

-			AlphaCompareMode alphaCompareMode         : BITS(ALPHA_LAST);

-			bool depthWriteEnable                     : 1;

-			bool quadLayoutDepthBuffer                : 1;

-

-			bool stencilActive                        : 1;

-			StencilCompareMode stencilCompareMode     : BITS(STENCIL_LAST);

-			StencilOperation stencilFailOperation     : BITS(OPERATION_LAST);

-			StencilOperation stencilPassOperation     : BITS(OPERATION_LAST);

-			StencilOperation stencilZFailOperation    : BITS(OPERATION_LAST);

-			bool noStencilMask                        : 1;

-			bool noStencilWriteMask                   : 1;

-			bool stencilWriteMasked                   : 1;

-			bool twoSidedStencil                      : 1;

-			StencilCompareMode stencilCompareModeCCW  : BITS(STENCIL_LAST);

-			StencilOperation stencilFailOperationCCW  : BITS(OPERATION_LAST);

-			StencilOperation stencilPassOperationCCW  : BITS(OPERATION_LAST);

-			StencilOperation stencilZFailOperationCCW : BITS(OPERATION_LAST);

-			bool noStencilMaskCCW                     : 1;

-			bool noStencilWriteMaskCCW                : 1;

-			bool stencilWriteMaskedCCW                : 1;

-

-			bool depthTestActive                      : 1;

-			bool fogActive                            : 1;

-			FogMode pixelFogMode                      : BITS(FOG_LAST);

-			bool specularAdd                          : 1;

-			bool occlusionEnabled                     : 1;

-			bool wBasedFog                            : 1;

-			bool perspective                          : 1;

-

-			bool alphaBlendActive                     : 1;

-			BlendFactor sourceBlendFactor             : BITS(BLEND_LAST);

-			BlendFactor destBlendFactor               : BITS(BLEND_LAST);

-			BlendOperation blendOperation             : BITS(BLENDOP_LAST);

-			BlendFactor sourceBlendFactorAlpha        : BITS(BLEND_LAST);

-			BlendFactor destBlendFactorAlpha          : BITS(BLEND_LAST);

-			BlendOperation blendOperationAlpha        : BITS(BLENDOP_LAST);

-

-			unsigned int colorWriteMask                       : RENDERTARGETS * 4;   // Four component bit masks

-			Format targetFormat[RENDERTARGETS];

-			bool writeSRGB                                    : 1;

-			unsigned int multiSample                          : 3;

-			unsigned int multiSampleMask                      : 4;

-			TransparencyAntialiasing transparencyAntialiasing : BITS(TRANSPARENCY_LAST);

-			bool centroid                                     : 1;

-

-			LogicalOperation logicalOperation : BITS(LOGICALOP_LAST);

-

-			Sampler::State sampler[TEXTURE_IMAGE_UNITS];

-			TextureStage::State textureStage[8];

-

-			struct Interpolant

-			{

-				unsigned char component : 4;

-				unsigned char flat : 4;

-				unsigned char project : 2;

-				bool centroid : 1;

-			};

-

-			union

-			{

-				struct

-				{

-					Interpolant color[2];

-					Interpolant texture[8];

-				};

-

-				Interpolant interpolant[10];

-			};

-

-			Interpolant fog;

-		};

-

-		struct State : States

-		{

-			State();

-

-			bool operator==(const State &state) const;

-

-			int colorWriteActive(int index) const

-			{

-				return (colorWriteMask >> (index * 4)) & 0xF;

-			}

-

-			bool alphaTestActive() const

-			{

-				return alphaCompareMode != ALPHA_ALWAYS;

-			}

-

-			bool pixelFogActive() const

-			{

-				return pixelFogMode != FOG_NONE;

-			}

-

-			unsigned int hash;

-		};

-

-		struct Stencil

-		{

-			int64_t testMaskQ;

-			int64_t referenceMaskedQ;

-			int64_t referenceMaskedSignedQ;

-			int64_t writeMaskQ;

-			int64_t invWriteMaskQ;

-			int64_t referenceQ;

-

-			void set(int reference, int testMask, int writeMask)

-			{

-				referenceQ = replicate(reference);

-				testMaskQ = replicate(testMask);

-				writeMaskQ = replicate(writeMask);

-				invWriteMaskQ = ~writeMaskQ;

-				referenceMaskedQ = referenceQ & testMaskQ;

-				referenceMaskedSignedQ = replicate((reference + 0x80) & 0xFF & testMask);

-			}

-

-			static int64_t replicate(int b)

-			{

-				int64_t w = b & 0xFF;

-

-				return (w << 0) | (w << 8) | (w << 16) | (w << 24) | (w << 32) | (w << 40) | (w << 48) | (w << 56);

-			}

-		};

-

-		struct Fog

-		{

-			float4 scale;

-			float4 offset;

-			word4 color4[3];

-			float4 colorF[3];

-			float4 densityE;

-			float4 density2E;

-		};

-

-		struct Factor

-		{

-			word4 textureFactor4[4];

-

-			word4 alphaReference4;

-

-			word4 blendConstant4W[4];

-			float4 blendConstant4F[4];

-			word4 invBlendConstant4W[4];

-			float4 invBlendConstant4F[4];

-		};

-

-	public:

-		typedef void (*RoutinePointer)(const Primitive *primitive, int count, int thread, DrawData *draw);

-

-		PixelProcessor(Context *context);

-

-		virtual ~PixelProcessor();

-

-		virtual void setFloatConstant(unsigned int index, const float value[4]);

-		virtual void setIntegerConstant(unsigned int index, const int value[4]);

-		virtual void setBooleanConstant(unsigned int index, int boolean);

-

-		virtual void setUniformBuffer(int index, sw::Resource* buffer, int offset);

-		virtual void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);

-

-		virtual void setRenderTarget(int index, Surface *renderTarget);

-		virtual void setDepthBuffer(Surface *depthBuffer);

-		virtual void setStencilBuffer(Surface *stencilBuffer);

-

-		virtual void setTexCoordIndex(unsigned int stage, int texCoordIndex);

-		virtual void setStageOperation(unsigned int stage, TextureStage::StageOperation stageOperation);

-		virtual void setFirstArgument(unsigned int stage, TextureStage::SourceArgument firstArgument);

-		virtual void setSecondArgument(unsigned int stage, TextureStage::SourceArgument secondArgument);

-		virtual void setThirdArgument(unsigned int stage, TextureStage::SourceArgument thirdArgument);

-		virtual void setStageOperationAlpha(unsigned int stage, TextureStage::StageOperation stageOperationAlpha);

-		virtual void setFirstArgumentAlpha(unsigned int stage, TextureStage::SourceArgument firstArgumentAlpha);

-		virtual void setSecondArgumentAlpha(unsigned int stage, TextureStage::SourceArgument secondArgumentAlpha);

-		virtual void setThirdArgumentAlpha(unsigned int stage, TextureStage::SourceArgument thirdArgumentAlpha);

-		virtual void setFirstModifier(unsigned int stage, TextureStage::ArgumentModifier firstModifier);

-		virtual void setSecondModifier(unsigned int stage, TextureStage::ArgumentModifier secondModifier);

-		virtual void setThirdModifier(unsigned int stage, TextureStage::ArgumentModifier thirdModifier);

-		virtual void setFirstModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier firstModifierAlpha);

-		virtual void setSecondModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier secondModifierAlpha);

-		virtual void setThirdModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier thirdModifierAlpha);

-		virtual void setDestinationArgument(unsigned int stage, TextureStage::DestinationArgument destinationArgument);

-		virtual void setConstantColor(unsigned int stage, const Color<float> &constantColor);

-		virtual void setBumpmapMatrix(unsigned int stage, int element, float value);

-		virtual void setLuminanceScale(unsigned int stage, float value);

-		virtual void setLuminanceOffset(unsigned int stage, float value);

-

-		virtual void setTextureFilter(unsigned int sampler, FilterType textureFilter);

-		virtual void setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter);

-		virtual void setGatherEnable(unsigned int sampler, bool enable);

-		virtual void setAddressingModeU(unsigned int sampler, AddressingMode addressingMode);

-		virtual void setAddressingModeV(unsigned int sampler, AddressingMode addressingMode);

-		virtual void setAddressingModeW(unsigned int sampler, AddressingMode addressingMode);

-		virtual void setReadSRGB(unsigned int sampler, bool sRGB);

-		virtual void setMipmapLOD(unsigned int sampler, float bias);

-		virtual void setBorderColor(unsigned int sampler, const Color<float> &borderColor);

-		virtual void setMaxAnisotropy(unsigned int sampler, float maxAnisotropy);

-		virtual void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);

-		virtual void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);

-		virtual void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);

-		virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);

-

-		virtual void setWriteSRGB(bool sRGB);

-		virtual void setDepthBufferEnable(bool depthBufferEnable);

-		virtual void setDepthCompare(DepthCompareMode depthCompareMode);

-		virtual void setAlphaCompare(AlphaCompareMode alphaCompareMode);

-		virtual void setDepthWriteEnable(bool depthWriteEnable);

-		virtual void setAlphaTestEnable(bool alphaTestEnable);

-		virtual void setCullMode(CullMode cullMode);

-		virtual void setColorWriteMask(int index, int rgbaMask);

-

-		virtual void setColorLogicOpEnabled(bool colorLogicOpEnabled);

-		virtual void setLogicalOperation(LogicalOperation logicalOperation);

-

-		virtual void setStencilEnable(bool stencilEnable);

-		virtual void setStencilCompare(StencilCompareMode stencilCompareMode);

-		virtual void setStencilReference(int stencilReference);

-		virtual void setStencilMask(int stencilMask);

-		virtual void setStencilFailOperation(StencilOperation stencilFailOperation);

-		virtual void setStencilPassOperation(StencilOperation stencilPassOperation);

-		virtual void setStencilZFailOperation(StencilOperation stencilZFailOperation);

-		virtual void setStencilWriteMask(int stencilWriteMask);

-		virtual void setTwoSidedStencil(bool enable);

-		virtual void setStencilCompareCCW(StencilCompareMode stencilCompareMode);

-		virtual void setStencilReferenceCCW(int stencilReference);

-		virtual void setStencilMaskCCW(int stencilMask);

-		virtual void setStencilFailOperationCCW(StencilOperation stencilFailOperation);

-		virtual void setStencilPassOperationCCW(StencilOperation stencilPassOperation);

-		virtual void setStencilZFailOperationCCW(StencilOperation stencilZFailOperation);

-		virtual void setStencilWriteMaskCCW(int stencilWriteMask);

-

-		virtual void setTextureFactor(const Color<float> &textureFactor);

-		virtual void setBlendConstant(const Color<float> &blendConstant);

-

-		virtual void setFillMode(FillMode fillMode);

-		virtual void setShadingMode(ShadingMode shadingMode);

-		

-		virtual void setAlphaBlendEnable(bool alphaBlendEnable);

-		virtual void setSourceBlendFactor(BlendFactor sourceBlendFactor);

-		virtual void setDestBlendFactor(BlendFactor destBlendFactor);

-		virtual void setBlendOperation(BlendOperation blendOperation);

-

-		virtual void setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable);

-		virtual void setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha);

-		virtual void setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha);

-		virtual void setBlendOperationAlpha(BlendOperation blendOperationAlpha);

-

-		virtual void setAlphaReference(float alphaReference);

-

-		virtual void setGlobalMipmapBias(float bias);

-

-		virtual void setFogStart(float start);

-		virtual void setFogEnd(float end);

-		virtual void setFogColor(Color<float> fogColor);

-		virtual void setFogDensity(float fogDensity);

-		virtual void setPixelFogMode(FogMode fogMode);

-

-		virtual void setPerspectiveCorrection(bool perspectiveCorrection);

-

-		virtual void setOcclusionEnabled(bool enable);

-

-	protected:

-		const State update() const;

-		Routine *routine(const State &state);

-		void setRoutineCacheSize(int routineCacheSize);

-

-		// Shader constants

-		word4 cW[8][4];

-		float4 c[FRAGMENT_UNIFORM_VECTORS];

-		int4 i[16];

-		bool b[16];

-

-		// Other semi-constants

-		Stencil stencil;

-		Stencil stencilCCW;

-		Fog fog;

-		Factor factor;

-

-	private:

-		struct UniformBufferInfo

-		{

-			UniformBufferInfo();

-

-			Resource* buffer;

-			int offset;

-		};

-		UniformBufferInfo uniformBufferInfo[MAX_UNIFORM_BUFFER_BINDINGS];

-

-		void setFogRanges(float start, float end);

-

-		Context *const context;

-

-		RoutineCache<State> *routineCache;

-	};

-}

-

-#endif   // sw_PixelProcessor_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_PixelProcessor_hpp
+#define sw_PixelProcessor_hpp
+
+#include "Context.hpp"
+#include "RoutineCache.hpp"
+
+namespace sw
+{
+	class PixelShader;
+	class Rasterizer;
+	struct Texture;
+	struct DrawData;
+
+	class PixelProcessor
+	{
+	public:
+		struct States
+		{
+			unsigned int computeHash();
+
+			int shaderID;
+
+			bool depthOverride                        : 1;
+			bool shaderContainsKill                   : 1;
+
+			DepthCompareMode depthCompareMode         : BITS(DEPTH_LAST);
+			AlphaCompareMode alphaCompareMode         : BITS(ALPHA_LAST);
+			bool depthWriteEnable                     : 1;
+			bool quadLayoutDepthBuffer                : 1;
+
+			bool stencilActive                        : 1;
+			StencilCompareMode stencilCompareMode     : BITS(STENCIL_LAST);
+			StencilOperation stencilFailOperation     : BITS(OPERATION_LAST);
+			StencilOperation stencilPassOperation     : BITS(OPERATION_LAST);
+			StencilOperation stencilZFailOperation    : BITS(OPERATION_LAST);
+			bool noStencilMask                        : 1;
+			bool noStencilWriteMask                   : 1;
+			bool stencilWriteMasked                   : 1;
+			bool twoSidedStencil                      : 1;
+			StencilCompareMode stencilCompareModeCCW  : BITS(STENCIL_LAST);
+			StencilOperation stencilFailOperationCCW  : BITS(OPERATION_LAST);
+			StencilOperation stencilPassOperationCCW  : BITS(OPERATION_LAST);
+			StencilOperation stencilZFailOperationCCW : BITS(OPERATION_LAST);
+			bool noStencilMaskCCW                     : 1;
+			bool noStencilWriteMaskCCW                : 1;
+			bool stencilWriteMaskedCCW                : 1;
+
+			bool depthTestActive                      : 1;
+			bool fogActive                            : 1;
+			FogMode pixelFogMode                      : BITS(FOG_LAST);
+			bool specularAdd                          : 1;
+			bool occlusionEnabled                     : 1;
+			bool wBasedFog                            : 1;
+			bool perspective                          : 1;
+
+			bool alphaBlendActive                     : 1;
+			BlendFactor sourceBlendFactor             : BITS(BLEND_LAST);
+			BlendFactor destBlendFactor               : BITS(BLEND_LAST);
+			BlendOperation blendOperation             : BITS(BLENDOP_LAST);
+			BlendFactor sourceBlendFactorAlpha        : BITS(BLEND_LAST);
+			BlendFactor destBlendFactorAlpha          : BITS(BLEND_LAST);
+			BlendOperation blendOperationAlpha        : BITS(BLENDOP_LAST);
+
+			unsigned int colorWriteMask                       : RENDERTARGETS * 4;   // Four component bit masks
+			Format targetFormat[RENDERTARGETS];
+			bool writeSRGB                                    : 1;
+			unsigned int multiSample                          : 3;
+			unsigned int multiSampleMask                      : 4;
+			TransparencyAntialiasing transparencyAntialiasing : BITS(TRANSPARENCY_LAST);
+			bool centroid                                     : 1;
+
+			LogicalOperation logicalOperation : BITS(LOGICALOP_LAST);
+
+			Sampler::State sampler[TEXTURE_IMAGE_UNITS];
+			TextureStage::State textureStage[8];
+
+			struct Interpolant
+			{
+				unsigned char component : 4;
+				unsigned char flat : 4;
+				unsigned char project : 2;
+				bool centroid : 1;
+			};
+
+			union
+			{
+				struct
+				{
+					Interpolant color[2];
+					Interpolant texture[8];
+				};
+
+				Interpolant interpolant[10];
+			};
+
+			Interpolant fog;
+		};
+
+		struct State : States
+		{
+			State();
+
+			bool operator==(const State &state) const;
+
+			int colorWriteActive(int index) const
+			{
+				return (colorWriteMask >> (index * 4)) & 0xF;
+			}
+
+			bool alphaTestActive() const
+			{
+				return alphaCompareMode != ALPHA_ALWAYS;
+			}
+
+			bool pixelFogActive() const
+			{
+				return pixelFogMode != FOG_NONE;
+			}
+
+			unsigned int hash;
+		};
+
+		struct Stencil
+		{
+			int64_t testMaskQ;
+			int64_t referenceMaskedQ;
+			int64_t referenceMaskedSignedQ;
+			int64_t writeMaskQ;
+			int64_t invWriteMaskQ;
+			int64_t referenceQ;
+
+			void set(int reference, int testMask, int writeMask)
+			{
+				referenceQ = replicate(reference);
+				testMaskQ = replicate(testMask);
+				writeMaskQ = replicate(writeMask);
+				invWriteMaskQ = ~writeMaskQ;
+				referenceMaskedQ = referenceQ & testMaskQ;
+				referenceMaskedSignedQ = replicate((reference + 0x80) & 0xFF & testMask);
+			}
+
+			static int64_t replicate(int b)
+			{
+				int64_t w = b & 0xFF;
+
+				return (w << 0) | (w << 8) | (w << 16) | (w << 24) | (w << 32) | (w << 40) | (w << 48) | (w << 56);
+			}
+		};
+
+		struct Fog
+		{
+			float4 scale;
+			float4 offset;
+			word4 color4[3];
+			float4 colorF[3];
+			float4 densityE;
+			float4 density2E;
+		};
+
+		struct Factor
+		{
+			word4 textureFactor4[4];
+
+			word4 alphaReference4;
+
+			word4 blendConstant4W[4];
+			float4 blendConstant4F[4];
+			word4 invBlendConstant4W[4];
+			float4 invBlendConstant4F[4];
+		};
+
+	public:
+		typedef void (*RoutinePointer)(const Primitive *primitive, int count, int thread, DrawData *draw);
+
+		PixelProcessor(Context *context);
+
+		virtual ~PixelProcessor();
+
+		virtual void setFloatConstant(unsigned int index, const float value[4]);
+		virtual void setIntegerConstant(unsigned int index, const int value[4]);
+		virtual void setBooleanConstant(unsigned int index, int boolean);
+
+		virtual void setUniformBuffer(int index, sw::Resource* buffer, int offset);
+		virtual void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);
+
+		virtual void setRenderTarget(int index, Surface *renderTarget);
+		virtual void setDepthBuffer(Surface *depthBuffer);
+		virtual void setStencilBuffer(Surface *stencilBuffer);
+
+		virtual void setTexCoordIndex(unsigned int stage, int texCoordIndex);
+		virtual void setStageOperation(unsigned int stage, TextureStage::StageOperation stageOperation);
+		virtual void setFirstArgument(unsigned int stage, TextureStage::SourceArgument firstArgument);
+		virtual void setSecondArgument(unsigned int stage, TextureStage::SourceArgument secondArgument);
+		virtual void setThirdArgument(unsigned int stage, TextureStage::SourceArgument thirdArgument);
+		virtual void setStageOperationAlpha(unsigned int stage, TextureStage::StageOperation stageOperationAlpha);
+		virtual void setFirstArgumentAlpha(unsigned int stage, TextureStage::SourceArgument firstArgumentAlpha);
+		virtual void setSecondArgumentAlpha(unsigned int stage, TextureStage::SourceArgument secondArgumentAlpha);
+		virtual void setThirdArgumentAlpha(unsigned int stage, TextureStage::SourceArgument thirdArgumentAlpha);
+		virtual void setFirstModifier(unsigned int stage, TextureStage::ArgumentModifier firstModifier);
+		virtual void setSecondModifier(unsigned int stage, TextureStage::ArgumentModifier secondModifier);
+		virtual void setThirdModifier(unsigned int stage, TextureStage::ArgumentModifier thirdModifier);
+		virtual void setFirstModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier firstModifierAlpha);
+		virtual void setSecondModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier secondModifierAlpha);
+		virtual void setThirdModifierAlpha(unsigned int stage, TextureStage::ArgumentModifier thirdModifierAlpha);
+		virtual void setDestinationArgument(unsigned int stage, TextureStage::DestinationArgument destinationArgument);
+		virtual void setConstantColor(unsigned int stage, const Color<float> &constantColor);
+		virtual void setBumpmapMatrix(unsigned int stage, int element, float value);
+		virtual void setLuminanceScale(unsigned int stage, float value);
+		virtual void setLuminanceOffset(unsigned int stage, float value);
+
+		virtual void setTextureFilter(unsigned int sampler, FilterType textureFilter);
+		virtual void setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter);
+		virtual void setGatherEnable(unsigned int sampler, bool enable);
+		virtual void setAddressingModeU(unsigned int sampler, AddressingMode addressingMode);
+		virtual void setAddressingModeV(unsigned int sampler, AddressingMode addressingMode);
+		virtual void setAddressingModeW(unsigned int sampler, AddressingMode addressingMode);
+		virtual void setReadSRGB(unsigned int sampler, bool sRGB);
+		virtual void setMipmapLOD(unsigned int sampler, float bias);
+		virtual void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
+		virtual void setMaxAnisotropy(unsigned int sampler, float maxAnisotropy);
+		virtual void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
+		virtual void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
+		virtual void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
+		virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
+
+		virtual void setWriteSRGB(bool sRGB);
+		virtual void setDepthBufferEnable(bool depthBufferEnable);
+		virtual void setDepthCompare(DepthCompareMode depthCompareMode);
+		virtual void setAlphaCompare(AlphaCompareMode alphaCompareMode);
+		virtual void setDepthWriteEnable(bool depthWriteEnable);
+		virtual void setAlphaTestEnable(bool alphaTestEnable);
+		virtual void setCullMode(CullMode cullMode);
+		virtual void setColorWriteMask(int index, int rgbaMask);
+
+		virtual void setColorLogicOpEnabled(bool colorLogicOpEnabled);
+		virtual void setLogicalOperation(LogicalOperation logicalOperation);
+
+		virtual void setStencilEnable(bool stencilEnable);
+		virtual void setStencilCompare(StencilCompareMode stencilCompareMode);
+		virtual void setStencilReference(int stencilReference);
+		virtual void setStencilMask(int stencilMask);
+		virtual void setStencilFailOperation(StencilOperation stencilFailOperation);
+		virtual void setStencilPassOperation(StencilOperation stencilPassOperation);
+		virtual void setStencilZFailOperation(StencilOperation stencilZFailOperation);
+		virtual void setStencilWriteMask(int stencilWriteMask);
+		virtual void setTwoSidedStencil(bool enable);
+		virtual void setStencilCompareCCW(StencilCompareMode stencilCompareMode);
+		virtual void setStencilReferenceCCW(int stencilReference);
+		virtual void setStencilMaskCCW(int stencilMask);
+		virtual void setStencilFailOperationCCW(StencilOperation stencilFailOperation);
+		virtual void setStencilPassOperationCCW(StencilOperation stencilPassOperation);
+		virtual void setStencilZFailOperationCCW(StencilOperation stencilZFailOperation);
+		virtual void setStencilWriteMaskCCW(int stencilWriteMask);
+
+		virtual void setTextureFactor(const Color<float> &textureFactor);
+		virtual void setBlendConstant(const Color<float> &blendConstant);
+
+		virtual void setFillMode(FillMode fillMode);
+		virtual void setShadingMode(ShadingMode shadingMode);
+	
+		virtual void setAlphaBlendEnable(bool alphaBlendEnable);
+		virtual void setSourceBlendFactor(BlendFactor sourceBlendFactor);
+		virtual void setDestBlendFactor(BlendFactor destBlendFactor);
+		virtual void setBlendOperation(BlendOperation blendOperation);
+
+		virtual void setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable);
+		virtual void setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha);
+		virtual void setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha);
+		virtual void setBlendOperationAlpha(BlendOperation blendOperationAlpha);
+
+		virtual void setAlphaReference(float alphaReference);
+
+		virtual void setGlobalMipmapBias(float bias);
+
+		virtual void setFogStart(float start);
+		virtual void setFogEnd(float end);
+		virtual void setFogColor(Color<float> fogColor);
+		virtual void setFogDensity(float fogDensity);
+		virtual void setPixelFogMode(FogMode fogMode);
+
+		virtual void setPerspectiveCorrection(bool perspectiveCorrection);
+
+		virtual void setOcclusionEnabled(bool enable);
+
+	protected:
+		const State update() const;
+		Routine *routine(const State &state);
+		void setRoutineCacheSize(int routineCacheSize);
+
+		// Shader constants
+		word4 cW[8][4];
+		float4 c[FRAGMENT_UNIFORM_VECTORS];
+		int4 i[16];
+		bool b[16];
+
+		// Other semi-constants
+		Stencil stencil;
+		Stencil stencilCCW;
+		Fog fog;
+		Factor factor;
+
+	private:
+		struct UniformBufferInfo
+		{
+			UniformBufferInfo();
+
+			Resource* buffer;
+			int offset;
+		};
+		UniformBufferInfo uniformBufferInfo[MAX_UNIFORM_BUFFER_BINDINGS];
+
+		void setFogRanges(float start, float end);
+
+		Context *const context;
+
+		RoutineCache<State> *routineCache;
+	};
+}
+
+#endif   // sw_PixelProcessor_hpp
diff --git a/src/Renderer/Plane.cpp b/src/Renderer/Plane.cpp
index ab9ea77..095b7f2 100644
--- a/src/Renderer/Plane.cpp
+++ b/src/Renderer/Plane.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Plane.hpp"
 
diff --git a/src/Renderer/Plane.hpp b/src/Renderer/Plane.hpp
index f831339..962b9ae 100644
--- a/src/Renderer/Plane.hpp
+++ b/src/Renderer/Plane.hpp
@@ -1,37 +1,40 @@
-// 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.

-//

-

-#ifndef Plane_hpp

-#define Plane_hpp

-

-#include "Vector.hpp"

-

-namespace sw

-{

-	struct Matrix;

-

-	struct Plane

-	{

-		float A;

-		float B;

-		float C;

-		float D;

-

-		Plane();

-		Plane(float A, float B, float C, float D);   // Plane equation 

-		Plane(const float ABCD[4]);

-

-		friend Plane operator*(const Plane &p, const Matrix &A);   // Transform plane by matrix (post-multiply)

-		friend Plane operator*(const Matrix &A, const Plane &p);   // Transform plane by matrix (pre-multiply)

-	};

-}

-

-#endif   // Plane_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef Plane_hpp
+#define Plane_hpp
+
+#include "Vector.hpp"
+
+namespace sw
+{
+	struct Matrix;
+
+	struct Plane
+	{
+		float A;
+		float B;
+		float C;
+		float D;
+
+		Plane();
+		Plane(float A, float B, float C, float D);   // Plane equation 
+		Plane(const float ABCD[4]);
+
+		friend Plane operator*(const Plane &p, const Matrix &A);   // Transform plane by matrix (post-multiply)
+		friend Plane operator*(const Matrix &A, const Plane &p);   // Transform plane by matrix (pre-multiply)
+	};
+}
+
+#endif   // Plane_hpp
diff --git a/src/Renderer/Point.cpp b/src/Renderer/Point.cpp
index 93355f1..e7e33dd 100644
--- a/src/Renderer/Point.cpp
+++ b/src/Renderer/Point.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Point.hpp"
 
diff --git a/src/Renderer/Point.hpp b/src/Renderer/Point.hpp
index 7b50f58..85198c5 100644
--- a/src/Renderer/Point.hpp
+++ b/src/Renderer/Point.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef Point_hpp
 #define Point_hpp
@@ -32,7 +35,7 @@
 			float p[3];
 
 			struct
-			{		
+			{	
 				float x;
 				float y;
 				float z;
diff --git a/src/Renderer/Polygon.hpp b/src/Renderer/Polygon.hpp
index db41627..0b94132 100644
--- a/src/Renderer/Polygon.hpp
+++ b/src/Renderer/Polygon.hpp
@@ -1,51 +1,54 @@
-// 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.

-//

-

-#ifndef sw_Polygon_hpp

-#define sw_Polygon_hpp

-

-#include "Vertex.hpp"

-

-namespace sw

-{

-	struct Polygon

-	{

-		Polygon(const float4 *P0, const float4 *P1, const float4 *P2)

-		{

-			P[0][0] = P0;

-			P[0][1] = P1;

-			P[0][2] = P2;

-

-			n = 3;

-			i = 0;

-		}

-

-		Polygon(const float4 *P, int n)

-		{

-			for(int i = 0; i < n; i++)

-			{

-				this->P[0][i] = &P[i];

-			}

-

-			this->n = n;

-			this->i = 0;

-		}

-

-		float4 B[16];              // Buffer for clipped vertices

-		const float4 *P[16][16];   // Pointers to clipped polygon's vertices

-

-		int i;

-		int b;

-		int n;

-	};

-}

-

-#endif   // sw_Polygon_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Polygon_hpp
+#define sw_Polygon_hpp
+
+#include "Vertex.hpp"
+
+namespace sw
+{
+	struct Polygon
+	{
+		Polygon(const float4 *P0, const float4 *P1, const float4 *P2)
+		{
+			P[0][0] = P0;
+			P[0][1] = P1;
+			P[0][2] = P2;
+
+			n = 3;
+			i = 0;
+		}
+
+		Polygon(const float4 *P, int n)
+		{
+			for(int i = 0; i < n; i++)
+			{
+				this->P[0][i] = &P[i];
+			}
+
+			this->n = n;
+			this->i = 0;
+		}
+
+		float4 B[16];              // Buffer for clipped vertices
+		const float4 *P[16][16];   // Pointers to clipped polygon's vertices
+
+		int i;
+		int b;
+		int n;
+	};
+}
+
+#endif   // sw_Polygon_hpp
diff --git a/src/Renderer/Primitive.hpp b/src/Renderer/Primitive.hpp
index ac37814..83e3a77 100644
--- a/src/Renderer/Primitive.hpp
+++ b/src/Renderer/Primitive.hpp
@@ -1,76 +1,79 @@
-// 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.

-//

-

-#ifndef sw_Primitive_hpp

-#define sw_Primitive_hpp

-

-#include "Vertex.hpp"

-#include "Config.hpp"

-

-namespace sw

-{

-	struct Triangle

-	{

-		Vertex v0;

-		Vertex v1;

-		Vertex v2;

-	};

-

-	struct PlaneEquation   // z = A * x + B * y + C

-	{

-		float4 A;

-		float4 B;

-		float4 C;

-	};

-

-	struct Primitive

-	{

-		int yMin;

-		int yMax;

-

-		float4 xQuad;

-		float4 yQuad;

-

-		PlaneEquation z;

-		PlaneEquation w;

-

-		union

-		{

-			struct

-			{

-				PlaneEquation C[2][4];

-				PlaneEquation T[8][4];

-			};

-

-			PlaneEquation V[10][4];

-		};

-

-		PlaneEquation f;

-

-		float area;

-

-		// Masks for two-sided stencil

-		int64_t clockwiseMask;

-		int64_t invClockwiseMask;

-

-		struct Span

-		{

-			unsigned short left;

-			unsigned short right;

-		};

-

-		Span outlineUnderflow;

-		Span outline[OUTLINE_RESOLUTION];

-		Span outlineOverflow;

-	};

-}

-

-#endif   // sw_Primitive_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Primitive_hpp
+#define sw_Primitive_hpp
+
+#include "Vertex.hpp"
+#include "Config.hpp"
+
+namespace sw
+{
+	struct Triangle
+	{
+		Vertex v0;
+		Vertex v1;
+		Vertex v2;
+	};
+
+	struct PlaneEquation   // z = A * x + B * y + C
+	{
+		float4 A;
+		float4 B;
+		float4 C;
+	};
+
+	struct Primitive
+	{
+		int yMin;
+		int yMax;
+
+		float4 xQuad;
+		float4 yQuad;
+
+		PlaneEquation z;
+		PlaneEquation w;
+
+		union
+		{
+			struct
+			{
+				PlaneEquation C[2][4];
+				PlaneEquation T[8][4];
+			};
+
+			PlaneEquation V[10][4];
+		};
+
+		PlaneEquation f;
+
+		float area;
+
+		// Masks for two-sided stencil
+		int64_t clockwiseMask;
+		int64_t invClockwiseMask;
+
+		struct Span
+		{
+			unsigned short left;
+			unsigned short right;
+		};
+
+		Span outlineUnderflow;
+		Span outline[OUTLINE_RESOLUTION];
+		Span outlineOverflow;
+	};
+}
+
+#endif   // sw_Primitive_hpp
diff --git a/src/Renderer/QuadRasterizer.cpp b/src/Renderer/QuadRasterizer.cpp
index 6e390b0..5bc500f 100644
--- a/src/Renderer/QuadRasterizer.cpp
+++ b/src/Renderer/QuadRasterizer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "QuadRasterizer.hpp"
 
diff --git a/src/Renderer/QuadRasterizer.hpp b/src/Renderer/QuadRasterizer.hpp
index 7d307a4..51d578d 100644
--- a/src/Renderer/QuadRasterizer.hpp
+++ b/src/Renderer/QuadRasterizer.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_QuadRasterizer_hpp
 #define sw_QuadRasterizer_hpp
diff --git a/src/Renderer/Rasterizer.hpp b/src/Renderer/Rasterizer.hpp
index 7e3a857..3c746c8 100644
--- a/src/Renderer/Rasterizer.hpp
+++ b/src/Renderer/Rasterizer.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_Rasterizer_hpp
 #define sw_Rasterizer_hpp
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index a77ec3b..40d9de6 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Renderer.hpp"
 
@@ -834,7 +837,7 @@
 		case Task::PRIMITIVES:
 			{
 				int unit = task[threadIndex].primitiveUnit;
-				
+			
 				int input = primitiveProgress[unit].firstPrimitive;
 				int count = primitiveProgress[unit].primitiveCount;
 				DrawCall *draw = drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
@@ -1434,7 +1437,7 @@
 				}
 			}
 			break;
-        case DRAW_QUADLIST:
+		case DRAW_QUADLIST:
 			{
 				unsigned int index = 4 * start / 2;
 
@@ -1444,7 +1447,7 @@
 					batch[i+0][1] = index + 1;
 					batch[i+0][2] = index + 2;
 
-                    batch[i+1][0] = index + 0;
+					batch[i+1][0] = index + 0;
 					batch[i+1][1] = index + 2;
 					batch[i+1][2] = index + 3;
 
@@ -1457,11 +1460,11 @@
 			return;
 		}
 
-		task->vertexStart = start * 3;

-		task->vertexCount = triangleCount * 3;

-		// Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,

-		//       which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.

-		DrawType type = static_cast<DrawType>(static_cast<unsigned int>(draw->drawType) & 0xF);

+		task->vertexStart = start * 3;
+		task->vertexCount = triangleCount * 3;
+		// Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
+		//       which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
+		DrawType type = static_cast<DrawType>(static_cast<unsigned int>(draw->drawType) & 0xF);
 		task->verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
 		vertexRoutine(&triangle->v0, (unsigned int*)&batch, task, data);
 	}
@@ -1944,12 +1947,12 @@
 	unsigned int Renderer::computeClipFlags(const float4 &v, const DrawData &data)
 	{
 		return ((v.x > v.w)  << 0) |
-			   ((v.y > v.w)  << 1) |
-			   ((v.z > v.w)  << 2) |
-			   ((v.x < -v.w) << 3) |
+		       ((v.y > v.w)  << 1) |
+		       ((v.z > v.w)  << 2) |
+		       ((v.x < -v.w) << 3) |
 		       ((v.y < -v.w) << 4) |
-			   ((v.z < 0)    << 5) |
-			   Clipper::CLIP_FINITE;   // FIXME: xyz finite
+		       ((v.z < 0)    << 5) |
+		       Clipper::CLIP_FINITE;   // FIXME: xyz finite
 	}
 
 	void Renderer::initializeThreads()
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index e0b9141..4b3abbe 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_Renderer_hpp
 #define sw_Renderer_hpp
diff --git a/src/Renderer/RoutineCache.hpp b/src/Renderer/RoutineCache.hpp
index 5e421e8..8965a1c 100644
--- a/src/Renderer/RoutineCache.hpp
+++ b/src/Renderer/RoutineCache.hpp
@@ -1,172 +1,175 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_RoutineCache_hpp

-#define sw_RoutineCache_hpp

-

-#include "LRUCache.hpp"

-

-#include "Reactor/Reactor.hpp"

-

-namespace sw

-{

-	template<class State>

-	class RoutineCache : public LRUCache<State, Routine>

-	{

-	public:

-		RoutineCache(int n, const char *precache = 0);

-		~RoutineCache();

-

-	private:

-		const char *precache;

-		#if defined(_WIN32)

-		HMODULE precacheDLL;

-		#endif

-	};

-}

-

-#if defined(_WIN32)

-	#include "Shader/Constants.hpp"

-	#include "Reactor/DLL.hpp"

-#endif

-

-namespace sw

-{

-	template<class State>

-	RoutineCache<State>::RoutineCache(int n, const char *precache) : LRUCache<State, Routine>(n), precache(precache)

-	{

-		#if defined(_WIN32)

-			precacheDLL = 0;

-

-			if(precache)

-			{

-				char dllName[1024]; sprintf(dllName, "%s.dll", precache);

-				char dirName[1024]; sprintf(dirName, "%s.dir", precache);

-

-				precacheDLL = LoadLibrary(dllName);

-				FILE *dir = fopen(dirName, "rb");

-				int ordinal = 1;

-

-				while(precacheDLL && dir)

-				{

-					State state;

-					int offset;

-					int size;

-

-					size_t bytes = fread(&state, 1, sizeof(State), dir);

-					bytes += fread(&offset, 1, sizeof(offset), dir);

-					bytes += fread(&size, 1, sizeof(size), dir);

-

-					if(bytes != sizeof(State) + sizeof(offset) + sizeof(size))

-					{

-						break;

-					}

-

-					void (*routine)(void) = (void(*)(void))GetProcAddress(precacheDLL, (char*)ordinal);

-					ordinal++;

-

-					if(routine)

-					{

-						add(state, new Routine(routine, size, offset));

-					}

-				}

-

-				if(dir)

-				{

-					fclose(dir);

-				}

-			}

-		#endif

-	}

-

-	template<class State>

-	RoutineCache<State>::~RoutineCache()

-	{

-		#if defined(_WIN32)

-			char dllName[1024]; sprintf(dllName, "%s.dll", precache);

-			char dirName[1024]; sprintf(dirName, "%s.dir", precache);

-

-			if(precache)

-			{

-				DLL dll(dllName, &constants, sizeof(Constants));

-				FILE *dir = fopen(dirName, "wb");

-

-				for(int i = 0; i < getSize(); i++)

-				{

-					State &state = getKey(i);

-					Routine *routine = query(state);

-

-					if(routine)

-					{

-						unsigned char *buffer = (unsigned char*)routine->getBuffer();

-						unsigned char *entry = (unsigned char*)routine->getEntry();

-						int size = routine->getBufferSize();

-						int codeSize = routine->getCodeSize();

-

-						#ifndef _M_AMD64

-							for(int j = 1; j < codeSize - 4; j++)

-							{

-								unsigned char modRM_SIB = entry[j - 1];

-								unsigned int address = *(unsigned int*)&entry[j];

-

-								if((modRM_SIB & 0x05) == 0x05 && (address % 4) == 0)

-								{

-									if(address >= (unsigned int)buffer && address < (unsigned int)entry)   // Constant stored above the function entry

-									{

-										dll.addRelocation(buffer, &entry[j], true);

-

-										j += 4;

-									}

-								}

-							}

-						#else

-							for(int j = 1; j < codeSize - 4; j++)

-							{

-								unsigned char modRM_SIB = entry[j - 1];

-								uint64_t address = *(uint64_t*)&entry[j];

-

-							//	if((modRM_SIB & 0x05) == 0x05 && (address % 4) == 0)

-								{

-									if(address >= (uint64_t)buffer && address < (uint64_t)entry)   // Constant stored above the function entry

-									{

-										dll.addRelocation(buffer, &entry[j], true);

-

-										j += 4;

-									}

-								}

-							}

-						#endif

-

-						dll.addFunction(buffer, entry, size);

-						fwrite(&state, 1, sizeof(State), dir);

-						int offset = (int)(entry - buffer);

-						fwrite(&offset, 1, sizeof(offset), dir);

-						fwrite(&size, 1, sizeof(size), dir);

-					}

-				}

-

-				FreeLibrary(precacheDLL);

-

-				dll.emit();

-				fclose(dir);

-			}

-			else

-			{

-				FreeLibrary(precacheDLL);

-

-				remove(dllName);

-				remove(dirName);

-			}

-		#endif

-	}

-}

-

-#endif   // sw_RoutineCache_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_RoutineCache_hpp
+#define sw_RoutineCache_hpp
+
+#include "LRUCache.hpp"
+
+#include "Reactor/Reactor.hpp"
+
+namespace sw
+{
+	template<class State>
+	class RoutineCache : public LRUCache<State, Routine>
+	{
+	public:
+		RoutineCache(int n, const char *precache = 0);
+		~RoutineCache();
+
+	private:
+		const char *precache;
+		#if defined(_WIN32)
+		HMODULE precacheDLL;
+		#endif
+	};
+}
+
+#if defined(_WIN32)
+	#include "Shader/Constants.hpp"
+	#include "Reactor/DLL.hpp"
+#endif
+
+namespace sw
+{
+	template<class State>
+	RoutineCache<State>::RoutineCache(int n, const char *precache) : LRUCache<State, Routine>(n), precache(precache)
+	{
+		#if defined(_WIN32)
+			precacheDLL = 0;
+
+			if(precache)
+			{
+				char dllName[1024]; sprintf(dllName, "%s.dll", precache);
+				char dirName[1024]; sprintf(dirName, "%s.dir", precache);
+
+				precacheDLL = LoadLibrary(dllName);
+				FILE *dir = fopen(dirName, "rb");
+				int ordinal = 1;
+
+				while(precacheDLL && dir)
+				{
+					State state;
+					int offset;
+					int size;
+
+					size_t bytes = fread(&state, 1, sizeof(State), dir);
+					bytes += fread(&offset, 1, sizeof(offset), dir);
+					bytes += fread(&size, 1, sizeof(size), dir);
+
+					if(bytes != sizeof(State) + sizeof(offset) + sizeof(size))
+					{
+						break;
+					}
+
+					void (*routine)(void) = (void(*)(void))GetProcAddress(precacheDLL, (char*)ordinal);
+					ordinal++;
+
+					if(routine)
+					{
+						add(state, new Routine(routine, size, offset));
+					}
+				}
+
+				if(dir)
+				{
+					fclose(dir);
+				}
+			}
+		#endif
+	}
+
+	template<class State>
+	RoutineCache<State>::~RoutineCache()
+	{
+		#if defined(_WIN32)
+			char dllName[1024]; sprintf(dllName, "%s.dll", precache);
+			char dirName[1024]; sprintf(dirName, "%s.dir", precache);
+
+			if(precache)
+			{
+				DLL dll(dllName, &constants, sizeof(Constants));
+				FILE *dir = fopen(dirName, "wb");
+
+				for(int i = 0; i < getSize(); i++)
+				{
+					State &state = getKey(i);
+					Routine *routine = query(state);
+
+					if(routine)
+					{
+						unsigned char *buffer = (unsigned char*)routine->getBuffer();
+						unsigned char *entry = (unsigned char*)routine->getEntry();
+						int size = routine->getBufferSize();
+						int codeSize = routine->getCodeSize();
+
+						#ifndef _M_AMD64
+							for(int j = 1; j < codeSize - 4; j++)
+							{
+								unsigned char modRM_SIB = entry[j - 1];
+								unsigned int address = *(unsigned int*)&entry[j];
+
+								if((modRM_SIB & 0x05) == 0x05 && (address % 4) == 0)
+								{
+									if(address >= (unsigned int)buffer && address < (unsigned int)entry)   // Constant stored above the function entry
+									{
+										dll.addRelocation(buffer, &entry[j], true);
+
+										j += 4;
+									}
+								}
+							}
+						#else
+							for(int j = 1; j < codeSize - 4; j++)
+							{
+								unsigned char modRM_SIB = entry[j - 1];
+								uint64_t address = *(uint64_t*)&entry[j];
+
+							//	if((modRM_SIB & 0x05) == 0x05 && (address % 4) == 0)
+								{
+									if(address >= (uint64_t)buffer && address < (uint64_t)entry)   // Constant stored above the function entry
+									{
+										dll.addRelocation(buffer, &entry[j], true);
+
+										j += 4;
+									}
+								}
+							}
+						#endif
+
+						dll.addFunction(buffer, entry, size);
+						fwrite(&state, 1, sizeof(State), dir);
+						int offset = (int)(entry - buffer);
+						fwrite(&offset, 1, sizeof(offset), dir);
+						fwrite(&size, 1, sizeof(size), dir);
+					}
+				}
+
+				FreeLibrary(precacheDLL);
+
+				dll.emit();
+				fclose(dir);
+			}
+			else
+			{
+				FreeLibrary(precacheDLL);
+
+				remove(dllName);
+				remove(dirName);
+			}
+		#endif
+	}
+}
+
+#endif   // sw_RoutineCache_hpp
diff --git a/src/Renderer/Sampler.cpp b/src/Renderer/Sampler.cpp
index f446467..7518715 100644
--- a/src/Renderer/Sampler.cpp
+++ b/src/Renderer/Sampler.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Sampler.hpp"
 
@@ -227,7 +230,7 @@
 					unsigned int YStride = pitchP;
 					unsigned int YSize = YStride * height;
 					unsigned int CStride = align(YStride / 2, 16);
- 					unsigned int CSize = CStride * height / 2;
+					unsigned int CSize = CStride * height / 2;
 
 					mipmap.buffer[1] = (byte*)mipmap.buffer[0] + YSize;
 					mipmap.buffer[2] = (byte*)mipmap.buffer[1] + CSize;
@@ -357,8 +360,8 @@
 	{
 		return Surface::isUnsignedComponent(internalTextureFormat, 0) &&
 		       Surface::isUnsignedComponent(internalTextureFormat, 1) &&
-			   Surface::isUnsignedComponent(internalTextureFormat, 2) &&
-			   Surface::isUnsignedComponent(internalTextureFormat, 3);
+		       Surface::isUnsignedComponent(internalTextureFormat, 2) &&
+		       Surface::isUnsignedComponent(internalTextureFormat, 3);
 	}
 
 	bool Sampler::hasCubeTexture() const
diff --git a/src/Renderer/Sampler.hpp b/src/Renderer/Sampler.hpp
index 9580f09..edaa8e1 100644
--- a/src/Renderer/Sampler.hpp
+++ b/src/Renderer/Sampler.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_Sampler_hpp
 #define sw_Sampler_hpp
diff --git a/src/Renderer/SetupProcessor.cpp b/src/Renderer/SetupProcessor.cpp
index 6d4d7cb..1bedf79 100644
--- a/src/Renderer/SetupProcessor.cpp
+++ b/src/Renderer/SetupProcessor.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "SetupProcessor.hpp"
 
diff --git a/src/Renderer/SetupProcessor.hpp b/src/Renderer/SetupProcessor.hpp
index 02133f0..06e4ce9 100644
--- a/src/Renderer/SetupProcessor.hpp
+++ b/src/Renderer/SetupProcessor.hpp
@@ -1,106 +1,109 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_SetupProcessor_hpp

-#define sw_SetupProcessor_hpp

-

-#include "Context.hpp"

-#include "RoutineCache.hpp"

-#include "Shader/VertexShader.hpp"

-#include "Shader/PixelShader.hpp"

-#include "Common/Types.hpp"

-

-namespace sw

-{

-	struct Primitive;

-	struct Triangle;

-	struct Polygon;

-	struct Vertex;

-	struct DrawCall;

-	struct DrawData;

-

-	class SetupProcessor

-	{

-	public:

-		struct States

-		{

-			unsigned int computeHash();

-

-			bool isDrawPoint               : 1;

-			bool isDrawLine                : 1;

-			bool isDrawTriangle            : 1;

-			bool isDrawSolidTriangle       : 1;

-			bool interpolateZ              : 1;

-			bool interpolateW              : 1;

-			bool perspective               : 1;

-			bool pointSprite               : 1;

-			unsigned int positionRegister  : 4;

-			unsigned int pointSizeRegister : 4;

-			CullMode cullMode              : BITS(CULL_LAST);

-			bool twoSidedStencil           : 1;

-			bool slopeDepthBias            : 1;

-			bool vFace                     : 1;

-			unsigned int multiSample       : 3;   // 1, 2 or 4

-			bool rasterizerDiscard         : 1;

-

-			struct Gradient

-			{

-				unsigned char attribute : BITS(Unused);

-				bool flat               : 1;

-				bool wrap               : 1;

-			};

-

-			union

-			{

-				struct

-				{

-					Gradient color[2][4];

-					Gradient texture[8][4];

-				};

-

-				Gradient gradient[10][4];

-			};

-

-			Gradient fog;

-		};

-

-		struct State : States

-		{

-			State(int i = 0);

-

-			bool operator==(const State &states) const;

-

-			unsigned int hash;

-		};

-

-		typedef bool (*RoutinePointer)(Primitive *primitive, const Triangle *triangle, const Polygon *polygon, const DrawData *draw);

-

-		SetupProcessor(Context *context);

-

-		~SetupProcessor();

-

-	protected:

-		State update() const;

-		Routine *routine(const State &state);

-

-		void setRoutineCacheSize(int cacheSize);

-

-		float depthBias;

-		float slopeDepthBias;

-

-	private:

-		Context *const context;

-

-		RoutineCache<State> *routineCache;

-	};

-}

-

-#endif   // sw_SetupProcessor_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_SetupProcessor_hpp
+#define sw_SetupProcessor_hpp
+
+#include "Context.hpp"
+#include "RoutineCache.hpp"
+#include "Shader/VertexShader.hpp"
+#include "Shader/PixelShader.hpp"
+#include "Common/Types.hpp"
+
+namespace sw
+{
+	struct Primitive;
+	struct Triangle;
+	struct Polygon;
+	struct Vertex;
+	struct DrawCall;
+	struct DrawData;
+
+	class SetupProcessor
+	{
+	public:
+		struct States
+		{
+			unsigned int computeHash();
+
+			bool isDrawPoint               : 1;
+			bool isDrawLine                : 1;
+			bool isDrawTriangle            : 1;
+			bool isDrawSolidTriangle       : 1;
+			bool interpolateZ              : 1;
+			bool interpolateW              : 1;
+			bool perspective               : 1;
+			bool pointSprite               : 1;
+			unsigned int positionRegister  : 4;
+			unsigned int pointSizeRegister : 4;
+			CullMode cullMode              : BITS(CULL_LAST);
+			bool twoSidedStencil           : 1;
+			bool slopeDepthBias            : 1;
+			bool vFace                     : 1;
+			unsigned int multiSample       : 3;   // 1, 2 or 4
+			bool rasterizerDiscard         : 1;
+
+			struct Gradient
+			{
+				unsigned char attribute : BITS(Unused);
+				bool flat               : 1;
+				bool wrap               : 1;
+			};
+
+			union
+			{
+				struct
+				{
+					Gradient color[2][4];
+					Gradient texture[8][4];
+				};
+
+				Gradient gradient[10][4];
+			};
+
+			Gradient fog;
+		};
+
+		struct State : States
+		{
+			State(int i = 0);
+
+			bool operator==(const State &states) const;
+
+			unsigned int hash;
+		};
+
+		typedef bool (*RoutinePointer)(Primitive *primitive, const Triangle *triangle, const Polygon *polygon, const DrawData *draw);
+
+		SetupProcessor(Context *context);
+
+		~SetupProcessor();
+
+	protected:
+		State update() const;
+		Routine *routine(const State &state);
+
+		void setRoutineCacheSize(int cacheSize);
+
+		float depthBias;
+		float slopeDepthBias;
+
+	private:
+		Context *const context;
+
+		RoutineCache<State> *routineCache;
+	};
+}
+
+#endif   // sw_SetupProcessor_hpp
diff --git a/src/Renderer/Stream.hpp b/src/Renderer/Stream.hpp
index a3555f4..9e06cf3 100644
--- a/src/Renderer/Stream.hpp
+++ b/src/Renderer/Stream.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_Stream_hpp
 #define sw_Stream_hpp
@@ -75,7 +78,7 @@
 		Stream &defaults()
 		{
 			static const float4 null = {0, 0, 0, 1};
-	
+
 			resource = 0;
 			buffer = &null;
 			stride = 0;
diff --git a/src/Renderer/Surface.cpp b/src/Renderer/Surface.cpp
index d64e041..4d84cf0 100644
--- a/src/Renderer/Surface.cpp
+++ b/src/Renderer/Surface.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Surface.hpp"
 
@@ -2567,7 +2570,7 @@
 				unsigned int YStride = align(width, 16);
 				unsigned int YSize = YStride * height;
 				unsigned int CStride = align(YStride / 2, 16);
- 				unsigned int CSize = CStride * height / 2;
+				unsigned int CSize = CStride * height / 2;
 
 				return YSize + 2 * CSize;
 			}
diff --git a/src/Renderer/Surface.hpp b/src/Renderer/Surface.hpp
index e7764e8..cd89d74 100644
--- a/src/Renderer/Surface.hpp
+++ b/src/Renderer/Surface.hpp
@@ -1,599 +1,602 @@
-// 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.

-//

-

-#ifndef sw_Surface_hpp

-#define sw_Surface_hpp

-

-#include "Color.hpp"

-#include "Main/Config.hpp"

-#include "Common/Resource.hpp"

-

-namespace sw

-{

-	class Resource;

-

-	struct Rect

-	{

-		Rect() {}

-		Rect(int x0i, int y0i, int x1i, int y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {}

-

-		void clip(int minX, int minY, int maxX, int maxY);

-

-		int width() const  { return x1 - x0; }

-		int height() const { return y1 - y0; }

-

-		int x0;   // Inclusive

-		int y0;   // Inclusive

-		int x1;   // Exclusive

-		int y1;   // Exclusive

-	};

-

-	struct SliceRect : public Rect

-	{

-		SliceRect() : slice(0) {}

-		SliceRect(const Rect& rect) : Rect(rect), slice(0) {}

-		SliceRect(const Rect& rect, int s) : Rect(rect), slice(s) {}

-		SliceRect(int x0, int y0, int x1, int y1, int s) : Rect(x0, y0, x1, y1), slice(s) {}

-		int slice;

-	};

-

-	enum Format : unsigned char

-	{

-		FORMAT_NULL,

-

-		FORMAT_A8,

-		FORMAT_R8I,

-		FORMAT_R8UI,

-		FORMAT_R8I_SNORM,

-		FORMAT_R8, // UI_SNORM

-		FORMAT_R16I,

-		FORMAT_R16UI,

-		FORMAT_R32I,

-		FORMAT_R32UI,

-		FORMAT_R3G3B2,

-		FORMAT_A8R3G3B2,

-		FORMAT_X4R4G4B4,

-		FORMAT_A4R4G4B4,

-		FORMAT_R4G4B4A4,

-		FORMAT_R5G6B5,

-		FORMAT_R8G8B8,

-		FORMAT_B8G8R8,

-		FORMAT_X8R8G8B8,

-		FORMAT_A8R8G8B8,

-		FORMAT_X8B8G8R8I,

-		FORMAT_X8B8G8R8UI,

-		FORMAT_X8B8G8R8I_SNORM,

-		FORMAT_X8B8G8R8, // UI_SNORM

-		FORMAT_A8B8G8R8I,

-		FORMAT_A8B8G8R8UI,

-		FORMAT_A8B8G8R8I_SNORM,

-		FORMAT_A8B8G8R8, // UI_SNORM

-		FORMAT_SRGB8_X8,

-		FORMAT_SRGB8_A8,

-		FORMAT_X1R5G5B5,

-		FORMAT_A1R5G5B5,

-		FORMAT_R5G5B5A1,

-		FORMAT_G8R8I,

-		FORMAT_G8R8UI,

-		FORMAT_G8R8I_SNORM,

-		FORMAT_G8R8, // UI_SNORM

-		FORMAT_G16R16, // D3D format

-		FORMAT_G16R16I,

-		FORMAT_G16R16UI,

-		FORMAT_G32R32I,

-		FORMAT_G32R32UI,

-		FORMAT_A2R10G10B10,

-		FORMAT_A2B10G10R10,

-		FORMAT_A16B16G16R16, // D3D format

-		FORMAT_X16B16G16R16I,

-		FORMAT_X16B16G16R16UI,

-		FORMAT_A16B16G16R16I,

-		FORMAT_A16B16G16R16UI,

-		FORMAT_X32B32G32R32I,

-		FORMAT_X32B32G32R32UI,

-		FORMAT_A32B32G32R32I,

-		FORMAT_A32B32G32R32UI,

-		// Paletted formats

-		FORMAT_P8,

-		FORMAT_A8P8,

-		// Compressed formats

-		FORMAT_DXT1,

-		FORMAT_DXT3,

-		FORMAT_DXT5,

-		FORMAT_ATI1,

-		FORMAT_ATI2,

-		FORMAT_ETC1,

-		FORMAT_R11_EAC,

-		FORMAT_SIGNED_R11_EAC,

-		FORMAT_RG11_EAC,

-		FORMAT_SIGNED_RG11_EAC,

-		FORMAT_RGB8_ETC2,

-		FORMAT_SRGB8_ETC2,

-		FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,

-		FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,

-		FORMAT_RGBA8_ETC2_EAC,

-		FORMAT_SRGB8_ALPHA8_ETC2_EAC,

-		FORMAT_RGBA_ASTC_4x4_KHR,

-		FORMAT_RGBA_ASTC_5x4_KHR,

-		FORMAT_RGBA_ASTC_5x5_KHR,

-		FORMAT_RGBA_ASTC_6x5_KHR,

-		FORMAT_RGBA_ASTC_6x6_KHR,

-		FORMAT_RGBA_ASTC_8x5_KHR,

-		FORMAT_RGBA_ASTC_8x6_KHR,

-		FORMAT_RGBA_ASTC_8x8_KHR,

-		FORMAT_RGBA_ASTC_10x5_KHR,

-		FORMAT_RGBA_ASTC_10x6_KHR,

-		FORMAT_RGBA_ASTC_10x8_KHR,

-		FORMAT_RGBA_ASTC_10x10_KHR,

-		FORMAT_RGBA_ASTC_12x10_KHR,

-		FORMAT_RGBA_ASTC_12x12_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR,

-		FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR,

-		// Floating-point formats

-		FORMAT_A16F,

-		FORMAT_R16F,

-		FORMAT_G16R16F,

-		FORMAT_B16G16R16F,

-		FORMAT_A16B16G16R16F,

-		FORMAT_A32F,

-		FORMAT_R32F,

-		FORMAT_G32R32F,

-		FORMAT_B32G32R32F,

-		FORMAT_X32B32G32R32F,

-		FORMAT_A32B32G32R32F,

-		// Bump map formats

-		FORMAT_V8U8,

-		FORMAT_L6V5U5,

-		FORMAT_Q8W8V8U8,

-		FORMAT_X8L8V8U8,

-		FORMAT_A2W10V10U10,

-		FORMAT_V16U16,

-		FORMAT_A16W16V16U16,

-		FORMAT_Q16W16V16U16,

-		// Luminance formats

-		FORMAT_L8,

-		FORMAT_A4L4,

-		FORMAT_L16,

-		FORMAT_A8L8,

-		FORMAT_L16F,

-		FORMAT_A16L16F,

-		FORMAT_L32F,

-		FORMAT_A32L32F,

-		// Depth/stencil formats

-		FORMAT_D16,

-		FORMAT_D32,

-		FORMAT_D24X8,

-		FORMAT_D24S8,

-		FORMAT_D24FS8,

-		FORMAT_D32F,                 // Quad layout

-		FORMAT_D32F_COMPLEMENTARY,   // Quad layout, 1 - z

-		FORMAT_D32F_LOCKABLE,        // Linear layout

-		FORMAT_D32FS8_TEXTURE,       // Linear layout, no PCF

-		FORMAT_D32FS8_SHADOW,        // Linear layout, PCF

-		FORMAT_DF24S8,

-		FORMAT_DF16S8,

-		FORMAT_INTZ,

-		FORMAT_S8,

-		// Quad layout framebuffer

-		FORMAT_X8G8R8B8Q,

-		FORMAT_A8G8R8B8Q,

-		// YUV formats

-		FORMAT_YV12_BT601,

-		FORMAT_YV12_BT709,

-		FORMAT_YV12_JFIF,    // Full-swing BT.601

-

-		FORMAT_LAST = FORMAT_YV12_JFIF

-	};

-

-	enum Lock

-	{

-		LOCK_UNLOCKED,

-		LOCK_READONLY,

-		LOCK_WRITEONLY,

-		LOCK_READWRITE,

-		LOCK_DISCARD

-	};

-

-	class Surface

-	{

-	private:

-		struct Buffer

-		{

-		public:

-			void write(int x, int y, int z, const Color<float> &color);

-			void write(int x, int y, const Color<float> &color);

-			void write(void *element, const Color<float> &color);

-			Color<float> read(int x, int y, int z) const;

-			Color<float> read(int x, int y) const;

-			Color<float> read(void *element) const;

-			Color<float> sample(float x, float y, float z) const;

-			Color<float> sample(float x, float y) const;

-

-			void *lockRect(int x, int y, int z, Lock lock);

-			void unlockRect();

-

-			void *buffer;

-			int width;

-			int height;

-			int depth;

-			int bytes;

-			int pitchB;

-			int pitchP;

-			int sliceB;

-			int sliceP;

-			Format format;

-			Lock lock;

-

-			bool dirty;

-		};

-

-	public:

-		Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);

-		Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);

-

-		virtual ~Surface();

-

-		inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false);

-		inline void unlock(bool internal = false);

-		inline int getWidth() const;

-		inline int getHeight() const;

-		inline int getDepth() const;

-		inline Format getFormat(bool internal = false) const;

-		inline int getPitchB(bool internal = false) const;

-		inline int getPitchP(bool internal = false) const;

-		inline int getSliceB(bool internal = false) const;

-		inline int getSliceP(bool internal = false) const;

-

-		void *lockExternal(int x, int y, int z, Lock lock, Accessor client);

-		void unlockExternal();

-		inline Format getExternalFormat() const;

-		inline int getExternalPitchB() const;

-		inline int getExternalPitchP() const;

-		inline int getExternalSliceB() const;

-		inline int getExternalSliceP() const;

-

-		virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client);

-		virtual void unlockInternal();

-		inline Format getInternalFormat() const;

-		inline int getInternalPitchB() const;

-		inline int getInternalPitchP() const;

-		inline int getInternalSliceB() const;

-		inline int getInternalSliceP() const;

-

-		void *lockStencil(int front, Accessor client);

-		void unlockStencil();

-		inline int getStencilPitchB() const;

-		inline int getStencilSliceB() const;

-

-		inline int getMultiSampleCount() const;

-		inline int getSuperSampleCount() const;

-

-		bool isEntire(const SliceRect& rect) const;

-		SliceRect getRect() const;

-		void clearDepth(float depth, int x0, int y0, int width, int height);

-		void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height);

-		void fill(const Color<float> &color, int x0, int y0, int width, int height);

-

-		Color<float> readExternal(int x, int y, int z) const;

-		Color<float> readExternal(int x, int y) const;

-		Color<float> sampleExternal(float x, float y, float z) const;

-		Color<float> sampleExternal(float x, float y) const;

-		void writeExternal(int x, int y, int z, const Color<float> &color);

-		void writeExternal(int x, int y, const Color<float> &color);

-

-		void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter);

-		void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter);

-

-		bool hasStencil() const;

-		bool hasDepth() const;

-		bool hasPalette() const;

-		bool isRenderTarget() const;

-

-		bool hasDirtyMipmaps() const;

-		void cleanMipmaps();

-		inline bool isExternalDirty() const;

-		Resource *getResource();

-

-		static int bytes(Format format);

-		static int pitchB(int width, Format format, bool target);

-		static int pitchP(int width, Format format, bool target);

-		static int sliceB(int width, int height, Format format, bool target);

-		static int sliceP(int width, int height, Format format, bool target);

-		static unsigned int size(int width, int height, int depth, Format format);   // FIXME: slice * depth

-

-		static bool isStencil(Format format);

-		static bool isDepth(Format format);

-		static bool isPalette(Format format);

-

-		static bool isFloatFormat(Format format);

-		static bool isUnsignedComponent(Format format, int component);

-		static bool isSRGBreadable(Format format);

-		static bool isSRGBwritable(Format format);

-		static bool isCompressed(Format format);

-		static bool isNonNormalizedInteger(Format format);

-		static int componentCount(Format format);

-

-		static void setTexturePalette(unsigned int *palette);

-

-	protected:

-		sw::Resource *resource;

-

-	private:

-		typedef unsigned char byte;

-		typedef unsigned short word;

-		typedef unsigned int dword;

-		typedef uint64_t qword;

-

-		#if S3TC_SUPPORT

-		struct DXT1

-		{

-			word c0;

-			word c1;

-			dword lut;

-		};

-

-		struct DXT3

-		{

-			qword a;

-

-			word c0;

-			word c1;

-			dword lut;

-		};

-

-		struct DXT5

-		{

-			union

-			{

-				struct

-				{

-					byte a0;

-					byte a1;

-				};

-

-				qword alut;   // Skip first 16 bit

-			};

-

-			word c0;

-			word c1;

-			dword clut;

-		};

-		#endif

-

-		struct ATI2

-		{

-			union

-			{

-				struct

-				{

-					byte y0;

-					byte y1;

-				};

-

-				qword ylut;   // Skip first 16 bit

-			};

-

-			union

-			{

-				struct

-				{

-					byte x0;

-					byte x1;

-				};

-

-				qword xlut;   // Skip first 16 bit

-			};

-		};

-

-		struct ATI1

-		{

-			union

-			{

-				struct

-				{

-					byte r0;

-					byte r1;

-				};

-

-				qword rlut;   // Skip first 16 bit

-			};

-		};

-

-		static void decodeR8G8B8(Buffer &destination, const Buffer &source);

-		static void decodeX1R5G5B5(Buffer &destination, const Buffer &source);

-		static void decodeA1R5G5B5(Buffer &destination, const Buffer &source);

-		static void decodeX4R4G4B4(Buffer &destination, const Buffer &source);

-		static void decodeA4R4G4B4(Buffer &destination, const Buffer &source);

-		static void decodeP8(Buffer &destination, const Buffer &source);

-

-		#if S3TC_SUPPORT

-		static void decodeDXT1(Buffer &internal, const Buffer &external);

-		static void decodeDXT3(Buffer &internal, const Buffer &external);

-		static void decodeDXT5(Buffer &internal, const Buffer &external);

-		#endif

-		static void decodeATI1(Buffer &internal, const Buffer &external);

-		static void decodeATI2(Buffer &internal, const Buffer &external);

-		static void decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned);

-		static void decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB);

-		static void decodeASTC(Buffer &internal, const Buffer &external, int xSize, int ySize, int zSize, bool isSRGB);

-

-		static void update(Buffer &destination, Buffer &source);

-		static void genericUpdate(Buffer &destination, Buffer &source);

-		static void *allocateBuffer(int width, int height, int depth, Format format);

-		static void memfill4(void *buffer, int pattern, int bytes);

-

-		bool identicalFormats() const;

-		Format selectInternalFormat(Format format) const;

-

-		void resolve();

-

-		Buffer external;

-		Buffer internal;

-		Buffer stencil;

-

-		const bool lockable;

-		const bool renderTarget;

-

-		bool dirtyMipmaps;

-		unsigned int paletteUsed;

-

-		static unsigned int *palette;   // FIXME: Not multi-device safe

-		static unsigned int paletteID;

-

-		bool hasParent;

-		bool ownExternal;

-	};

-}

-

-#undef min

-#undef max

-

-namespace sw

-{

-	void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal)

-	{

-		return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client);

-	}

-

-	void Surface::unlock(bool internal)

-	{

-		return internal ? unlockInternal() : unlockExternal();

-	}

-

-	int Surface::getWidth() const

-	{

-		return external.width;

-	}

-

-	int Surface::getHeight() const

-	{

-		return external.height;

-	}

-

-	int Surface::getDepth() const

-	{

-		return external.depth;

-	}

-

-	Format Surface::getFormat(bool internal) const

-	{

-		return internal ? getInternalFormat() : getExternalFormat();

-	}

-

-	int Surface::getPitchB(bool internal) const

-	{

-		return internal ? getInternalPitchB() : getExternalPitchB();

-	}

-

-	int Surface::getPitchP(bool internal) const

-	{

-		return internal ? getInternalPitchP() : getExternalPitchB();

-	}

-

-	int Surface::getSliceB(bool internal) const

-	{

-		return internal ? getInternalSliceB() : getExternalSliceB();

-	}

-

-	int Surface::getSliceP(bool internal) const

-	{

-		return internal ? getInternalSliceP() : getExternalSliceB();

-	}

-

-	Format Surface::getExternalFormat() const

-	{

-		return external.format;

-	}

-

-	int Surface::getExternalPitchB() const

-	{

-		return external.pitchB;

-	}

-

-	int Surface::getExternalPitchP() const

-	{

-		return external.pitchP;

-	}

-

-	int Surface::getExternalSliceB() const

-	{

-		return external.sliceB;

-	}

-

-	int Surface::getExternalSliceP() const

-	{

-		return external.sliceP;

-	}

-

-	Format Surface::getInternalFormat() const

-	{

-		return internal.format;

-	}

-

-	int Surface::getInternalPitchB() const

-	{

-		return internal.pitchB;

-	}

-

-	int Surface::getInternalPitchP() const

-	{

-		return internal.pitchP;

-	}

-

-	int Surface::getInternalSliceB() const

-	{

-		return internal.sliceB;

-	}

-

-	int Surface::getInternalSliceP() const

-	{

-		return internal.sliceP;

-	}

-

-	int Surface::getStencilPitchB() const

-	{

-		return stencil.pitchB;

-	}

-

-	int Surface::getStencilSliceB() const

-	{

-		return stencil.sliceB;

-	}

-

-	int Surface::getMultiSampleCount() const

-	{

-		return sw::min(internal.depth, 4);

-	}

-

-	int Surface::getSuperSampleCount() const

-	{

-		return internal.depth > 4 ? internal.depth / 4 : 1;

-	}

-

-	bool Surface::isExternalDirty() const

-	{

-		return external.buffer && external.buffer != internal.buffer && external.dirty;

-	}

-}

-

-#endif   // sw_Surface_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Surface_hpp
+#define sw_Surface_hpp
+
+#include "Color.hpp"
+#include "Main/Config.hpp"
+#include "Common/Resource.hpp"
+
+namespace sw
+{
+	class Resource;
+
+	struct Rect
+	{
+		Rect() {}
+		Rect(int x0i, int y0i, int x1i, int y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {}
+
+		void clip(int minX, int minY, int maxX, int maxY);
+
+		int width() const  { return x1 - x0; }
+		int height() const { return y1 - y0; }
+
+		int x0;   // Inclusive
+		int y0;   // Inclusive
+		int x1;   // Exclusive
+		int y1;   // Exclusive
+	};
+
+	struct SliceRect : public Rect
+	{
+		SliceRect() : slice(0) {}
+		SliceRect(const Rect& rect) : Rect(rect), slice(0) {}
+		SliceRect(const Rect& rect, int s) : Rect(rect), slice(s) {}
+		SliceRect(int x0, int y0, int x1, int y1, int s) : Rect(x0, y0, x1, y1), slice(s) {}
+		int slice;
+	};
+
+	enum Format : unsigned char
+	{
+		FORMAT_NULL,
+
+		FORMAT_A8,
+		FORMAT_R8I,
+		FORMAT_R8UI,
+		FORMAT_R8I_SNORM,
+		FORMAT_R8, // UI_SNORM
+		FORMAT_R16I,
+		FORMAT_R16UI,
+		FORMAT_R32I,
+		FORMAT_R32UI,
+		FORMAT_R3G3B2,
+		FORMAT_A8R3G3B2,
+		FORMAT_X4R4G4B4,
+		FORMAT_A4R4G4B4,
+		FORMAT_R4G4B4A4,
+		FORMAT_R5G6B5,
+		FORMAT_R8G8B8,
+		FORMAT_B8G8R8,
+		FORMAT_X8R8G8B8,
+		FORMAT_A8R8G8B8,
+		FORMAT_X8B8G8R8I,
+		FORMAT_X8B8G8R8UI,
+		FORMAT_X8B8G8R8I_SNORM,
+		FORMAT_X8B8G8R8, // UI_SNORM
+		FORMAT_A8B8G8R8I,
+		FORMAT_A8B8G8R8UI,
+		FORMAT_A8B8G8R8I_SNORM,
+		FORMAT_A8B8G8R8, // UI_SNORM
+		FORMAT_SRGB8_X8,
+		FORMAT_SRGB8_A8,
+		FORMAT_X1R5G5B5,
+		FORMAT_A1R5G5B5,
+		FORMAT_R5G5B5A1,
+		FORMAT_G8R8I,
+		FORMAT_G8R8UI,
+		FORMAT_G8R8I_SNORM,
+		FORMAT_G8R8, // UI_SNORM
+		FORMAT_G16R16, // D3D format
+		FORMAT_G16R16I,
+		FORMAT_G16R16UI,
+		FORMAT_G32R32I,
+		FORMAT_G32R32UI,
+		FORMAT_A2R10G10B10,
+		FORMAT_A2B10G10R10,
+		FORMAT_A16B16G16R16, // D3D format
+		FORMAT_X16B16G16R16I,
+		FORMAT_X16B16G16R16UI,
+		FORMAT_A16B16G16R16I,
+		FORMAT_A16B16G16R16UI,
+		FORMAT_X32B32G32R32I,
+		FORMAT_X32B32G32R32UI,
+		FORMAT_A32B32G32R32I,
+		FORMAT_A32B32G32R32UI,
+		// Paletted formats
+		FORMAT_P8,
+		FORMAT_A8P8,
+		// Compressed formats
+		FORMAT_DXT1,
+		FORMAT_DXT3,
+		FORMAT_DXT5,
+		FORMAT_ATI1,
+		FORMAT_ATI2,
+		FORMAT_ETC1,
+		FORMAT_R11_EAC,
+		FORMAT_SIGNED_R11_EAC,
+		FORMAT_RG11_EAC,
+		FORMAT_SIGNED_RG11_EAC,
+		FORMAT_RGB8_ETC2,
+		FORMAT_SRGB8_ETC2,
+		FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+		FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+		FORMAT_RGBA8_ETC2_EAC,
+		FORMAT_SRGB8_ALPHA8_ETC2_EAC,
+		FORMAT_RGBA_ASTC_4x4_KHR,
+		FORMAT_RGBA_ASTC_5x4_KHR,
+		FORMAT_RGBA_ASTC_5x5_KHR,
+		FORMAT_RGBA_ASTC_6x5_KHR,
+		FORMAT_RGBA_ASTC_6x6_KHR,
+		FORMAT_RGBA_ASTC_8x5_KHR,
+		FORMAT_RGBA_ASTC_8x6_KHR,
+		FORMAT_RGBA_ASTC_8x8_KHR,
+		FORMAT_RGBA_ASTC_10x5_KHR,
+		FORMAT_RGBA_ASTC_10x6_KHR,
+		FORMAT_RGBA_ASTC_10x8_KHR,
+		FORMAT_RGBA_ASTC_10x10_KHR,
+		FORMAT_RGBA_ASTC_12x10_KHR,
+		FORMAT_RGBA_ASTC_12x12_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR,
+		FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR,
+		// Floating-point formats
+		FORMAT_A16F,
+		FORMAT_R16F,
+		FORMAT_G16R16F,
+		FORMAT_B16G16R16F,
+		FORMAT_A16B16G16R16F,
+		FORMAT_A32F,
+		FORMAT_R32F,
+		FORMAT_G32R32F,
+		FORMAT_B32G32R32F,
+		FORMAT_X32B32G32R32F,
+		FORMAT_A32B32G32R32F,
+		// Bump map formats
+		FORMAT_V8U8,
+		FORMAT_L6V5U5,
+		FORMAT_Q8W8V8U8,
+		FORMAT_X8L8V8U8,
+		FORMAT_A2W10V10U10,
+		FORMAT_V16U16,
+		FORMAT_A16W16V16U16,
+		FORMAT_Q16W16V16U16,
+		// Luminance formats
+		FORMAT_L8,
+		FORMAT_A4L4,
+		FORMAT_L16,
+		FORMAT_A8L8,
+		FORMAT_L16F,
+		FORMAT_A16L16F,
+		FORMAT_L32F,
+		FORMAT_A32L32F,
+		// Depth/stencil formats
+		FORMAT_D16,
+		FORMAT_D32,
+		FORMAT_D24X8,
+		FORMAT_D24S8,
+		FORMAT_D24FS8,
+		FORMAT_D32F,                 // Quad layout
+		FORMAT_D32F_COMPLEMENTARY,   // Quad layout, 1 - z
+		FORMAT_D32F_LOCKABLE,        // Linear layout
+		FORMAT_D32FS8_TEXTURE,       // Linear layout, no PCF
+		FORMAT_D32FS8_SHADOW,        // Linear layout, PCF
+		FORMAT_DF24S8,
+		FORMAT_DF16S8,
+		FORMAT_INTZ,
+		FORMAT_S8,
+		// Quad layout framebuffer
+		FORMAT_X8G8R8B8Q,
+		FORMAT_A8G8R8B8Q,
+		// YUV formats
+		FORMAT_YV12_BT601,
+		FORMAT_YV12_BT709,
+		FORMAT_YV12_JFIF,    // Full-swing BT.601
+
+		FORMAT_LAST = FORMAT_YV12_JFIF
+	};
+
+	enum Lock
+	{
+		LOCK_UNLOCKED,
+		LOCK_READONLY,
+		LOCK_WRITEONLY,
+		LOCK_READWRITE,
+		LOCK_DISCARD
+	};
+
+	class Surface
+	{
+	private:
+		struct Buffer
+		{
+		public:
+			void write(int x, int y, int z, const Color<float> &color);
+			void write(int x, int y, const Color<float> &color);
+			void write(void *element, const Color<float> &color);
+			Color<float> read(int x, int y, int z) const;
+			Color<float> read(int x, int y) const;
+			Color<float> read(void *element) const;
+			Color<float> sample(float x, float y, float z) const;
+			Color<float> sample(float x, float y) const;
+
+			void *lockRect(int x, int y, int z, Lock lock);
+			void unlockRect();
+
+			void *buffer;
+			int width;
+			int height;
+			int depth;
+			int bytes;
+			int pitchB;
+			int pitchP;
+			int sliceB;
+			int sliceP;
+			Format format;
+			Lock lock;
+
+			bool dirty;
+		};
+
+	public:
+		Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
+		Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
+
+		virtual ~Surface();
+
+		inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false);
+		inline void unlock(bool internal = false);
+		inline int getWidth() const;
+		inline int getHeight() const;
+		inline int getDepth() const;
+		inline Format getFormat(bool internal = false) const;
+		inline int getPitchB(bool internal = false) const;
+		inline int getPitchP(bool internal = false) const;
+		inline int getSliceB(bool internal = false) const;
+		inline int getSliceP(bool internal = false) const;
+
+		void *lockExternal(int x, int y, int z, Lock lock, Accessor client);
+		void unlockExternal();
+		inline Format getExternalFormat() const;
+		inline int getExternalPitchB() const;
+		inline int getExternalPitchP() const;
+		inline int getExternalSliceB() const;
+		inline int getExternalSliceP() const;
+
+		virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client);
+		virtual void unlockInternal();
+		inline Format getInternalFormat() const;
+		inline int getInternalPitchB() const;
+		inline int getInternalPitchP() const;
+		inline int getInternalSliceB() const;
+		inline int getInternalSliceP() const;
+
+		void *lockStencil(int front, Accessor client);
+		void unlockStencil();
+		inline int getStencilPitchB() const;
+		inline int getStencilSliceB() const;
+
+		inline int getMultiSampleCount() const;
+		inline int getSuperSampleCount() const;
+
+		bool isEntire(const SliceRect& rect) const;
+		SliceRect getRect() const;
+		void clearDepth(float depth, int x0, int y0, int width, int height);
+		void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height);
+		void fill(const Color<float> &color, int x0, int y0, int width, int height);
+
+		Color<float> readExternal(int x, int y, int z) const;
+		Color<float> readExternal(int x, int y) const;
+		Color<float> sampleExternal(float x, float y, float z) const;
+		Color<float> sampleExternal(float x, float y) const;
+		void writeExternal(int x, int y, int z, const Color<float> &color);
+		void writeExternal(int x, int y, const Color<float> &color);
+
+		void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter);
+		void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter);
+
+		bool hasStencil() const;
+		bool hasDepth() const;
+		bool hasPalette() const;
+		bool isRenderTarget() const;
+
+		bool hasDirtyMipmaps() const;
+		void cleanMipmaps();
+		inline bool isExternalDirty() const;
+		Resource *getResource();
+
+		static int bytes(Format format);
+		static int pitchB(int width, Format format, bool target);
+		static int pitchP(int width, Format format, bool target);
+		static int sliceB(int width, int height, Format format, bool target);
+		static int sliceP(int width, int height, Format format, bool target);
+		static unsigned int size(int width, int height, int depth, Format format);   // FIXME: slice * depth
+
+		static bool isStencil(Format format);
+		static bool isDepth(Format format);
+		static bool isPalette(Format format);
+
+		static bool isFloatFormat(Format format);
+		static bool isUnsignedComponent(Format format, int component);
+		static bool isSRGBreadable(Format format);
+		static bool isSRGBwritable(Format format);
+		static bool isCompressed(Format format);
+		static bool isNonNormalizedInteger(Format format);
+		static int componentCount(Format format);
+
+		static void setTexturePalette(unsigned int *palette);
+
+	protected:
+		sw::Resource *resource;
+
+	private:
+		typedef unsigned char byte;
+		typedef unsigned short word;
+		typedef unsigned int dword;
+		typedef uint64_t qword;
+
+		#if S3TC_SUPPORT
+		struct DXT1
+		{
+			word c0;
+			word c1;
+			dword lut;
+		};
+
+		struct DXT3
+		{
+			qword a;
+
+			word c0;
+			word c1;
+			dword lut;
+		};
+
+		struct DXT5
+		{
+			union
+			{
+				struct
+				{
+					byte a0;
+					byte a1;
+				};
+
+				qword alut;   // Skip first 16 bit
+			};
+
+			word c0;
+			word c1;
+			dword clut;
+		};
+		#endif
+
+		struct ATI2
+		{
+			union
+			{
+				struct
+				{
+					byte y0;
+					byte y1;
+				};
+
+				qword ylut;   // Skip first 16 bit
+			};
+
+			union
+			{
+				struct
+				{
+					byte x0;
+					byte x1;
+				};
+
+				qword xlut;   // Skip first 16 bit
+			};
+		};
+
+		struct ATI1
+		{
+			union
+			{
+				struct
+				{
+					byte r0;
+					byte r1;
+				};
+
+				qword rlut;   // Skip first 16 bit
+			};
+		};
+
+		static void decodeR8G8B8(Buffer &destination, const Buffer &source);
+		static void decodeX1R5G5B5(Buffer &destination, const Buffer &source);
+		static void decodeA1R5G5B5(Buffer &destination, const Buffer &source);
+		static void decodeX4R4G4B4(Buffer &destination, const Buffer &source);
+		static void decodeA4R4G4B4(Buffer &destination, const Buffer &source);
+		static void decodeP8(Buffer &destination, const Buffer &source);
+
+		#if S3TC_SUPPORT
+		static void decodeDXT1(Buffer &internal, const Buffer &external);
+		static void decodeDXT3(Buffer &internal, const Buffer &external);
+		static void decodeDXT5(Buffer &internal, const Buffer &external);
+		#endif
+		static void decodeATI1(Buffer &internal, const Buffer &external);
+		static void decodeATI2(Buffer &internal, const Buffer &external);
+		static void decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned);
+		static void decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB);
+		static void decodeASTC(Buffer &internal, const Buffer &external, int xSize, int ySize, int zSize, bool isSRGB);
+
+		static void update(Buffer &destination, Buffer &source);
+		static void genericUpdate(Buffer &destination, Buffer &source);
+		static void *allocateBuffer(int width, int height, int depth, Format format);
+		static void memfill4(void *buffer, int pattern, int bytes);
+
+		bool identicalFormats() const;
+		Format selectInternalFormat(Format format) const;
+
+		void resolve();
+
+		Buffer external;
+		Buffer internal;
+		Buffer stencil;
+
+		const bool lockable;
+		const bool renderTarget;
+
+		bool dirtyMipmaps;
+		unsigned int paletteUsed;
+
+		static unsigned int *palette;   // FIXME: Not multi-device safe
+		static unsigned int paletteID;
+
+		bool hasParent;
+		bool ownExternal;
+	};
+}
+
+#undef min
+#undef max
+
+namespace sw
+{
+	void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal)
+	{
+		return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client);
+	}
+
+	void Surface::unlock(bool internal)
+	{
+		return internal ? unlockInternal() : unlockExternal();
+	}
+
+	int Surface::getWidth() const
+	{
+		return external.width;
+	}
+
+	int Surface::getHeight() const
+	{
+		return external.height;
+	}
+
+	int Surface::getDepth() const
+	{
+		return external.depth;
+	}
+
+	Format Surface::getFormat(bool internal) const
+	{
+		return internal ? getInternalFormat() : getExternalFormat();
+	}
+
+	int Surface::getPitchB(bool internal) const
+	{
+		return internal ? getInternalPitchB() : getExternalPitchB();
+	}
+
+	int Surface::getPitchP(bool internal) const
+	{
+		return internal ? getInternalPitchP() : getExternalPitchB();
+	}
+
+	int Surface::getSliceB(bool internal) const
+	{
+		return internal ? getInternalSliceB() : getExternalSliceB();
+	}
+
+	int Surface::getSliceP(bool internal) const
+	{
+		return internal ? getInternalSliceP() : getExternalSliceB();
+	}
+
+	Format Surface::getExternalFormat() const
+	{
+		return external.format;
+	}
+
+	int Surface::getExternalPitchB() const
+	{
+		return external.pitchB;
+	}
+
+	int Surface::getExternalPitchP() const
+	{
+		return external.pitchP;
+	}
+
+	int Surface::getExternalSliceB() const
+	{
+		return external.sliceB;
+	}
+
+	int Surface::getExternalSliceP() const
+	{
+		return external.sliceP;
+	}
+
+	Format Surface::getInternalFormat() const
+	{
+		return internal.format;
+	}
+
+	int Surface::getInternalPitchB() const
+	{
+		return internal.pitchB;
+	}
+
+	int Surface::getInternalPitchP() const
+	{
+		return internal.pitchP;
+	}
+
+	int Surface::getInternalSliceB() const
+	{
+		return internal.sliceB;
+	}
+
+	int Surface::getInternalSliceP() const
+	{
+		return internal.sliceP;
+	}
+
+	int Surface::getStencilPitchB() const
+	{
+		return stencil.pitchB;
+	}
+
+	int Surface::getStencilSliceB() const
+	{
+		return stencil.sliceB;
+	}
+
+	int Surface::getMultiSampleCount() const
+	{
+		return sw::min(internal.depth, 4);
+	}
+
+	int Surface::getSuperSampleCount() const
+	{
+		return internal.depth > 4 ? internal.depth / 4 : 1;
+	}
+
+	bool Surface::isExternalDirty() const
+	{
+		return external.buffer && external.buffer != internal.buffer && external.dirty;
+	}
+}
+
+#endif   // sw_Surface_hpp
diff --git a/src/Renderer/TextureStage.cpp b/src/Renderer/TextureStage.cpp
index d102d19..583f82e 100644
--- a/src/Renderer/TextureStage.cpp
+++ b/src/Renderer/TextureStage.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "TextureStage.hpp"
 
@@ -238,7 +241,7 @@
 				return thirdArgument == source;
 			}
 		}
-		
+	
 		return false;
 	}
 
diff --git a/src/Renderer/TextureStage.hpp b/src/Renderer/TextureStage.hpp
index 199043f..2c9ecbd 100644
--- a/src/Renderer/TextureStage.hpp
+++ b/src/Renderer/TextureStage.hpp
@@ -1,195 +1,198 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_TextureStage_hpp

-#define sw_TextureStage_hpp

-

-#include "Common/Types.hpp"

-#include "Common/Math.hpp"

-#include "Renderer/Color.hpp"

-

-namespace sw

-{

-	class Sampler;

-	class PixelRoutine;

-	class Context;

-

-	class TextureStage

-	{

-		friend class Context;   // FIXME

-

-	public:

-		enum StageOperation

-		{

-			STAGE_DISABLE,

-			STAGE_SELECTARG1,

-			STAGE_SELECTARG2,

-			STAGE_SELECTARG3,

-			STAGE_MODULATE,

-			STAGE_MODULATE2X,

-			STAGE_MODULATE4X,

-			STAGE_ADD,

-			STAGE_ADDSIGNED,

-			STAGE_ADDSIGNED2X,

-			STAGE_SUBTRACT,

-			STAGE_ADDSMOOTH,

-			STAGE_MULTIPLYADD,

-			STAGE_LERP,

-			STAGE_DOT3,

-			STAGE_BLENDCURRENTALPHA,

-			STAGE_BLENDDIFFUSEALPHA,

-			STAGE_BLENDFACTORALPHA,

-			STAGE_BLENDTEXTUREALPHA,

-			STAGE_BLENDTEXTUREALPHAPM,

-			STAGE_PREMODULATE,

-			STAGE_MODULATEALPHA_ADDCOLOR,

-			STAGE_MODULATECOLOR_ADDALPHA,

-			STAGE_MODULATEINVALPHA_ADDCOLOR,

-			STAGE_MODULATEINVCOLOR_ADDALPHA,

-			STAGE_BUMPENVMAP,

-			STAGE_BUMPENVMAPLUMINANCE,

-

-			STAGE_LAST = STAGE_BUMPENVMAPLUMINANCE

-		};

-

-		enum SourceArgument

-		{

-			SOURCE_TEXTURE,

-			SOURCE_CONSTANT,

-			SOURCE_CURRENT,

-			SOURCE_DIFFUSE,

-			SOURCE_SPECULAR,

-			SOURCE_TEMP,

-			SOURCE_TFACTOR,

-

-			SOURCE_LAST = SOURCE_TFACTOR

-		};

-

-		enum DestinationArgument

-		{

-			DESTINATION_CURRENT,

-			DESTINATION_TEMP,

-

-			DESTINATION_LAST = DESTINATION_TEMP

-		};

-

-		enum ArgumentModifier

-		{

-			MODIFIER_COLOR,

-			MODIFIER_INVCOLOR,

-			MODIFIER_ALPHA,

-			MODIFIER_INVALPHA,

-

-			MODIFIER_LAST = MODIFIER_INVALPHA

-		};

-

-		struct State

-		{

-			State();

-

-			unsigned int stageOperation			: BITS(STAGE_LAST);

-			unsigned int firstArgument			: BITS(SOURCE_LAST);

-			unsigned int secondArgument			: BITS(SOURCE_LAST);

-			unsigned int thirdArgument			: BITS(SOURCE_LAST);

-			unsigned int stageOperationAlpha	: BITS(STAGE_LAST);

-			unsigned int firstArgumentAlpha		: BITS(SOURCE_LAST);

-			unsigned int secondArgumentAlpha	: BITS(SOURCE_LAST);

-			unsigned int thirdArgumentAlpha		: BITS(SOURCE_LAST);

-			unsigned int firstModifier			: BITS(MODIFIER_LAST);

-			unsigned int secondModifier			: BITS(MODIFIER_LAST);

-			unsigned int thirdModifier			: BITS(MODIFIER_LAST);

-			unsigned int firstModifierAlpha		: BITS(MODIFIER_LAST);

-			unsigned int secondModifierAlpha	: BITS(MODIFIER_LAST);

-			unsigned int thirdModifierAlpha		: BITS(MODIFIER_LAST);

-			unsigned int destinationArgument	: BITS(DESTINATION_LAST);

-			unsigned int texCoordIndex			: BITS(7);

-

-			unsigned int cantUnderflow			: 1;

-			unsigned int usesTexture			: 1;

-		};

-

-		struct Uniforms

-		{

-			word4 constantColor4[4];

-			float4 bumpmapMatrix4F[2][2];

-			word4 bumpmapMatrix4W[2][2];

-			word4 luminanceScale4;

-			word4 luminanceOffset4;

-		};

-

-		TextureStage();

-

-		~TextureStage();

-

-		void init(int stage, const Sampler *sampler, const TextureStage *previousStage);

-

-		State textureStageState() const;

-

-		void setConstantColor(const Color<float> &constantColor);

-		void setBumpmapMatrix(int element, float value);

-		void setLuminanceScale(float value);

-		void setLuminanceOffset(float value);

-

-		void setTexCoordIndex(unsigned int texCoordIndex);

-		void setStageOperation(StageOperation stageOperation);

-		void setFirstArgument(SourceArgument firstArgument);

-		void setSecondArgument(SourceArgument secondArgument);

-		void setThirdArgument(SourceArgument thirdArgument);

-		void setStageOperationAlpha(StageOperation stageOperationAlpha);

-		void setFirstArgumentAlpha(SourceArgument firstArgumentAlpha);

-		void setSecondArgumentAlpha(SourceArgument secondArgumentAlpha);

-		void setThirdArgumentAlpha(SourceArgument thirdArgumentAlpha);

-		void setFirstModifier(ArgumentModifier firstModifier);

-		void setSecondModifier(ArgumentModifier secondModifier);

-		void setThirdModifier(ArgumentModifier thirdModifier);

-		void setFirstModifierAlpha(ArgumentModifier firstModifierAlpha);

-		void setSecondModifierAlpha(ArgumentModifier secondModifierAlpha);

-		void setThirdModifierAlpha(ArgumentModifier thirdModifierAlpha);

-		void setDestinationArgument(DestinationArgument destinationArgument);

-

-		Uniforms uniforms;   // FIXME: Private

-

-	private:

-		bool usesColor(SourceArgument source) const;

-		bool usesAlpha(SourceArgument source) const;

-		bool uses(SourceArgument source) const;

-		bool usesCurrent() const;

-		bool usesDiffuse() const;

-		bool usesSpecular() const;

-		bool usesTexture() const;

-		bool isStageDisabled() const;

-		bool writesCurrent() const;

-

-		int stage;

-

-		StageOperation stageOperation;

-		SourceArgument firstArgument;

-		SourceArgument secondArgument;

-		SourceArgument thirdArgument;

-		StageOperation stageOperationAlpha;

-		SourceArgument firstArgumentAlpha;

-		SourceArgument secondArgumentAlpha;

-		SourceArgument thirdArgumentAlpha;

-		ArgumentModifier firstModifier;

-		ArgumentModifier secondModifier;

-		ArgumentModifier thirdModifier;

-		ArgumentModifier firstModifierAlpha;

-		ArgumentModifier secondModifierAlpha;

-		ArgumentModifier thirdModifierAlpha;

-		DestinationArgument destinationArgument;

-

-		int texCoordIndex;

-		const Sampler *sampler;

-		const TextureStage *previousStage;

-	};

-}

-

-#endif  // sw_TextureStage_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_TextureStage_hpp
+#define sw_TextureStage_hpp
+
+#include "Common/Types.hpp"
+#include "Common/Math.hpp"
+#include "Renderer/Color.hpp"
+
+namespace sw
+{
+	class Sampler;
+	class PixelRoutine;
+	class Context;
+
+	class TextureStage
+	{
+		friend class Context;   // FIXME
+
+	public:
+		enum StageOperation
+		{
+			STAGE_DISABLE,
+			STAGE_SELECTARG1,
+			STAGE_SELECTARG2,
+			STAGE_SELECTARG3,
+			STAGE_MODULATE,
+			STAGE_MODULATE2X,
+			STAGE_MODULATE4X,
+			STAGE_ADD,
+			STAGE_ADDSIGNED,
+			STAGE_ADDSIGNED2X,
+			STAGE_SUBTRACT,
+			STAGE_ADDSMOOTH,
+			STAGE_MULTIPLYADD,
+			STAGE_LERP,
+			STAGE_DOT3,
+			STAGE_BLENDCURRENTALPHA,
+			STAGE_BLENDDIFFUSEALPHA,
+			STAGE_BLENDFACTORALPHA,
+			STAGE_BLENDTEXTUREALPHA,
+			STAGE_BLENDTEXTUREALPHAPM,
+			STAGE_PREMODULATE,
+			STAGE_MODULATEALPHA_ADDCOLOR,
+			STAGE_MODULATECOLOR_ADDALPHA,
+			STAGE_MODULATEINVALPHA_ADDCOLOR,
+			STAGE_MODULATEINVCOLOR_ADDALPHA,
+			STAGE_BUMPENVMAP,
+			STAGE_BUMPENVMAPLUMINANCE,
+
+			STAGE_LAST = STAGE_BUMPENVMAPLUMINANCE
+		};
+
+		enum SourceArgument
+		{
+			SOURCE_TEXTURE,
+			SOURCE_CONSTANT,
+			SOURCE_CURRENT,
+			SOURCE_DIFFUSE,
+			SOURCE_SPECULAR,
+			SOURCE_TEMP,
+			SOURCE_TFACTOR,
+
+			SOURCE_LAST = SOURCE_TFACTOR
+		};
+
+		enum DestinationArgument
+		{
+			DESTINATION_CURRENT,
+			DESTINATION_TEMP,
+
+			DESTINATION_LAST = DESTINATION_TEMP
+		};
+
+		enum ArgumentModifier
+		{
+			MODIFIER_COLOR,
+			MODIFIER_INVCOLOR,
+			MODIFIER_ALPHA,
+			MODIFIER_INVALPHA,
+
+			MODIFIER_LAST = MODIFIER_INVALPHA
+		};
+
+		struct State
+		{
+			State();
+
+			unsigned int stageOperation			: BITS(STAGE_LAST);
+			unsigned int firstArgument			: BITS(SOURCE_LAST);
+			unsigned int secondArgument			: BITS(SOURCE_LAST);
+			unsigned int thirdArgument			: BITS(SOURCE_LAST);
+			unsigned int stageOperationAlpha	: BITS(STAGE_LAST);
+			unsigned int firstArgumentAlpha		: BITS(SOURCE_LAST);
+			unsigned int secondArgumentAlpha	: BITS(SOURCE_LAST);
+			unsigned int thirdArgumentAlpha		: BITS(SOURCE_LAST);
+			unsigned int firstModifier			: BITS(MODIFIER_LAST);
+			unsigned int secondModifier			: BITS(MODIFIER_LAST);
+			unsigned int thirdModifier			: BITS(MODIFIER_LAST);
+			unsigned int firstModifierAlpha		: BITS(MODIFIER_LAST);
+			unsigned int secondModifierAlpha	: BITS(MODIFIER_LAST);
+			unsigned int thirdModifierAlpha		: BITS(MODIFIER_LAST);
+			unsigned int destinationArgument	: BITS(DESTINATION_LAST);
+			unsigned int texCoordIndex			: BITS(7);
+
+			unsigned int cantUnderflow			: 1;
+			unsigned int usesTexture			: 1;
+		};
+
+		struct Uniforms
+		{
+			word4 constantColor4[4];
+			float4 bumpmapMatrix4F[2][2];
+			word4 bumpmapMatrix4W[2][2];
+			word4 luminanceScale4;
+			word4 luminanceOffset4;
+		};
+
+		TextureStage();
+
+		~TextureStage();
+
+		void init(int stage, const Sampler *sampler, const TextureStage *previousStage);
+
+		State textureStageState() const;
+
+		void setConstantColor(const Color<float> &constantColor);
+		void setBumpmapMatrix(int element, float value);
+		void setLuminanceScale(float value);
+		void setLuminanceOffset(float value);
+
+		void setTexCoordIndex(unsigned int texCoordIndex);
+		void setStageOperation(StageOperation stageOperation);
+		void setFirstArgument(SourceArgument firstArgument);
+		void setSecondArgument(SourceArgument secondArgument);
+		void setThirdArgument(SourceArgument thirdArgument);
+		void setStageOperationAlpha(StageOperation stageOperationAlpha);
+		void setFirstArgumentAlpha(SourceArgument firstArgumentAlpha);
+		void setSecondArgumentAlpha(SourceArgument secondArgumentAlpha);
+		void setThirdArgumentAlpha(SourceArgument thirdArgumentAlpha);
+		void setFirstModifier(ArgumentModifier firstModifier);
+		void setSecondModifier(ArgumentModifier secondModifier);
+		void setThirdModifier(ArgumentModifier thirdModifier);
+		void setFirstModifierAlpha(ArgumentModifier firstModifierAlpha);
+		void setSecondModifierAlpha(ArgumentModifier secondModifierAlpha);
+		void setThirdModifierAlpha(ArgumentModifier thirdModifierAlpha);
+		void setDestinationArgument(DestinationArgument destinationArgument);
+
+		Uniforms uniforms;   // FIXME: Private
+
+	private:
+		bool usesColor(SourceArgument source) const;
+		bool usesAlpha(SourceArgument source) const;
+		bool uses(SourceArgument source) const;
+		bool usesCurrent() const;
+		bool usesDiffuse() const;
+		bool usesSpecular() const;
+		bool usesTexture() const;
+		bool isStageDisabled() const;
+		bool writesCurrent() const;
+
+		int stage;
+
+		StageOperation stageOperation;
+		SourceArgument firstArgument;
+		SourceArgument secondArgument;
+		SourceArgument thirdArgument;
+		StageOperation stageOperationAlpha;
+		SourceArgument firstArgumentAlpha;
+		SourceArgument secondArgumentAlpha;
+		SourceArgument thirdArgumentAlpha;
+		ArgumentModifier firstModifier;
+		ArgumentModifier secondModifier;
+		ArgumentModifier thirdModifier;
+		ArgumentModifier firstModifierAlpha;
+		ArgumentModifier secondModifierAlpha;
+		ArgumentModifier thirdModifierAlpha;
+		DestinationArgument destinationArgument;
+
+		int texCoordIndex;
+		const Sampler *sampler;
+		const TextureStage *previousStage;
+	};
+}
+
+#endif  // sw_TextureStage_hpp
diff --git a/src/Renderer/Triangle.hpp b/src/Renderer/Triangle.hpp
index 845fec8..8a91fab 100644
--- a/src/Renderer/Triangle.hpp
+++ b/src/Renderer/Triangle.hpp
@@ -1,27 +1,30 @@
-// 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.

-//

-

-#ifndef sw_Triangle_hpp

-#define sw_Triangle_hpp

-

-#include "Vertex.hpp"

-

-namespace sw

-{

-	struct Triangle

-	{

-		Vertex V0;

-		Vertex V1;

-		Vertex V2;

-	};

-}

-

-#endif   // sw_Triangle_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Triangle_hpp
+#define sw_Triangle_hpp
+
+#include "Vertex.hpp"
+
+namespace sw
+{
+	struct Triangle
+	{
+		Vertex V0;
+		Vertex V1;
+		Vertex V2;
+	};
+}
+
+#endif   // sw_Triangle_hpp
diff --git a/src/Renderer/Vector.cpp b/src/Renderer/Vector.cpp
index c67a644..a212f3d 100644
--- a/src/Renderer/Vector.cpp
+++ b/src/Renderer/Vector.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Vector.hpp"
 
diff --git a/src/Renderer/Vector.hpp b/src/Renderer/Vector.hpp
index 2ff1713..e7f261d 100644
--- a/src/Renderer/Vector.hpp
+++ b/src/Renderer/Vector.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2011 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef Vector_hpp
 #define Vector_hpp
diff --git a/src/Renderer/Vertex.hpp b/src/Renderer/Vertex.hpp
index 129d258..01a7273 100644
--- a/src/Renderer/Vertex.hpp
+++ b/src/Renderer/Vertex.hpp
@@ -1,100 +1,103 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef Vertex_hpp

-#define Vertex_hpp

-

-#include "Color.hpp"

-#include "Common/MetaMacro.hpp"

-#include "Common/Types.hpp"

-

-namespace sw

-{

-	enum Out   // Default vertex output semantic

-	{

-		Pos = 0,

-		D0 = 1,   // Diffuse

-		D1 = 2,   // Specular

-		T0 = 3,

-		T1 = 4,

-		T2 = 5,

-		T3 = 6,

-		T4 = 7,

-		T5 = 8,

-		T6 = 9,

-		T7 = 10,

-		Fog = 11,    // x component

-		Pts = Fog,   // y component

-		Unused

-	};

-

-	struct UVWQ

-	{

-		float u;

-		float v;

-		float w;

-		float q;

-

-		float &operator[](int i)

-		{

-			return (&u)[i];

-		}

-	};

-

-	ALIGN(16, struct Vertex

-	{

-		union

-		{

-			struct   // Fixed semantics

-			{

-				union   // Position

-				{

-					struct

-					{

-						float x;

-						float y;

-						float z;

-						float w;

-					};

-

-					struct

-					{

-						float4 P;

-					};

-				};

-

-				float4 C[2];   // Diffuse and specular color

-

-				UVWQ T[8];           // Texture coordinates

-

-				float f;             // Fog

-				float pSize;         // Point size

-				unsigned char padding0[4];

-				unsigned char clipFlags;

-				unsigned char padding1[3];

-			};

-

-			float4 v[12];   // Generic components using semantic declaration

-		};

-

-		struct   // Projected coordinates

-		{

-			int X;

-			int Y;

-			float Z;

-			float W;

-		};

-	});

-

-	META_ASSERT((sizeof(Vertex) & 0x0000000F) == 0);

-}

-

-#endif   // Vertex_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef Vertex_hpp
+#define Vertex_hpp
+
+#include "Color.hpp"
+#include "Common/MetaMacro.hpp"
+#include "Common/Types.hpp"
+
+namespace sw
+{
+	enum Out   // Default vertex output semantic
+	{
+		Pos = 0,
+		D0 = 1,   // Diffuse
+		D1 = 2,   // Specular
+		T0 = 3,
+		T1 = 4,
+		T2 = 5,
+		T3 = 6,
+		T4 = 7,
+		T5 = 8,
+		T6 = 9,
+		T7 = 10,
+		Fog = 11,    // x component
+		Pts = Fog,   // y component
+		Unused
+	};
+
+	struct UVWQ
+	{
+		float u;
+		float v;
+		float w;
+		float q;
+
+		float &operator[](int i)
+		{
+			return (&u)[i];
+		}
+	};
+
+	ALIGN(16, struct Vertex
+	{
+		union
+		{
+			struct   // Fixed semantics
+			{
+				union   // Position
+				{
+					struct
+					{
+						float x;
+						float y;
+						float z;
+						float w;
+					};
+
+					struct
+					{
+						float4 P;
+					};
+				};
+
+				float4 C[2];   // Diffuse and specular color
+
+				UVWQ T[8];           // Texture coordinates
+
+				float f;             // Fog
+				float pSize;         // Point size
+				unsigned char padding0[4];
+				unsigned char clipFlags;
+				unsigned char padding1[3];
+			};
+
+			float4 v[12];   // Generic components using semantic declaration
+		};
+
+		struct   // Projected coordinates
+		{
+			int X;
+			int Y;
+			float Z;
+			float W;
+		};
+	});
+
+	META_ASSERT((sizeof(Vertex) & 0x0000000F) == 0);
+}
+
+#endif   // Vertex_hpp
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 24f40cc..0b76520 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "VertexProcessor.hpp"
 
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index caebbfa..14758bb 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -1,340 +1,343 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_VertexProcessor_hpp

-#define sw_VertexProcessor_hpp

-

-#include "Matrix.hpp"

-#include "Context.hpp"

-#include "RoutineCache.hpp"

-

-namespace sw

-{

-	struct DrawData;

-

-	struct VertexCache   // FIXME: Variable size

-	{

-		void clear();

-

-		Vertex vertex[16][4];

-		unsigned int tag[16];

-

-		int drawCall;

-	};

-

-	struct VertexTask

-	{

-		unsigned int vertexStart;

-		unsigned int vertexCount;

-		unsigned int verticesPerPrimitive;

-		VertexCache vertexCache;

-	};

-

-	class VertexProcessor

-	{

-	public:

-		struct States

-		{

-			unsigned int computeHash();

-

-			uint64_t shaderID;

-

-			bool fixedFunction             : 1;

-			bool textureSampling           : 1;

-			unsigned int positionRegister  : 4;

-			unsigned int pointSizeRegister : 4;   // 0xF signifies no vertex point size

-

-			unsigned int vertexBlendMatrixCount               : 3;

-			bool indexedVertexBlendEnable                     : 1;

-			bool vertexNormalActive                           : 1;

-			bool normalizeNormals                             : 1;

-			bool vertexLightingActive                         : 1;

-			bool diffuseActive                                : 1;

-			bool specularActive                               : 1;

-			bool vertexSpecularActive                         : 1;

-			unsigned int vertexLightActive                    : 8;

-			MaterialSource vertexDiffuseMaterialSourceActive  : BITS(MATERIAL_LAST);

-			MaterialSource vertexSpecularMaterialSourceActive : BITS(MATERIAL_LAST);

-			MaterialSource vertexAmbientMaterialSourceActive  : BITS(MATERIAL_LAST);

-			MaterialSource vertexEmissiveMaterialSourceActive : BITS(MATERIAL_LAST);

-			bool fogActive                                    : 1;

-			FogMode vertexFogMode                             : BITS(FOG_LAST);

-			bool rangeFogActive                               : 1;

-			bool localViewerActive                            : 1;

-			bool pointSizeActive                              : 1;

-			bool pointScaleActive                             : 1;

-			bool transformFeedbackQueryEnabled                : 1;

-			uint64_t transformFeedbackEnabled                 : 64;

-

-			bool preTransformed : 1;

-			bool superSampling  : 1;

-			bool multiSampling  : 1;

-

-			struct TextureState

-			{

-				TexGen texGenActive                       : BITS(TEXGEN_LAST);

-				unsigned char textureTransformCountActive : 3;

-				unsigned char texCoordIndexActive         : 3;

-			};

-

-			TextureState textureState[8];

-

-			Sampler::State samplerState[VERTEX_TEXTURE_IMAGE_UNITS];

-

-			struct Input

-			{

-				operator bool() const   // Returns true if stream contains data

-				{

-					return count != 0;

-				}

-

-				StreamType type    : BITS(STREAMTYPE_LAST);

-				unsigned int count : 3;

-				bool normalized    : 1;

-			};

-

-			struct Output

-			{

-				union

-				{

-					unsigned char write : 4;

-

-					struct

-					{

-						unsigned char xWrite : 1;

-						unsigned char yWrite : 1;

-						unsigned char zWrite : 1;

-						unsigned char wWrite : 1;

-					};

-				};

-

-				union

-				{

-					unsigned char clamp : 4;

-

-					struct

-					{

-						unsigned char xClamp : 1;

-						unsigned char yClamp : 1;

-						unsigned char zClamp : 1;

-						unsigned char wClamp : 1;

-					};

-				};

-			};

-

-			Input input[VERTEX_ATTRIBUTES];

-			Output output[12];

-		};

-

-		struct State : States

-		{

-			State();

-

-			bool operator==(const State &state) const;

-

-			unsigned int hash;

-		};

-

-		struct FixedFunction

-		{

-			float4 transformT[12][4];

-			float4 cameraTransformT[12][4];

-			float4 normalTransformT[12][4];

-			float4 textureTransform[8][4];

-

-			float4 lightPosition[8];

-			float4 lightAmbient[8];

-			float4 lightSpecular[8];

-			float4 lightDiffuse[8];

-			float4 attenuationConstant[8];

-			float4 attenuationLinear[8];

-			float4 attenuationQuadratic[8];

-			float lightRange[8];

-			float4 materialDiffuse;

-			float4 materialSpecular;

-			float materialShininess;

-			float4 globalAmbient;

-			float4 materialEmission;

-			float4 materialAmbient;

-		};

-

-		struct PointSprite

-		{

-			float4 pointSize;

-			float pointSizeMin;

-			float pointSizeMax;

-			float pointScaleA;

-			float pointScaleB;

-			float pointScaleC;

-		};

-

-		typedef void (*RoutinePointer)(Vertex *output, unsigned int *batch, VertexTask *vertexTask, DrawData *draw);

-

-		VertexProcessor(Context *context);

-

-		virtual ~VertexProcessor();

-

-		virtual void setInputStream(int index, const Stream &stream);

-		virtual void resetInputStreams(bool preTransformed);

-

-		virtual void setFloatConstant(unsigned int index, const float value[4]);

-		virtual void setIntegerConstant(unsigned int index, const int integer[4]);

-		virtual void setBooleanConstant(unsigned int index, int boolean);

-

-		virtual void setUniformBuffer(int index, sw::Resource* uniformBuffer, int offset);

-		virtual void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);

-

-		virtual void setTransformFeedbackBuffer(int index, sw::Resource* transformFeedbackBuffer, int offset, unsigned int reg, unsigned int row, unsigned int col, size_t stride);

-		virtual void lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[]);

-

-		// Transformations

-		virtual void setModelMatrix(const Matrix &M, int i = 0);

-		virtual void setViewMatrix(const Matrix &V);

-		virtual void setBaseMatrix(const Matrix &B);

-		virtual void setProjectionMatrix(const Matrix &P);

-

-		// Lighting

-		virtual void setLightingEnable(bool lightingEnable);

-		virtual void setLightEnable(unsigned int light, bool lightEnable);

-		virtual void setSpecularEnable(bool specularEnable);

-

-		virtual void setGlobalAmbient(const Color<float> &globalAmbient);

-		virtual void setLightPosition(unsigned int light, const Point &lightPosition);

-		virtual void setLightViewPosition(unsigned int light, const Point &lightPosition);

-		virtual void setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse);

-		virtual void setLightSpecular(unsigned int light, const Color<float> &lightSpecular);

-		virtual void setLightAmbient(unsigned int light, const Color<float> &lightAmbient);

-		virtual void setLightAttenuation(unsigned int light, float constant, float linear, float quadratic);

-		virtual void setLightRange(unsigned int light, float lightRange);

-

-		virtual void setInstanceID(int instanceID);

-

-		virtual void setFogEnable(bool fogEnable);

-		virtual void setVertexFogMode(FogMode fogMode);

-		virtual void setRangeFogEnable(bool enable);

-

-		virtual void setColorVertexEnable(bool colorVertexEnable);

-		virtual void setDiffuseMaterialSource(MaterialSource diffuseMaterialSource);

-		virtual void setSpecularMaterialSource(MaterialSource specularMaterialSource);

-		virtual void setAmbientMaterialSource(MaterialSource ambientMaterialSource);

-		virtual void setEmissiveMaterialSource(MaterialSource emissiveMaterialSource);

-

-		virtual void setMaterialEmission(const Color<float> &emission);

-		virtual void setMaterialAmbient(const Color<float> &materialAmbient);

-		virtual void setMaterialDiffuse(const Color<float> &diffuseColor);

-		virtual void setMaterialSpecular(const Color<float> &specularColor);

-		virtual void setMaterialShininess(float specularPower);

-

-		virtual void setIndexedVertexBlendEnable(bool indexedVertexBlendEnable);

-		virtual void setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount);

-

-		virtual void setTextureWrap(unsigned int stage, int mask);

-		virtual void setTexGen(unsigned int stage, TexGen texGen);

-		virtual void setLocalViewer(bool localViewer);

-		virtual void setNormalizeNormals(bool normalizeNormals);

-		virtual void setTextureMatrix(int stage, const Matrix &T);

-		virtual void setTextureTransform(int stage, int count, bool project);

-

-		virtual void setTextureFilter(unsigned int sampler, FilterType textureFilter);

-		virtual void setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter);

-		virtual void setGatherEnable(unsigned int sampler, bool enable);

-		virtual void setAddressingModeU(unsigned int sampler, AddressingMode addressingMode);

-		virtual void setAddressingModeV(unsigned int sampler, AddressingMode addressingMode);

-		virtual void setAddressingModeW(unsigned int sampler, AddressingMode addressingMode);

-		virtual void setReadSRGB(unsigned int sampler, bool sRGB);

-		virtual void setMipmapLOD(unsigned int sampler, float bias);

-		virtual void setBorderColor(unsigned int sampler, const Color<float> &borderColor);

-		virtual void setMaxAnisotropy(unsigned int stage, float maxAnisotropy);

-		virtual void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);

-		virtual void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);

-		virtual void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);

-		virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);

-

-		virtual void setPointSize(float pointSize);

-		virtual void setPointSizeMin(float pointSizeMin);

-		virtual void setPointSizeMax(float pointSizeMax);

-		virtual void setPointScaleA(float pointScaleA);

-		virtual void setPointScaleB(float pointScaleB);

-		virtual void setPointScaleC(float pointScaleC);

-

-		virtual void setTransformFeedbackQueryEnabled(bool enable);

-		virtual void enableTransformFeedback(uint64_t enable);

-

-	protected:

-		const Matrix &getModelTransform(int i);

-		const Matrix &getViewTransform();

-

-		const State update();

-		Routine *routine(const State &state);

-

-		bool isFixedFunction();

-		void setRoutineCacheSize(int cacheSize);

-

-		// Shader constants

-		float4 c[VERTEX_UNIFORM_VECTORS + 1];   // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}

-		int4 i[16];

-		bool b[16];

-

-		PointSprite point;

-		FixedFunction ff;

-

-	private:

-		struct UniformBufferInfo

-		{

-			UniformBufferInfo();

-

-			Resource* buffer;

-			int offset;

-		};

-		UniformBufferInfo uniformBufferInfo[MAX_UNIFORM_BUFFER_BINDINGS];

-

-		struct TransformFeedbackInfo

-		{

-			TransformFeedbackInfo();

-

-			Resource* buffer;

-			int offset;

-			int reg;

-			int row;

-			int col;

-			size_t stride;

-		};

-		TransformFeedbackInfo transformFeedbackInfo[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];

-

-		void updateTransform();

-		void setTransform(const Matrix &M, int i);

-		void setCameraTransform(const Matrix &M, int i);

-		void setNormalTransform(const Matrix &M, int i);

-

-		Context *const context;

-

-		RoutineCache<State> *routineCache;

-

-	protected:

-		Matrix M[12];      // Model/Geometry/World matrix

-		Matrix V;          // View/Camera/Eye matrix

-		Matrix B;          // Base matrix

-		Matrix P;          // Projection matrix

-		Matrix PB;         // P * B

-		Matrix PBV;        // P * B * V

-		Matrix PBVM[12];   // P * B * V * M

-

-		// Update hierarchy

-		bool updateMatrix;

-		bool updateModelMatrix[12];

-		bool updateViewMatrix;

-		bool updateBaseMatrix;

-		bool updateProjectionMatrix;

-		bool updateLighting;

-	};

-}

-

-#endif   // sw_VertexProcessor_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_VertexProcessor_hpp
+#define sw_VertexProcessor_hpp
+
+#include "Matrix.hpp"
+#include "Context.hpp"
+#include "RoutineCache.hpp"
+
+namespace sw
+{
+	struct DrawData;
+
+	struct VertexCache   // FIXME: Variable size
+	{
+		void clear();
+
+		Vertex vertex[16][4];
+		unsigned int tag[16];
+
+		int drawCall;
+	};
+
+	struct VertexTask
+	{
+		unsigned int vertexStart;
+		unsigned int vertexCount;
+		unsigned int verticesPerPrimitive;
+		VertexCache vertexCache;
+	};
+
+	class VertexProcessor
+	{
+	public:
+		struct States
+		{
+			unsigned int computeHash();
+
+			uint64_t shaderID;
+
+			bool fixedFunction             : 1;
+			bool textureSampling           : 1;
+			unsigned int positionRegister  : 4;
+			unsigned int pointSizeRegister : 4;   // 0xF signifies no vertex point size
+
+			unsigned int vertexBlendMatrixCount               : 3;
+			bool indexedVertexBlendEnable                     : 1;
+			bool vertexNormalActive                           : 1;
+			bool normalizeNormals                             : 1;
+			bool vertexLightingActive                         : 1;
+			bool diffuseActive                                : 1;
+			bool specularActive                               : 1;
+			bool vertexSpecularActive                         : 1;
+			unsigned int vertexLightActive                    : 8;
+			MaterialSource vertexDiffuseMaterialSourceActive  : BITS(MATERIAL_LAST);
+			MaterialSource vertexSpecularMaterialSourceActive : BITS(MATERIAL_LAST);
+			MaterialSource vertexAmbientMaterialSourceActive  : BITS(MATERIAL_LAST);
+			MaterialSource vertexEmissiveMaterialSourceActive : BITS(MATERIAL_LAST);
+			bool fogActive                                    : 1;
+			FogMode vertexFogMode                             : BITS(FOG_LAST);
+			bool rangeFogActive                               : 1;
+			bool localViewerActive                            : 1;
+			bool pointSizeActive                              : 1;
+			bool pointScaleActive                             : 1;
+			bool transformFeedbackQueryEnabled                : 1;
+			uint64_t transformFeedbackEnabled                 : 64;
+
+			bool preTransformed : 1;
+			bool superSampling  : 1;
+			bool multiSampling  : 1;
+
+			struct TextureState
+			{
+				TexGen texGenActive                       : BITS(TEXGEN_LAST);
+				unsigned char textureTransformCountActive : 3;
+				unsigned char texCoordIndexActive         : 3;
+			};
+
+			TextureState textureState[8];
+
+			Sampler::State samplerState[VERTEX_TEXTURE_IMAGE_UNITS];
+
+			struct Input
+			{
+				operator bool() const   // Returns true if stream contains data
+				{
+					return count != 0;
+				}
+
+				StreamType type    : BITS(STREAMTYPE_LAST);
+				unsigned int count : 3;
+				bool normalized    : 1;
+			};
+
+			struct Output
+			{
+				union
+				{
+					unsigned char write : 4;
+
+					struct
+					{
+						unsigned char xWrite : 1;
+						unsigned char yWrite : 1;
+						unsigned char zWrite : 1;
+						unsigned char wWrite : 1;
+					};
+				};
+
+				union
+				{
+					unsigned char clamp : 4;
+
+					struct
+					{
+						unsigned char xClamp : 1;
+						unsigned char yClamp : 1;
+						unsigned char zClamp : 1;
+						unsigned char wClamp : 1;
+					};
+				};
+			};
+
+			Input input[VERTEX_ATTRIBUTES];
+			Output output[12];
+		};
+
+		struct State : States
+		{
+			State();
+
+			bool operator==(const State &state) const;
+
+			unsigned int hash;
+		};
+
+		struct FixedFunction
+		{
+			float4 transformT[12][4];
+			float4 cameraTransformT[12][4];
+			float4 normalTransformT[12][4];
+			float4 textureTransform[8][4];
+
+			float4 lightPosition[8];
+			float4 lightAmbient[8];
+			float4 lightSpecular[8];
+			float4 lightDiffuse[8];
+			float4 attenuationConstant[8];
+			float4 attenuationLinear[8];
+			float4 attenuationQuadratic[8];
+			float lightRange[8];
+			float4 materialDiffuse;
+			float4 materialSpecular;
+			float materialShininess;
+			float4 globalAmbient;
+			float4 materialEmission;
+			float4 materialAmbient;
+		};
+
+		struct PointSprite
+		{
+			float4 pointSize;
+			float pointSizeMin;
+			float pointSizeMax;
+			float pointScaleA;
+			float pointScaleB;
+			float pointScaleC;
+		};
+
+		typedef void (*RoutinePointer)(Vertex *output, unsigned int *batch, VertexTask *vertexTask, DrawData *draw);
+
+		VertexProcessor(Context *context);
+
+		virtual ~VertexProcessor();
+
+		virtual void setInputStream(int index, const Stream &stream);
+		virtual void resetInputStreams(bool preTransformed);
+
+		virtual void setFloatConstant(unsigned int index, const float value[4]);
+		virtual void setIntegerConstant(unsigned int index, const int integer[4]);
+		virtual void setBooleanConstant(unsigned int index, int boolean);
+
+		virtual void setUniformBuffer(int index, sw::Resource* uniformBuffer, int offset);
+		virtual void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);
+
+		virtual void setTransformFeedbackBuffer(int index, sw::Resource* transformFeedbackBuffer, int offset, unsigned int reg, unsigned int row, unsigned int col, size_t stride);
+		virtual void lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[]);
+
+		// Transformations
+		virtual void setModelMatrix(const Matrix &M, int i = 0);
+		virtual void setViewMatrix(const Matrix &V);
+		virtual void setBaseMatrix(const Matrix &B);
+		virtual void setProjectionMatrix(const Matrix &P);
+
+		// Lighting
+		virtual void setLightingEnable(bool lightingEnable);
+		virtual void setLightEnable(unsigned int light, bool lightEnable);
+		virtual void setSpecularEnable(bool specularEnable);
+
+		virtual void setGlobalAmbient(const Color<float> &globalAmbient);
+		virtual void setLightPosition(unsigned int light, const Point &lightPosition);
+		virtual void setLightViewPosition(unsigned int light, const Point &lightPosition);
+		virtual void setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse);
+		virtual void setLightSpecular(unsigned int light, const Color<float> &lightSpecular);
+		virtual void setLightAmbient(unsigned int light, const Color<float> &lightAmbient);
+		virtual void setLightAttenuation(unsigned int light, float constant, float linear, float quadratic);
+		virtual void setLightRange(unsigned int light, float lightRange);
+
+		virtual void setInstanceID(int instanceID);
+
+		virtual void setFogEnable(bool fogEnable);
+		virtual void setVertexFogMode(FogMode fogMode);
+		virtual void setRangeFogEnable(bool enable);
+
+		virtual void setColorVertexEnable(bool colorVertexEnable);
+		virtual void setDiffuseMaterialSource(MaterialSource diffuseMaterialSource);
+		virtual void setSpecularMaterialSource(MaterialSource specularMaterialSource);
+		virtual void setAmbientMaterialSource(MaterialSource ambientMaterialSource);
+		virtual void setEmissiveMaterialSource(MaterialSource emissiveMaterialSource);
+
+		virtual void setMaterialEmission(const Color<float> &emission);
+		virtual void setMaterialAmbient(const Color<float> &materialAmbient);
+		virtual void setMaterialDiffuse(const Color<float> &diffuseColor);
+		virtual void setMaterialSpecular(const Color<float> &specularColor);
+		virtual void setMaterialShininess(float specularPower);
+
+		virtual void setIndexedVertexBlendEnable(bool indexedVertexBlendEnable);
+		virtual void setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount);
+
+		virtual void setTextureWrap(unsigned int stage, int mask);
+		virtual void setTexGen(unsigned int stage, TexGen texGen);
+		virtual void setLocalViewer(bool localViewer);
+		virtual void setNormalizeNormals(bool normalizeNormals);
+		virtual void setTextureMatrix(int stage, const Matrix &T);
+		virtual void setTextureTransform(int stage, int count, bool project);
+
+		virtual void setTextureFilter(unsigned int sampler, FilterType textureFilter);
+		virtual void setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter);
+		virtual void setGatherEnable(unsigned int sampler, bool enable);
+		virtual void setAddressingModeU(unsigned int sampler, AddressingMode addressingMode);
+		virtual void setAddressingModeV(unsigned int sampler, AddressingMode addressingMode);
+		virtual void setAddressingModeW(unsigned int sampler, AddressingMode addressingMode);
+		virtual void setReadSRGB(unsigned int sampler, bool sRGB);
+		virtual void setMipmapLOD(unsigned int sampler, float bias);
+		virtual void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
+		virtual void setMaxAnisotropy(unsigned int stage, float maxAnisotropy);
+		virtual void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
+		virtual void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
+		virtual void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
+		virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
+
+		virtual void setPointSize(float pointSize);
+		virtual void setPointSizeMin(float pointSizeMin);
+		virtual void setPointSizeMax(float pointSizeMax);
+		virtual void setPointScaleA(float pointScaleA);
+		virtual void setPointScaleB(float pointScaleB);
+		virtual void setPointScaleC(float pointScaleC);
+
+		virtual void setTransformFeedbackQueryEnabled(bool enable);
+		virtual void enableTransformFeedback(uint64_t enable);
+
+	protected:
+		const Matrix &getModelTransform(int i);
+		const Matrix &getViewTransform();
+
+		const State update();
+		Routine *routine(const State &state);
+
+		bool isFixedFunction();
+		void setRoutineCacheSize(int cacheSize);
+
+		// Shader constants
+		float4 c[VERTEX_UNIFORM_VECTORS + 1];   // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
+		int4 i[16];
+		bool b[16];
+
+		PointSprite point;
+		FixedFunction ff;
+
+	private:
+		struct UniformBufferInfo
+		{
+			UniformBufferInfo();
+
+			Resource* buffer;
+			int offset;
+		};
+		UniformBufferInfo uniformBufferInfo[MAX_UNIFORM_BUFFER_BINDINGS];
+
+		struct TransformFeedbackInfo
+		{
+			TransformFeedbackInfo();
+
+			Resource* buffer;
+			int offset;
+			int reg;
+			int row;
+			int col;
+			size_t stride;
+		};
+		TransformFeedbackInfo transformFeedbackInfo[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
+
+		void updateTransform();
+		void setTransform(const Matrix &M, int i);
+		void setCameraTransform(const Matrix &M, int i);
+		void setNormalTransform(const Matrix &M, int i);
+
+		Context *const context;
+
+		RoutineCache<State> *routineCache;
+
+	protected:
+		Matrix M[12];      // Model/Geometry/World matrix
+		Matrix V;          // View/Camera/Eye matrix
+		Matrix B;          // Base matrix
+		Matrix P;          // Projection matrix
+		Matrix PB;         // P * B
+		Matrix PBV;        // P * B * V
+		Matrix PBVM[12];   // P * B * V * M
+
+		// Update hierarchy
+		bool updateMatrix;
+		bool updateModelMatrix[12];
+		bool updateViewMatrix;
+		bool updateBaseMatrix;
+		bool updateProjectionMatrix;
+		bool updateLighting;
+	};
+}
+
+#endif   // sw_VertexProcessor_hpp
diff --git a/src/Shader/Constants.cpp b/src/Shader/Constants.cpp
index bd15a1f..0420947 100644
--- a/src/Shader/Constants.cpp
+++ b/src/Shader/Constants.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Constants.hpp"
 
diff --git a/src/Shader/Constants.hpp b/src/Shader/Constants.hpp
index 859955c..e40ad5e 100644
--- a/src/Shader/Constants.hpp
+++ b/src/Shader/Constants.hpp
@@ -1,113 +1,116 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Constants_hpp

-#define sw_Constants_hpp

-

-#include "Common/Types.hpp"

-

-namespace sw

-{

-	struct Constants

-	{

-		Constants();

-		

-		unsigned int transposeBit0[16];

-		unsigned int transposeBit1[16];

-		unsigned int transposeBit2[16];

-

-		ushort4 cWeight[17];

-		float4 uvWeight[17];

-		float4 uvStart[17];

-

-		unsigned int occlusionCount[16];

-

-		byte8 maskB4Q[16];

-		byte8 invMaskB4Q[16];

-		word4 maskW4Q[16];

-		word4 invMaskW4Q[16];

-		dword4 maskD4X[16];

-		dword4 invMaskD4X[16];

-		qword maskQ0Q[16];

-		qword maskQ1Q[16];

-		qword maskQ2Q[16];

-		qword maskQ3Q[16];

-		qword invMaskQ0Q[16];

-		qword invMaskQ1Q[16];

-		qword invMaskQ2Q[16];

-		qword invMaskQ3Q[16];

-		dword4 maskX0X[16];

-		dword4 maskX1X[16];

-		dword4 maskX2X[16];

-		dword4 maskX3X[16];

-		dword4 invMaskX0X[16];

-		dword4 invMaskX1X[16];

-		dword4 invMaskX2X[16];

-		dword4 invMaskX3X[16];

-		dword2 maskD01Q[16];

-		dword2 maskD23Q[16];

-		dword2 invMaskD01Q[16];

-		dword2 invMaskD23Q[16];

-		qword2 maskQ01X[16];

-		qword2 maskQ23X[16];

-		qword2 invMaskQ01X[16];

-		qword2 invMaskQ23X[16];

-		word4 maskW01Q[4];

-		word4 invMaskW01Q[4];

-		dword4 maskD01X[4];

-		dword4 invMaskD01X[4];

-		word4 mask565Q[8];

-		word4 invMask565Q[8];

-

-		unsigned short sRGBtoLinear8_12[256];

-		unsigned short sRGBtoLinear6_12[64];

-		unsigned short sRGBtoLinear5_12[32];

-

-		unsigned short linearToSRGB12_16[4096];

-		unsigned short sRGBtoLinear12_16[4096];

-

-		// Centroid parameters

-		float4 sampleX[4][16];

-		float4 sampleY[4][16];

-		float4 weight[16];

-

-		// Fragment offsets

-		int Xf[4];

-		int Yf[4];

-

-		float4 X[4];

-		float4 Y[4];

-

-		dword maxX[16];

-		dword maxY[16];

-		dword maxZ[16];

-		dword minX[16];

-		dword minY[16];

-		dword minZ[16];

-		dword fini[16];

-

-		dword4 maxPos;

-

-		float4 unscaleByte;

-		float4 unscaleSByte;

-		float4 unscaleShort;

-		float4 unscaleUShort;

-		float4 unscaleInt;

-		float4 unscaleUInt;

-		float4 unscaleFixed;

-

-		float half2float[65536];

-	};

-

-	extern Constants constants;

-}

-

-#endif   // sw_Constants_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Constants_hpp
+#define sw_Constants_hpp
+
+#include "Common/Types.hpp"
+
+namespace sw
+{
+	struct Constants
+	{
+		Constants();
+	
+		unsigned int transposeBit0[16];
+		unsigned int transposeBit1[16];
+		unsigned int transposeBit2[16];
+
+		ushort4 cWeight[17];
+		float4 uvWeight[17];
+		float4 uvStart[17];
+
+		unsigned int occlusionCount[16];
+
+		byte8 maskB4Q[16];
+		byte8 invMaskB4Q[16];
+		word4 maskW4Q[16];
+		word4 invMaskW4Q[16];
+		dword4 maskD4X[16];
+		dword4 invMaskD4X[16];
+		qword maskQ0Q[16];
+		qword maskQ1Q[16];
+		qword maskQ2Q[16];
+		qword maskQ3Q[16];
+		qword invMaskQ0Q[16];
+		qword invMaskQ1Q[16];
+		qword invMaskQ2Q[16];
+		qword invMaskQ3Q[16];
+		dword4 maskX0X[16];
+		dword4 maskX1X[16];
+		dword4 maskX2X[16];
+		dword4 maskX3X[16];
+		dword4 invMaskX0X[16];
+		dword4 invMaskX1X[16];
+		dword4 invMaskX2X[16];
+		dword4 invMaskX3X[16];
+		dword2 maskD01Q[16];
+		dword2 maskD23Q[16];
+		dword2 invMaskD01Q[16];
+		dword2 invMaskD23Q[16];
+		qword2 maskQ01X[16];
+		qword2 maskQ23X[16];
+		qword2 invMaskQ01X[16];
+		qword2 invMaskQ23X[16];
+		word4 maskW01Q[4];
+		word4 invMaskW01Q[4];
+		dword4 maskD01X[4];
+		dword4 invMaskD01X[4];
+		word4 mask565Q[8];
+		word4 invMask565Q[8];
+
+		unsigned short sRGBtoLinear8_12[256];
+		unsigned short sRGBtoLinear6_12[64];
+		unsigned short sRGBtoLinear5_12[32];
+
+		unsigned short linearToSRGB12_16[4096];
+		unsigned short sRGBtoLinear12_16[4096];
+
+		// Centroid parameters
+		float4 sampleX[4][16];
+		float4 sampleY[4][16];
+		float4 weight[16];
+
+		// Fragment offsets
+		int Xf[4];
+		int Yf[4];
+
+		float4 X[4];
+		float4 Y[4];
+
+		dword maxX[16];
+		dword maxY[16];
+		dword maxZ[16];
+		dword minX[16];
+		dword minY[16];
+		dword minZ[16];
+		dword fini[16];
+
+		dword4 maxPos;
+
+		float4 unscaleByte;
+		float4 unscaleSByte;
+		float4 unscaleShort;
+		float4 unscaleUShort;
+		float4 unscaleInt;
+		float4 unscaleUInt;
+		float4 unscaleFixed;
+
+		float half2float[65536];
+	};
+
+	extern Constants constants;
+}
+
+#endif   // sw_Constants_hpp
diff --git a/src/Shader/PixelPipeline.cpp b/src/Shader/PixelPipeline.cpp
index 8adeed8..e353c27 100644
--- a/src/Shader/PixelPipeline.cpp
+++ b/src/Shader/PixelPipeline.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2015 Google Inc.
+// 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
 //
-// 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 Google Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "PixelPipeline.hpp"
 #include "Renderer.hpp"
diff --git a/src/Shader/PixelPipeline.hpp b/src/Shader/PixelPipeline.hpp
index 4d0362d..d8d2a03 100644
--- a/src/Shader/PixelPipeline.hpp
+++ b/src/Shader/PixelPipeline.hpp
@@ -1,111 +1,114 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-#ifndef sw_PixelPipeline_hpp

-#define sw_PixelPipeline_hpp

-

-#include "PixelRoutine.hpp"

-

-namespace sw

-{

-	class PixelPipeline : public PixelRoutine

-	{

-	public:

-		PixelPipeline(const PixelProcessor::State &state, const PixelShader *shader) :

-			PixelRoutine(state, shader), current(rs[0]), diffuse(vs[0]), specular(vs[1]), perturbate(false), luminance(false), previousScaling(false) {}

-		virtual ~PixelPipeline() {}

-

-	protected:

-		virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);

-		virtual void applyShader(Int cMask[4]);

-		virtual Bool alphaTest(Int cMask[4]);

-		virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);

-

-	private:

-		Vector4s &current;

-		Vector4s &diffuse;

-		Vector4s &specular;

-

-		Vector4s rs[6];

-		Vector4s vs[2];

-		Vector4s ts[6];

-

-		// bem(l) offsets and luminance

-		Float4 du;

-		Float4 dv;

-		Short4 L;

-

-		// texm3x3 temporaries

-		Float4 u_; // FIXME

-		Float4 v_; // FIXME

-		Float4 w_; // FIXME

-		Float4 U;  // FIXME

-		Float4 V;  // FIXME

-		Float4 W;  // FIXME

-

-		void fixedFunction();

-		void blendTexture(Vector4s &temp, Vector4s &texture, int stage);

-		void fogBlend(Vector4s &current, Float4 &fog);

-		void specularPixel(Vector4s &current, Vector4s &specular);

-

-		void sampleTexture(Vector4s &c, int coordinates, int sampler, bool project = false);

-		void sampleTexture(Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false);

-

-		Short4 convertFixed12(RValue<Float4> cf);

-		void convertFixed12(Vector4s &cs, Vector4f &cf);

-		Float4 convertSigned12(Short4 &cs);

-		void convertSigned12(Vector4f &cf, Vector4s &cs);

-

-		void writeDestination(Vector4s &d, const Dst &dst);

-		Vector4s fetchRegister(const Src &src);

-

-		// Instructions

-		void MOV(Vector4s &dst, Vector4s &src0);

-		void ADD(Vector4s &dst, Vector4s &src0, Vector4s &src1);

-		void SUB(Vector4s &dst, Vector4s &src0, Vector4s &src1);

-		void MAD(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);

-		void MUL(Vector4s &dst, Vector4s &src0, Vector4s &src1);

-		void DP3(Vector4s &dst, Vector4s &src0, Vector4s &src1);

-		void DP4(Vector4s &dst, Vector4s &src0, Vector4s &src1);

-		void LRP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);

-		void TEXCOORD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate);

-		void TEXCRD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate, bool project);

-		void TEXDP3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src);

-		void TEXDP3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0);

-		void TEXKILL(Int cMask[4], Float4 &u, Float4 &v, Float4 &s);

-		void TEXKILL(Int cMask[4], Vector4s &dst);

-		void TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, bool project);

-		void TEXLD(Vector4s &dst, Vector4s &src, int stage, bool project);

-		void TEXBEM(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);

-		void TEXBEML(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);

-		void TEXREG2AR(Vector4s &dst, Vector4s &src0, int stage);

-		void TEXREG2GB(Vector4s &dst, Vector4s &src0, int stage);

-		void TEXREG2RGB(Vector4s &dst, Vector4s &src0, int stage);

-		void TEXM3X2DEPTH(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src, bool signedScaling);

-		void TEXM3X2PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);

-		void TEXM3X2TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool signedScaling);

-		void TEXM3X3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, bool signedScaling);

-		void TEXM3X3PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);

-		void TEXM3X3SPEC(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, Vector4s &src1);

-		void TEXM3X3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool singedScaling);

-		void TEXM3X3VSPEC(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0);

-		void TEXDEPTH();

-		void CND(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);

-		void CMP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);

-		void BEM(Vector4s &dst, Vector4s &src0, Vector4s &src1, int stage);

-

-		bool perturbate;

-		bool luminance;

-		bool previousScaling;

-	};

-}

-

-#endif

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_PixelPipeline_hpp
+#define sw_PixelPipeline_hpp
+
+#include "PixelRoutine.hpp"
+
+namespace sw
+{
+	class PixelPipeline : public PixelRoutine
+	{
+	public:
+		PixelPipeline(const PixelProcessor::State &state, const PixelShader *shader) :
+			PixelRoutine(state, shader), current(rs[0]), diffuse(vs[0]), specular(vs[1]), perturbate(false), luminance(false), previousScaling(false) {}
+		virtual ~PixelPipeline() {}
+
+	protected:
+		virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);
+		virtual void applyShader(Int cMask[4]);
+		virtual Bool alphaTest(Int cMask[4]);
+		virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
+
+	private:
+		Vector4s &current;
+		Vector4s &diffuse;
+		Vector4s &specular;
+
+		Vector4s rs[6];
+		Vector4s vs[2];
+		Vector4s ts[6];
+
+		// bem(l) offsets and luminance
+		Float4 du;
+		Float4 dv;
+		Short4 L;
+
+		// texm3x3 temporaries
+		Float4 u_; // FIXME
+		Float4 v_; // FIXME
+		Float4 w_; // FIXME
+		Float4 U;  // FIXME
+		Float4 V;  // FIXME
+		Float4 W;  // FIXME
+
+		void fixedFunction();
+		void blendTexture(Vector4s &temp, Vector4s &texture, int stage);
+		void fogBlend(Vector4s &current, Float4 &fog);
+		void specularPixel(Vector4s &current, Vector4s &specular);
+
+		void sampleTexture(Vector4s &c, int coordinates, int sampler, bool project = false);
+		void sampleTexture(Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false);
+
+		Short4 convertFixed12(RValue<Float4> cf);
+		void convertFixed12(Vector4s &cs, Vector4f &cf);
+		Float4 convertSigned12(Short4 &cs);
+		void convertSigned12(Vector4f &cf, Vector4s &cs);
+
+		void writeDestination(Vector4s &d, const Dst &dst);
+		Vector4s fetchRegister(const Src &src);
+
+		// Instructions
+		void MOV(Vector4s &dst, Vector4s &src0);
+		void ADD(Vector4s &dst, Vector4s &src0, Vector4s &src1);
+		void SUB(Vector4s &dst, Vector4s &src0, Vector4s &src1);
+		void MAD(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
+		void MUL(Vector4s &dst, Vector4s &src0, Vector4s &src1);
+		void DP3(Vector4s &dst, Vector4s &src0, Vector4s &src1);
+		void DP4(Vector4s &dst, Vector4s &src0, Vector4s &src1);
+		void LRP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
+		void TEXCOORD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate);
+		void TEXCRD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate, bool project);
+		void TEXDP3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src);
+		void TEXDP3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0);
+		void TEXKILL(Int cMask[4], Float4 &u, Float4 &v, Float4 &s);
+		void TEXKILL(Int cMask[4], Vector4s &dst);
+		void TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, bool project);
+		void TEXLD(Vector4s &dst, Vector4s &src, int stage, bool project);
+		void TEXBEM(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);
+		void TEXBEML(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);
+		void TEXREG2AR(Vector4s &dst, Vector4s &src0, int stage);
+		void TEXREG2GB(Vector4s &dst, Vector4s &src0, int stage);
+		void TEXREG2RGB(Vector4s &dst, Vector4s &src0, int stage);
+		void TEXM3X2DEPTH(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src, bool signedScaling);
+		void TEXM3X2PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);
+		void TEXM3X2TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool signedScaling);
+		void TEXM3X3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, bool signedScaling);
+		void TEXM3X3PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);
+		void TEXM3X3SPEC(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, Vector4s &src1);
+		void TEXM3X3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool singedScaling);
+		void TEXM3X3VSPEC(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0);
+		void TEXDEPTH();
+		void CND(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
+		void CMP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
+		void BEM(Vector4s &dst, Vector4s &src0, Vector4s &src1, int stage);
+
+		bool perturbate;
+		bool luminance;
+		bool previousScaling;
+	};
+}
+
+#endif
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp
index 2984b9e..d229a92 100644
--- a/src/Shader/PixelProgram.cpp
+++ b/src/Shader/PixelProgram.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2015 Google Inc.
+// 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
 //
-// 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 Google Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "PixelProgram.hpp"
 #include "Primitive.hpp"
diff --git a/src/Shader/PixelProgram.hpp b/src/Shader/PixelProgram.hpp
index 085255d..a518cc1 100644
--- a/src/Shader/PixelProgram.hpp
+++ b/src/Shader/PixelProgram.hpp
@@ -1,165 +1,168 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2015 Google 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 Google Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-#ifndef sw_PixelProgram_hpp

-#define sw_PixelProgram_hpp

-

-#include "PixelRoutine.hpp"

-#include "SamplerCore.hpp"

-

-namespace sw

-{

-	class PixelProgram : public PixelRoutine

-	{

-	public:

-		PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :

-			PixelRoutine(state, shader), r(shader && shader->dynamicallyIndexedTemporaries),

-			loopDepth(-1), ifDepth(0), loopRepDepth(0), breakDepth(0), currentLabel(-1), whileTest(false)

-		{

-			for(int i = 0; i < 2048; ++i)

-			{

-				labelBlock[i] = 0;

-			}

-

-			enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);

-

-			if(shader && shader->containsBreakInstruction())

-			{

-				enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);

-			}

-

-			if(shader && shader->containsContinueInstruction())

-			{

-				enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);

-			}

-		}

-

-		virtual ~PixelProgram() {}

-

-	protected:

-		virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);

-		virtual void applyShader(Int cMask[4]);

-		virtual Bool alphaTest(Int cMask[4]);

-		virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);

-

-	private:

-		// Temporary registers

-		RegisterArray<4096> r;

-

-		// Color outputs

-		Vector4f c[RENDERTARGETS];

-		RegisterArray<RENDERTARGETS, true> oC;

-

-		// Shader variables

-		Vector4f vPos;

-		Vector4f vFace;

-

-		// DX9 specific variables

-		Vector4f p0;

-		Array<Int, 4> aL;

-		Array<Int, 4> increment;

-		Array<Int, 4> iteration;

-

-		Int loopDepth;    // FIXME: Add support for switch

-		Int stackIndex;   // FIXME: Inc/decrement callStack

-		Array<UInt, 16> callStack;

-

-		// Per pixel based on conditions reached

-		Int enableIndex;

-		Array<Int4, 1 + 24> enableStack;

-		Int4 enableBreak;

-		Int4 enableContinue;

-		Int4 enableLeave;

-

-		void sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method);

-		void sampleTexture(Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method);

-

-		// Raster operations

-		void clampColor(Vector4f oC[RENDERTARGETS]);

-

-		Int4 enableMask(const Shader::Instruction *instruction);

-

-		Vector4f fetchRegister(const Src &src, unsigned int offset = 0);

-		Vector4f readConstant(const Src &src, unsigned int offset = 0);

-		RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);

-		RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset);

-		Int relativeAddress(const Shader::Parameter &var, int bufferIndex = -1);

-

-		Float4 linearToSRGB(const Float4 &x);

-

-		// Instructions

-		typedef Shader::Control Control;

-

-		void M3X2(Vector4f &dst, Vector4f &src0, const Src &src1);

-		void M3X3(Vector4f &dst, Vector4f &src0, const Src &src1);

-		void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1);

-		void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);

-		void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);

-		void TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);

-		void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project);

-		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project);

-		void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);

-		void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);

-		void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, bool project, bool bias);

-		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias);

-		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);

-		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);

-		void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);

-		void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);

-		void DISCARD(Int cMask[4], const Shader::Instruction *instruction);

-		void DFDX(Vector4f &dst, Vector4f &src);

-		void DFDY(Vector4f &dst, Vector4f &src);

-		void FWIDTH(Vector4f &dst, Vector4f &src);

-		void BREAK();

-		void BREAKC(Vector4f &src0, Vector4f &src1, Control);

-		void BREAKP(const Src &predicateRegister);

-		void BREAK(Int4 &condition);

-		void CONTINUE();

-		void TEST();

-		void CALL(int labelIndex, int callSiteIndex);

-		void CALLNZ(int labelIndex, int callSiteIndex, const Src &src);

-		void CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister);

-		void CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister);

-		void ELSE();

-		void ENDIF();

-		void ENDLOOP();

-		void ENDREP();

-		void ENDWHILE();

-		void IF(const Src &src);

-		void IFb(const Src &boolRegister);

-		void IFp(const Src &predicateRegister);

-		void IFC(Vector4f &src0, Vector4f &src1, Control);

-		void IF(Int4 &condition);

-		void LABEL(int labelIndex);

-		void LOOP(const Src &integerRegister);

-		void REP(const Src &integerRegister);

-		void WHILE(const Src &temporaryRegister);

-		void RET();

-		void LEAVE();

-

-		int ifDepth;

-		int loopRepDepth;

-		int breakDepth;

-		int currentLabel;

-		bool whileTest;

-

-		// FIXME: Get rid of llvm::

-		llvm::BasicBlock *ifFalseBlock[24 + 24];

-		llvm::BasicBlock *loopRepTestBlock[4];

-		llvm::BasicBlock *loopRepEndBlock[4];

-		llvm::BasicBlock *labelBlock[2048];

-		std::vector<llvm::BasicBlock*> callRetBlock[2048];

-		llvm::BasicBlock *returnBlock;

-		bool isConditionalIf[24 + 24];

-	};

-}

-

-#endif

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_PixelProgram_hpp
+#define sw_PixelProgram_hpp
+
+#include "PixelRoutine.hpp"
+#include "SamplerCore.hpp"
+
+namespace sw
+{
+	class PixelProgram : public PixelRoutine
+	{
+	public:
+		PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :
+			PixelRoutine(state, shader), r(shader && shader->dynamicallyIndexedTemporaries),
+			loopDepth(-1), ifDepth(0), loopRepDepth(0), breakDepth(0), currentLabel(-1), whileTest(false)
+		{
+			for(int i = 0; i < 2048; ++i)
+			{
+				labelBlock[i] = 0;
+			}
+
+			enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+
+			if(shader && shader->containsBreakInstruction())
+			{
+				enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+			}
+
+			if(shader && shader->containsContinueInstruction())
+			{
+				enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+			}
+		}
+
+		virtual ~PixelProgram() {}
+
+	protected:
+		virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);
+		virtual void applyShader(Int cMask[4]);
+		virtual Bool alphaTest(Int cMask[4]);
+		virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
+
+	private:
+		// Temporary registers
+		RegisterArray<4096> r;
+
+		// Color outputs
+		Vector4f c[RENDERTARGETS];
+		RegisterArray<RENDERTARGETS, true> oC;
+
+		// Shader variables
+		Vector4f vPos;
+		Vector4f vFace;
+
+		// DX9 specific variables
+		Vector4f p0;
+		Array<Int, 4> aL;
+		Array<Int, 4> increment;
+		Array<Int, 4> iteration;
+
+		Int loopDepth;    // FIXME: Add support for switch
+		Int stackIndex;   // FIXME: Inc/decrement callStack
+		Array<UInt, 16> callStack;
+
+		// Per pixel based on conditions reached
+		Int enableIndex;
+		Array<Int4, 1 + 24> enableStack;
+		Int4 enableBreak;
+		Int4 enableContinue;
+		Int4 enableLeave;
+
+		void sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method);
+		void sampleTexture(Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method);
+
+		// Raster operations
+		void clampColor(Vector4f oC[RENDERTARGETS]);
+
+		Int4 enableMask(const Shader::Instruction *instruction);
+
+		Vector4f fetchRegister(const Src &src, unsigned int offset = 0);
+		Vector4f readConstant(const Src &src, unsigned int offset = 0);
+		RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
+		RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset);
+		Int relativeAddress(const Shader::Parameter &var, int bufferIndex = -1);
+
+		Float4 linearToSRGB(const Float4 &x);
+
+		// Instructions
+		typedef Shader::Control Control;
+
+		void M3X2(Vector4f &dst, Vector4f &src0, const Src &src1);
+		void M3X3(Vector4f &dst, Vector4f &src0, const Src &src1);
+		void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1);
+		void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);
+		void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);
+		void TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
+		void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project);
+		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project);
+		void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);
+		void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
+		void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, bool project, bool bias);
+		void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias);
+		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
+		void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
+		void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
+		void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);
+		void DISCARD(Int cMask[4], const Shader::Instruction *instruction);
+		void DFDX(Vector4f &dst, Vector4f &src);
+		void DFDY(Vector4f &dst, Vector4f &src);
+		void FWIDTH(Vector4f &dst, Vector4f &src);
+		void BREAK();
+		void BREAKC(Vector4f &src0, Vector4f &src1, Control);
+		void BREAKP(const Src &predicateRegister);
+		void BREAK(Int4 &condition);
+		void CONTINUE();
+		void TEST();
+		void CALL(int labelIndex, int callSiteIndex);
+		void CALLNZ(int labelIndex, int callSiteIndex, const Src &src);
+		void CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister);
+		void CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister);
+		void ELSE();
+		void ENDIF();
+		void ENDLOOP();
+		void ENDREP();
+		void ENDWHILE();
+		void IF(const Src &src);
+		void IFb(const Src &boolRegister);
+		void IFp(const Src &predicateRegister);
+		void IFC(Vector4f &src0, Vector4f &src1, Control);
+		void IF(Int4 &condition);
+		void LABEL(int labelIndex);
+		void LOOP(const Src &integerRegister);
+		void REP(const Src &integerRegister);
+		void WHILE(const Src &temporaryRegister);
+		void RET();
+		void LEAVE();
+
+		int ifDepth;
+		int loopRepDepth;
+		int breakDepth;
+		int currentLabel;
+		bool whileTest;
+
+		// FIXME: Get rid of llvm::
+		llvm::BasicBlock *ifFalseBlock[24 + 24];
+		llvm::BasicBlock *loopRepTestBlock[4];
+		llvm::BasicBlock *loopRepEndBlock[4];
+		llvm::BasicBlock *labelBlock[2048];
+		std::vector<llvm::BasicBlock*> callRetBlock[2048];
+		llvm::BasicBlock *returnBlock;
+		bool isConditionalIf[24 + 24];
+	};
+}
+
+#endif
diff --git a/src/Shader/PixelRoutine.cpp b/src/Shader/PixelRoutine.cpp
index a1a752c..b28a428 100644
--- a/src/Shader/PixelRoutine.cpp
+++ b/src/Shader/PixelRoutine.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "PixelRoutine.hpp"
 
diff --git a/src/Shader/PixelRoutine.hpp b/src/Shader/PixelRoutine.hpp
index 2cce393..89fe7ff 100644
--- a/src/Shader/PixelRoutine.hpp
+++ b/src/Shader/PixelRoutine.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_PixelRoutine_hpp
 #define sw_PixelRoutine_hpp
diff --git a/src/Shader/PixelShader.cpp b/src/Shader/PixelShader.cpp
index 2147fea..8cdfaff 100644
--- a/src/Shader/PixelShader.cpp
+++ b/src/Shader/PixelShader.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "PixelShader.hpp"
 
diff --git a/src/Shader/PixelShader.hpp b/src/Shader/PixelShader.hpp
index f57794e..cb568a8 100644
--- a/src/Shader/PixelShader.hpp
+++ b/src/Shader/PixelShader.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_PixelShader_hpp
 #define sw_PixelShader_hpp
diff --git a/src/Shader/SamplerCore.cpp b/src/Shader/SamplerCore.cpp
index 956f526..a4de5f5 100644
--- a/src/Shader/SamplerCore.cpp
+++ b/src/Shader/SamplerCore.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "SamplerCore.hpp"
 
diff --git a/src/Shader/SamplerCore.hpp b/src/Shader/SamplerCore.hpp
index 91e40db..8b915ee 100644
--- a/src/Shader/SamplerCore.hpp
+++ b/src/Shader/SamplerCore.hpp
@@ -1,85 +1,88 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_SamplerCore_hpp

-#define sw_SamplerCore_hpp

-

-#include "PixelRoutine.hpp"

-#include "Reactor/Nucleus.hpp"

-

-namespace sw

-{

-	enum SamplerMethod

-	{

-		Implicit,

-		Bias,

-		Lod,

-		Grad,

-	};

-

-	class SamplerCore

-	{

-	public:

-		SamplerCore(Pointer<Byte> &r, const Sampler::State &state);

-

-		void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method = Implicit);

-		void sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method = Implicit);

-

-	private:

-		void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method, bool fixed12);

-

-		void border(Short4 &mask, Float4 &coordinates);

-		void border(Int4 &mask, Float4 &coordinates);

-		Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);

-		void sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method);

-		void sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method);

-		void sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);

-		void sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);

-		void sample3D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, bool secondLOD);

-		void sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method);

-		void sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method);

-		void sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);

-		void sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);

-		void sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, bool secondLOD);

-		void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);

-		void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &x, Float4 &y, Float4 &z, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);

-		void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);

-		void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &lodX, Float4 &lodY, Float4 &lodZ, Float4 &x, Float4 &y, Float4 &z);

-		void computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Pointer<Byte> &mipmap);

-		void sampleTexel(Vector4s &c, Short4 &u, Short4 &v, Short4 &s, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);

-		void sampleTexel(Vector4f &c, Short4 &u, Short4 &v, Short4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);

-		void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);

-		Short4 address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap);

-

-		void convertFixed12(Short4 &ci, Float4 &cf);

-		void convertFixed12(Vector4s &cs, Vector4f &cf);

-		void convertSigned12(Float4 &cf, Short4 &ci);

-		void convertSigned15(Float4 &cf, Short4 &ci);

-		void convertUnsigned16(Float4 &cf, Short4 &ci);

-		void sRGBtoLinear16_8_12(Short4 &c);

-		void sRGBtoLinear16_6_12(Short4 &c);

-		void sRGBtoLinear16_5_12(Short4 &c);

-

-		bool hasFloatTexture() const;

-		bool hasUnsignedTextureComponent(int component) const;

-		int textureComponentCount() const;

-		bool has16bitTextureFormat() const;

-		bool has8bitTextureComponents() const;

-		bool has16bitTextureComponents() const;

-		bool hasYuvFormat() const;

-		bool isRGBComponent(int component) const;

-

-		Pointer<Byte> &constants;

-		const Sampler::State &state;

-	};

-}

-

-#endif   // sw_SamplerCore_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_SamplerCore_hpp
+#define sw_SamplerCore_hpp
+
+#include "PixelRoutine.hpp"
+#include "Reactor/Nucleus.hpp"
+
+namespace sw
+{
+	enum SamplerMethod
+	{
+		Implicit,
+		Bias,
+		Lod,
+		Grad,
+	};
+
+	class SamplerCore
+	{
+	public:
+		SamplerCore(Pointer<Byte> &r, const Sampler::State &state);
+
+		void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method = Implicit);
+		void sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method = Implicit);
+
+	private:
+		void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method, bool fixed12);
+
+		void border(Short4 &mask, Float4 &coordinates);
+		void border(Int4 &mask, Float4 &coordinates);
+		Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
+		void sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method);
+		void sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method);
+		void sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);
+		void sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);
+		void sample3D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, bool secondLOD);
+		void sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method);
+		void sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method);
+		void sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);
+		void sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD);
+		void sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, bool secondLOD);
+		void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);
+		void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &x, Float4 &y, Float4 &z, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);
+		void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);
+		void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &lodX, Float4 &lodY, Float4 &lodZ, Float4 &x, Float4 &y, Float4 &z);
+		void computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Pointer<Byte> &mipmap);
+		void sampleTexel(Vector4s &c, Short4 &u, Short4 &v, Short4 &s, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);
+		void sampleTexel(Vector4f &c, Short4 &u, Short4 &v, Short4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);
+		void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);
+		Short4 address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap);
+
+		void convertFixed12(Short4 &ci, Float4 &cf);
+		void convertFixed12(Vector4s &cs, Vector4f &cf);
+		void convertSigned12(Float4 &cf, Short4 &ci);
+		void convertSigned15(Float4 &cf, Short4 &ci);
+		void convertUnsigned16(Float4 &cf, Short4 &ci);
+		void sRGBtoLinear16_8_12(Short4 &c);
+		void sRGBtoLinear16_6_12(Short4 &c);
+		void sRGBtoLinear16_5_12(Short4 &c);
+
+		bool hasFloatTexture() const;
+		bool hasUnsignedTextureComponent(int component) const;
+		int textureComponentCount() const;
+		bool has16bitTextureFormat() const;
+		bool has8bitTextureComponents() const;
+		bool has16bitTextureComponents() const;
+		bool hasYuvFormat() const;
+		bool isRGBComponent(int component) const;
+
+		Pointer<Byte> &constants;
+		const Sampler::State &state;
+	};
+}
+
+#endif   // sw_SamplerCore_hpp
diff --git a/src/Shader/SetupRoutine.cpp b/src/Shader/SetupRoutine.cpp
index 1e2e897..36753bd 100644
--- a/src/Shader/SetupRoutine.cpp
+++ b/src/Shader/SetupRoutine.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "SetupRoutine.hpp"
 
@@ -163,7 +166,7 @@
 			// Vertical range
 			Int yMin = Y[0];
 			Int yMax = Y[0];
-			
+		
 			Int i = 1;
 			
 			Do
diff --git a/src/Shader/SetupRoutine.hpp b/src/Shader/SetupRoutine.hpp
index ea89a04b..9534b63 100644
--- a/src/Shader/SetupRoutine.hpp
+++ b/src/Shader/SetupRoutine.hpp
@@ -1,44 +1,47 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_SetupRoutine_hpp

-#define sw_SetupRoutine_hpp

-

-#include "SetupProcessor.hpp"

-#include "Reactor/Nucleus.hpp"

-

-namespace sw

-{

-	class Context;

-

-	class SetupRoutine

-	{

-	public:

-		SetupRoutine(const SetupProcessor::State &state);

-

-		virtual ~SetupRoutine();

-

-		void generate();

-		Routine *getRoutine();

-

-	private:

-		void setupGradient(Pointer<Byte> &primitive, Pointer<Byte> &triangle, Float4 &w012, Float4 (&m)[3], Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2, int attribute, int planeEquation, bool flatShading, bool sprite, bool perspective, bool wrap, int component);

-		void edge(Pointer<Byte> &primitive, Pointer<Byte> &data, const Int &X1, const Int &Y1, const Int &X2, const Int &Y2, Int &q);

-		void conditionalRotate1(Bool condition, Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2);

-		void conditionalRotate2(Bool condition, Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2);

-

-		const SetupProcessor::State &state;

-

-		Routine *routine;

-	};

-}

-

-#endif   // sw_SetupRoutine_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_SetupRoutine_hpp
+#define sw_SetupRoutine_hpp
+
+#include "SetupProcessor.hpp"
+#include "Reactor/Nucleus.hpp"
+
+namespace sw
+{
+	class Context;
+
+	class SetupRoutine
+	{
+	public:
+		SetupRoutine(const SetupProcessor::State &state);
+
+		virtual ~SetupRoutine();
+
+		void generate();
+		Routine *getRoutine();
+
+	private:
+		void setupGradient(Pointer<Byte> &primitive, Pointer<Byte> &triangle, Float4 &w012, Float4 (&m)[3], Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2, int attribute, int planeEquation, bool flatShading, bool sprite, bool perspective, bool wrap, int component);
+		void edge(Pointer<Byte> &primitive, Pointer<Byte> &data, const Int &X1, const Int &Y1, const Int &X2, const Int &Y2, Int &q);
+		void conditionalRotate1(Bool condition, Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2);
+		void conditionalRotate2(Bool condition, Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2);
+
+		const SetupProcessor::State &state;
+
+		Routine *routine;
+	};
+}
+
+#endif   // sw_SetupRoutine_hpp
diff --git a/src/Shader/Shader.cpp b/src/Shader/Shader.cpp
index 7c3f9bb..8e92d2e 100644
--- a/src/Shader/Shader.cpp
+++ b/src/Shader/Shader.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "Shader.hpp"
 
@@ -61,7 +64,7 @@
 		}
 	}
 
-	Shader::Opcode Shader::OPCODE_NRM(int i)	
+	Shader::Opcode Shader::OPCODE_NRM(int i)
 	{
 		switch(i)
 		{
diff --git a/src/Shader/Shader.hpp b/src/Shader/Shader.hpp
index a5785c8..d26a5b7 100644
--- a/src/Shader/Shader.hpp
+++ b/src/Shader/Shader.hpp
@@ -1,644 +1,647 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_Shader_hpp

-#define sw_Shader_hpp

-

-#include "Common/Types.hpp"

-

-#include <string>

-#include <vector>

-

-namespace sw

-{

-	class Shader

-	{

-	public:

-		enum ShaderType

-		{

-			SHADER_PIXEL = 0xFFFF,

-			SHADER_VERTEX = 0xFFFE,

-			SHADER_GEOMETRY = 0xFFFD

-		};

-

-		enum Opcode

-		{

-			// Matches order in d3d9types.h

-			OPCODE_NOP = 0,

-			OPCODE_MOV,

-			OPCODE_ADD,

-			OPCODE_SUB,

-			OPCODE_MAD,

-			OPCODE_MUL,

-			OPCODE_RCPX,

-			OPCODE_RSQX,

-			OPCODE_DP3,

-			OPCODE_DP4,

-			OPCODE_MIN,

-			OPCODE_MAX,

-			OPCODE_SLT,

-			OPCODE_SGE,

-			OPCODE_EXP2X,   // D3DSIO_EXP

-			OPCODE_LOG2X,   // D3DSIO_LOG

-			OPCODE_LIT,

-			OPCODE_ATT,   // D3DSIO_DST

-			OPCODE_LRP,

-			OPCODE_FRC,

-			OPCODE_M4X4,

-			OPCODE_M4X3,

-			OPCODE_M3X4,

-			OPCODE_M3X3,

-			OPCODE_M3X2,

-			OPCODE_CALL,

-			OPCODE_CALLNZ,

-			OPCODE_LOOP,

-			OPCODE_RET,

-			OPCODE_ENDLOOP,

-			OPCODE_LABEL,

-			OPCODE_DCL,

-			OPCODE_POWX,

-			OPCODE_CRS,

-			OPCODE_SGN,

-			OPCODE_ABS,

-			OPCODE_NRM3,   // D3DSIO_NRM

-			OPCODE_SINCOS,

-			OPCODE_REP,

-			OPCODE_ENDREP,

-			OPCODE_IF,

-			OPCODE_IFC,

-			OPCODE_ELSE,

-			OPCODE_ENDIF,

-			OPCODE_BREAK,

-			OPCODE_BREAKC,

-			OPCODE_MOVA,

-			OPCODE_DEFB,

-			OPCODE_DEFI,

-

-			OPCODE_TEXCOORD = 64,

-			OPCODE_TEXKILL,

-			OPCODE_TEX,

-			OPCODE_TEXBEM,

-			OPCODE_TEXBEML,

-			OPCODE_TEXREG2AR,

-			OPCODE_TEXREG2GB,

-			OPCODE_TEXM3X2PAD,

-			OPCODE_TEXM3X2TEX,

-			OPCODE_TEXM3X3PAD,

-			OPCODE_TEXM3X3TEX,

-			OPCODE_RESERVED0,

-			OPCODE_TEXM3X3SPEC,

-			OPCODE_TEXM3X3VSPEC,

-			OPCODE_EXPP,

-			OPCODE_LOGP,

-			OPCODE_CND,

-			OPCODE_DEF,

-			OPCODE_TEXREG2RGB,

-			OPCODE_TEXDP3TEX,

-			OPCODE_TEXM3X2DEPTH,

-			OPCODE_TEXDP3,

-			OPCODE_TEXM3X3,

-			OPCODE_TEXDEPTH,

-			OPCODE_CMP0,   // D3DSIO_CMP

-			OPCODE_BEM,

-			OPCODE_DP2ADD,

-			OPCODE_DFDX,   // D3DSIO_DSX

-			OPCODE_DFDY,   // D3DSIO_DSY

-			OPCODE_TEXLDD,

-			OPCODE_CMP,   // D3DSIO_SETP

-			OPCODE_TEXLDL,

-			OPCODE_BREAKP,

-			OPCODE_TEXSIZE,

-

-			OPCODE_PHASE = 0xFFFD,

-			OPCODE_COMMENT = 0xFFFE,

-			OPCODE_END = 0xFFFF,

-

-			OPCODE_PS_1_0 = 0xFFFF0100,

-			OPCODE_PS_1_1 = 0xFFFF0101,

-			OPCODE_PS_1_2 = 0xFFFF0102,

-			OPCODE_PS_1_3 = 0xFFFF0103,

-			OPCODE_PS_1_4 = 0xFFFF0104,

-			OPCODE_PS_2_0 = 0xFFFF0200,

-			OPCODE_PS_2_x = 0xFFFF0201,

-			OPCODE_PS_3_0 = 0xFFFF0300,

-

-			OPCODE_VS_1_0 = 0xFFFE0100,

-			OPCODE_VS_1_1 = 0xFFFE0101,

-			OPCODE_VS_2_0 = 0xFFFE0200,

-			OPCODE_VS_2_x = 0xFFFE0201,

-			OPCODE_VS_2_sw = 0xFFFE02FF,

-			OPCODE_VS_3_0 = 0xFFFE0300,

-			OPCODE_VS_3_sw = 0xFFFE03FF,

-

-			OPCODE_NULL = 0x10000000,   // Dead instruction, to be eliminated

-			OPCODE_WHILE,

-			OPCODE_ENDWHILE,

-			OPCODE_COS,

-			OPCODE_SIN,

-			OPCODE_TAN,

-			OPCODE_ACOS,

-			OPCODE_ASIN,

-			OPCODE_ATAN,

-			OPCODE_ATAN2,

-			OPCODE_COSH,

-			OPCODE_SINH,

-			OPCODE_TANH,

-			OPCODE_ACOSH,

-			OPCODE_ASINH,

-			OPCODE_ATANH,

-			OPCODE_DP1,

-			OPCODE_DP2,

-			OPCODE_TRUNC,

-			OPCODE_FLOOR,

-			OPCODE_ROUND,

-			OPCODE_ROUNDEVEN,

-			OPCODE_CEIL,

-			OPCODE_SQRT,

-			OPCODE_RSQ,

-			OPCODE_LEN2,

-			OPCODE_LEN3,

-			OPCODE_LEN4,

-			OPCODE_DIST1,

-			OPCODE_DIST2,

-			OPCODE_DIST3,

-			OPCODE_DIST4,

-			OPCODE_NRM2,

-			OPCODE_NRM4,

-			OPCODE_DIV,

-			OPCODE_MOD,

-			OPCODE_EXP2,

-			OPCODE_LOG2,

-			OPCODE_EXP,

-			OPCODE_LOG,

-			OPCODE_POW,

-			OPCODE_F2B,   // Float to bool

-			OPCODE_B2F,   // Bool to float

-			OPCODE_F2I,   // Float to int

-			OPCODE_I2F,   // Int to float

-			OPCODE_F2U,   // Float to uint

-			OPCODE_U2F,   // Uint to float

-			OPCODE_I2B,   // Int to bool

-			OPCODE_B2I,   // Bool to int

-			OPCODE_DET2,

-			OPCODE_DET3,

-			OPCODE_DET4,

-			OPCODE_ALL,

-			OPCODE_ANY,

-			OPCODE_NEG,

-			OPCODE_NOT,

-			OPCODE_OR,

-			OPCODE_XOR,

-			OPCODE_AND,

-			OPCODE_EQ,

-			OPCODE_NE,

-			OPCODE_STEP,

-			OPCODE_SMOOTH,

-			OPCODE_ISNAN,

-			OPCODE_ISINF,

-			OPCODE_TEXOFFSET,

-			OPCODE_TEXLDLOFFSET,

-			OPCODE_TEXELFETCH,

-			OPCODE_TEXELFETCHOFFSET,

-			OPCODE_TEXGRAD,

-			OPCODE_TEXGRADOFFSET,

-			OPCODE_FLOATBITSTOINT,

-			OPCODE_FLOATBITSTOUINT,

-			OPCODE_INTBITSTOFLOAT,

-			OPCODE_UINTBITSTOFLOAT,

-			OPCODE_PACKSNORM2x16,

-			OPCODE_PACKUNORM2x16,

-			OPCODE_PACKHALF2x16,

-			OPCODE_UNPACKSNORM2x16,

-			OPCODE_UNPACKUNORM2x16,

-			OPCODE_UNPACKHALF2x16,

-			OPCODE_FORWARD1,

-			OPCODE_FORWARD2,

-			OPCODE_FORWARD3,

-			OPCODE_FORWARD4,

-			OPCODE_REFLECT1,

-			OPCODE_REFLECT2,

-			OPCODE_REFLECT3,

-			OPCODE_REFLECT4,

-			OPCODE_REFRACT1,

-			OPCODE_REFRACT2,

-			OPCODE_REFRACT3,

-			OPCODE_REFRACT4,

-			OPCODE_ICMP,

-			OPCODE_UCMP,

-			OPCODE_SELECT,

-			OPCODE_EXTRACT,

-			OPCODE_INSERT,

-			OPCODE_DISCARD,

-			OPCODE_FWIDTH,

-			OPCODE_LEAVE,   // Return before the end of the function

-			OPCODE_CONTINUE,

-			OPCODE_TEST,   // Marks the end of the code that can be skipped by 'continue'

-

-			// Integer opcodes

-			OPCODE_INEG,

-			OPCODE_IABS,

-			OPCODE_ISGN,

-			OPCODE_IADD,

-			OPCODE_ISUB,

-			OPCODE_IMUL,

-			OPCODE_IDIV,

-			OPCODE_IMAD,

-			OPCODE_IMOD,

-			OPCODE_SHL,

-			OPCODE_ISHR,

-			OPCODE_IMIN,

-			OPCODE_IMAX,

-

-			// Unsigned integer opcodes

-			OPCODE_UDIV,

-			OPCODE_UMOD,

-			OPCODE_USHR,

-			OPCODE_UMIN,

-			OPCODE_UMAX,

-		};

-

-		static Opcode OPCODE_DP(int);

-		static Opcode OPCODE_LEN(int);

-		static Opcode OPCODE_DIST(int);

-		static Opcode OPCODE_NRM(int);

-		static Opcode OPCODE_FORWARD(int);

-		static Opcode OPCODE_REFLECT(int);

-		static Opcode OPCODE_REFRACT(int);

-

-		enum Control

-		{

-			CONTROL_RESERVED0,

-			CONTROL_GT,

-			CONTROL_EQ,

-			CONTROL_GE,

-			CONTROL_LT,

-			CONTROL_NE,

-			CONTROL_LE,

-			CONTROL_RESERVED1

-		};

-

-		enum SamplerType

-		{

-			SAMPLER_UNKNOWN,

-			SAMPLER_1D,

-			SAMPLER_2D,

-			SAMPLER_CUBE,

-			SAMPLER_VOLUME

-		};

-

-		enum Usage   // For vertex input/output declarations

-		{

-			USAGE_POSITION = 0,

-			USAGE_BLENDWEIGHT = 1,

-			USAGE_BLENDINDICES = 2,

-			USAGE_NORMAL = 3,

-			USAGE_PSIZE = 4,

-			USAGE_TEXCOORD = 5,

-			USAGE_TANGENT = 6,

-			USAGE_BINORMAL = 7,

-			USAGE_TESSFACTOR = 8,

-			USAGE_POSITIONT = 9,

-			USAGE_COLOR = 10,

-			USAGE_FOG = 11,

-			USAGE_DEPTH = 12,

-			USAGE_SAMPLE = 13

-		};

-

-		enum ParameterType

-		{

-			PARAMETER_TEMP = 0,

-			PARAMETER_INPUT = 1,

-			PARAMETER_CONST = 2,

-			PARAMETER_TEXTURE = 3,

-			PARAMETER_ADDR = 3,

-			PARAMETER_RASTOUT = 4,

-			PARAMETER_ATTROUT = 5,

-			PARAMETER_TEXCRDOUT = 6,

-			PARAMETER_OUTPUT = 6,

-			PARAMETER_CONSTINT = 7,

-			PARAMETER_COLOROUT = 8,

-			PARAMETER_DEPTHOUT = 9,

-			PARAMETER_SAMPLER = 10,

-			PARAMETER_CONST2 = 11,

-			PARAMETER_CONST3 = 12,

-			PARAMETER_CONST4 = 13,

-			PARAMETER_CONSTBOOL = 14,

-			PARAMETER_LOOP = 15,

-			PARAMETER_TEMPFLOAT16 = 16,

-			PARAMETER_MISCTYPE = 17,

-			PARAMETER_LABEL = 18,

-			PARAMETER_PREDICATE = 19,

-

-		//	PARAMETER_FLOAT1LITERAL,

-		//	PARAMETER_FLOAT2LITERAL,

-		//	PARAMETER_FLOAT3LITERAL,

-			PARAMETER_FLOAT4LITERAL,

-			PARAMETER_BOOL1LITERAL,

-		//	PARAMETER_BOOL2LITERAL,

-		//	PARAMETER_BOOL3LITERAL,

-		//	PARAMETER_BOOL4LITERAL,

-		//	PARAMETER_INT1LITERAL,

-		//	PARAMETER_INT2LITERAL,

-		//	PARAMETER_INT3LITERAL,

-			PARAMETER_INT4LITERAL,

-

-			PARAMETER_VOID

-		};

-

-		enum Modifier

-		{

-			MODIFIER_NONE,

-			MODIFIER_NEGATE,

-			MODIFIER_BIAS,

-			MODIFIER_BIAS_NEGATE,

-			MODIFIER_SIGN,

-			MODIFIER_SIGN_NEGATE,

-			MODIFIER_COMPLEMENT,

-			MODIFIER_X2,

-			MODIFIER_X2_NEGATE,

-			MODIFIER_DZ,

-			MODIFIER_DW,

-			MODIFIER_ABS,

-			MODIFIER_ABS_NEGATE,

-			MODIFIER_NOT

-		};

-

-		enum Analysis

-		{

-			// Flags indicating whether an instruction is affected by an execution enable mask

-			ANALYSIS_BRANCH   = 0x00000001,

-			ANALYSIS_BREAK    = 0x00000002,

-			ANALYSIS_CONTINUE = 0x00000004,

-			ANALYSIS_LEAVE    = 0x00000008,

-		};

-

-		struct Parameter

-		{

-			union

-			{

-				struct

-				{

-					unsigned int index;   // For registers types

-

-					struct

-					{

-						ParameterType type : 8;

-						unsigned int index;

-						unsigned int swizzle : 8;

-						unsigned int scale;

-						bool deterministic;   // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)

-					} rel;

-				};

-

-				float value[4];       // For float constants

-				int integer[4];       // For integer constants

-				int boolean[4];       // For boolean constants

-

-				struct

-				{

-					unsigned int label;      // Label index

-					unsigned int callSite;   // Call index (per label)

-				};

-			};

-

-			Parameter() : index(0), type(PARAMETER_VOID)

-			{

-				rel.type = PARAMETER_VOID;

-				rel.index = 0;

-				rel.swizzle = 0;

-				rel.scale = 1;

-				rel.deterministic = false;

-			}

-

-			std::string string(ShaderType shaderType, unsigned short version) const;

-			std::string typeString(ShaderType shaderType, unsigned short version) const;

-			std::string relativeString() const;

-

-			ParameterType type : 8;

-		};

-

-		struct DestinationParameter : Parameter

-		{

-			union

-			{

-				unsigned char mask;

-

-				struct

-				{

-					bool x : 1;

-					bool y : 1;

-					bool z : 1;

-					bool w : 1;

-				};

-			};

-

-			DestinationParameter() : mask(0xF), integer(false), saturate(false), partialPrecision(false), centroid(false), shift(0)

-			{

-			}

-

-			std::string modifierString() const;

-			std::string shiftString() const;

-			std::string maskString() const;

-

-			bool integer          : 1;

-			bool saturate         : 1;

-			bool partialPrecision : 1;

-			bool centroid         : 1;

-			signed char shift     : 4;

-		};

-

-		struct SourceParameter : Parameter

-		{

-			SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE), bufferIndex(-1)

-			{

-			}

-

-			std::string swizzleString() const;

-			std::string preModifierString() const;

-			std::string postModifierString() const;

-

-			unsigned int swizzle : 8;

-			Modifier modifier : 8;

-			int bufferIndex : 8;

-		};

-

-		struct Instruction

-		{

-			explicit Instruction(Opcode opcode);

-			Instruction(const unsigned long *token, int size, unsigned char majorVersion);

-

-			virtual ~Instruction();

-

-			void parseOperationToken(unsigned long token, unsigned char majorVersion);

-			void parseDeclarationToken(unsigned long token);

-			void parseDestinationToken(const unsigned long *token, unsigned char majorVersion);

-			void parseSourceToken(int i, const unsigned long *token, unsigned char majorVersion);

-

-			std::string string(ShaderType shaderType, unsigned short version) const;

-			static std::string swizzleString(ParameterType type, unsigned char swizzle);

-			std::string operationString(unsigned short version) const;

-			std::string controlString() const;

-

-			bool isBranch() const;

-			bool isCall() const;

-			bool isBreak() const;

-			bool isLoop() const;

-			bool isEndLoop() const;

-

-			bool isPredicated() const;

-

-			Opcode opcode;

-

-			union

-			{

-				Control control;

-

-				struct

-				{

-					unsigned char project : 1;

-					unsigned char bias : 1;

-				};

-			};

-

-			bool predicate;

-			bool predicateNot;   // Negative predicate

-			unsigned char predicateSwizzle;

-

-			bool coissue;

-			SamplerType samplerType;

-			Usage usage;

-			unsigned char usageIndex;

-

-			DestinationParameter dst;

-			SourceParameter src[5];

-

-			union

-			{

-				unsigned int analysis;

-

-				struct

-				{

-					// Keep in sync with Shader::Analysis flags

-					unsigned int analysisBranch : 1;

-					unsigned int analysisBreak : 1;

-					unsigned int analysisContinue : 1;

-					unsigned int analysisLeave : 1;

-				};

-			};

-		};

-

-		Shader();

-

-		virtual ~Shader();

-

-		int getSerialID() const;

-		size_t getLength() const;

-		ShaderType getShaderType() const;

-		unsigned short getVersion() const;

-

-		void append(Instruction *instruction);

-		void declareSampler(int i);

-

-		const Instruction *getInstruction(unsigned int i) const;

-		int size(unsigned long opcode) const;

-		static int size(unsigned long opcode, unsigned short version);

-

-		void print(const char *fileName, ...) const;

-		void printInstruction(int index, const char *fileName) const;

-

-		static bool maskContainsComponent(int mask, int component);

-		static bool swizzleContainsComponent(int swizzle, int component);

-		static bool swizzleContainsComponentMasked(int swizzle, int component, int mask);

-

-		bool containsDynamicBranching() const;

-		bool containsBreakInstruction() const;

-		bool containsContinueInstruction() const;

-		bool containsLeaveInstruction() const;

-		bool containsDefineInstruction() const;

-		bool usesSampler(int i) const;

-

-		struct Semantic

-		{

-			Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF) : usage(usage), index(index), centroid(false)

-			{

-			}

-

-			bool operator==(const Semantic &semantic) const

-			{

-				return usage == semantic.usage && index == semantic.index;

-			}

-

-			bool active() const

-			{

-				return usage != 0xFF;

-			}

-

-			unsigned char usage;

-			unsigned char index;

-			bool centroid;

-		};

-

-		void optimize();

-		virtual void analyze() = 0;

-

-		// FIXME: Private

-		unsigned int dirtyConstantsF;

-		unsigned int dirtyConstantsI;

-		unsigned int dirtyConstantsB;

-

-		bool dynamicallyIndexedTemporaries;

-		bool dynamicallyIndexedInput;

-		bool dynamicallyIndexedOutput;

-

-	protected:

-		void parse(const unsigned long *token);

-

-		void optimizeLeave();

-		void optimizeCall();

-		void removeNull();

-

-		void analyzeDirtyConstants();

-		void analyzeDynamicBranching();

-		void analyzeSamplers();

-		void analyzeCallSites();

-		void analyzeDynamicIndexing();

-		void markFunctionAnalysis(unsigned int functionLabel, Analysis flag);

-

-		ShaderType shaderType;

-

-		union

-		{

-			unsigned short version;

-

-			struct

-			{

-				unsigned char minorVersion;

-				unsigned char majorVersion;

-			};

-		};

-

-		std::vector<Instruction*> instruction;

-

-		unsigned short usedSamplers;   // Bit flags

-

-	private:

-		const int serialID;

-		static volatile int serialCounter;

-

-		bool dynamicBranching;

-		bool containsBreak;

-		bool containsContinue;

-		bool containsLeave;

-		bool containsDefine;

-	};

-}

-

-#endif   // sw_Shader_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Shader_hpp
+#define sw_Shader_hpp
+
+#include "Common/Types.hpp"
+
+#include <string>
+#include <vector>
+
+namespace sw
+{
+	class Shader
+	{
+	public:
+		enum ShaderType
+		{
+			SHADER_PIXEL = 0xFFFF,
+			SHADER_VERTEX = 0xFFFE,
+			SHADER_GEOMETRY = 0xFFFD
+		};
+
+		enum Opcode
+		{
+			// Matches order in d3d9types.h
+			OPCODE_NOP = 0,
+			OPCODE_MOV,
+			OPCODE_ADD,
+			OPCODE_SUB,
+			OPCODE_MAD,
+			OPCODE_MUL,
+			OPCODE_RCPX,
+			OPCODE_RSQX,
+			OPCODE_DP3,
+			OPCODE_DP4,
+			OPCODE_MIN,
+			OPCODE_MAX,
+			OPCODE_SLT,
+			OPCODE_SGE,
+			OPCODE_EXP2X,   // D3DSIO_EXP
+			OPCODE_LOG2X,   // D3DSIO_LOG
+			OPCODE_LIT,
+			OPCODE_ATT,   // D3DSIO_DST
+			OPCODE_LRP,
+			OPCODE_FRC,
+			OPCODE_M4X4,
+			OPCODE_M4X3,
+			OPCODE_M3X4,
+			OPCODE_M3X3,
+			OPCODE_M3X2,
+			OPCODE_CALL,
+			OPCODE_CALLNZ,
+			OPCODE_LOOP,
+			OPCODE_RET,
+			OPCODE_ENDLOOP,
+			OPCODE_LABEL,
+			OPCODE_DCL,
+			OPCODE_POWX,
+			OPCODE_CRS,
+			OPCODE_SGN,
+			OPCODE_ABS,
+			OPCODE_NRM3,   // D3DSIO_NRM
+			OPCODE_SINCOS,
+			OPCODE_REP,
+			OPCODE_ENDREP,
+			OPCODE_IF,
+			OPCODE_IFC,
+			OPCODE_ELSE,
+			OPCODE_ENDIF,
+			OPCODE_BREAK,
+			OPCODE_BREAKC,
+			OPCODE_MOVA,
+			OPCODE_DEFB,
+			OPCODE_DEFI,
+
+			OPCODE_TEXCOORD = 64,
+			OPCODE_TEXKILL,
+			OPCODE_TEX,
+			OPCODE_TEXBEM,
+			OPCODE_TEXBEML,
+			OPCODE_TEXREG2AR,
+			OPCODE_TEXREG2GB,
+			OPCODE_TEXM3X2PAD,
+			OPCODE_TEXM3X2TEX,
+			OPCODE_TEXM3X3PAD,
+			OPCODE_TEXM3X3TEX,
+			OPCODE_RESERVED0,
+			OPCODE_TEXM3X3SPEC,
+			OPCODE_TEXM3X3VSPEC,
+			OPCODE_EXPP,
+			OPCODE_LOGP,
+			OPCODE_CND,
+			OPCODE_DEF,
+			OPCODE_TEXREG2RGB,
+			OPCODE_TEXDP3TEX,
+			OPCODE_TEXM3X2DEPTH,
+			OPCODE_TEXDP3,
+			OPCODE_TEXM3X3,
+			OPCODE_TEXDEPTH,
+			OPCODE_CMP0,   // D3DSIO_CMP
+			OPCODE_BEM,
+			OPCODE_DP2ADD,
+			OPCODE_DFDX,   // D3DSIO_DSX
+			OPCODE_DFDY,   // D3DSIO_DSY
+			OPCODE_TEXLDD,
+			OPCODE_CMP,   // D3DSIO_SETP
+			OPCODE_TEXLDL,
+			OPCODE_BREAKP,
+			OPCODE_TEXSIZE,
+
+			OPCODE_PHASE = 0xFFFD,
+			OPCODE_COMMENT = 0xFFFE,
+			OPCODE_END = 0xFFFF,
+
+			OPCODE_PS_1_0 = 0xFFFF0100,
+			OPCODE_PS_1_1 = 0xFFFF0101,
+			OPCODE_PS_1_2 = 0xFFFF0102,
+			OPCODE_PS_1_3 = 0xFFFF0103,
+			OPCODE_PS_1_4 = 0xFFFF0104,
+			OPCODE_PS_2_0 = 0xFFFF0200,
+			OPCODE_PS_2_x = 0xFFFF0201,
+			OPCODE_PS_3_0 = 0xFFFF0300,
+
+			OPCODE_VS_1_0 = 0xFFFE0100,
+			OPCODE_VS_1_1 = 0xFFFE0101,
+			OPCODE_VS_2_0 = 0xFFFE0200,
+			OPCODE_VS_2_x = 0xFFFE0201,
+			OPCODE_VS_2_sw = 0xFFFE02FF,
+			OPCODE_VS_3_0 = 0xFFFE0300,
+			OPCODE_VS_3_sw = 0xFFFE03FF,
+
+			OPCODE_NULL = 0x10000000,   // Dead instruction, to be eliminated
+			OPCODE_WHILE,
+			OPCODE_ENDWHILE,
+			OPCODE_COS,
+			OPCODE_SIN,
+			OPCODE_TAN,
+			OPCODE_ACOS,
+			OPCODE_ASIN,
+			OPCODE_ATAN,
+			OPCODE_ATAN2,
+			OPCODE_COSH,
+			OPCODE_SINH,
+			OPCODE_TANH,
+			OPCODE_ACOSH,
+			OPCODE_ASINH,
+			OPCODE_ATANH,
+			OPCODE_DP1,
+			OPCODE_DP2,
+			OPCODE_TRUNC,
+			OPCODE_FLOOR,
+			OPCODE_ROUND,
+			OPCODE_ROUNDEVEN,
+			OPCODE_CEIL,
+			OPCODE_SQRT,
+			OPCODE_RSQ,
+			OPCODE_LEN2,
+			OPCODE_LEN3,
+			OPCODE_LEN4,
+			OPCODE_DIST1,
+			OPCODE_DIST2,
+			OPCODE_DIST3,
+			OPCODE_DIST4,
+			OPCODE_NRM2,
+			OPCODE_NRM4,
+			OPCODE_DIV,
+			OPCODE_MOD,
+			OPCODE_EXP2,
+			OPCODE_LOG2,
+			OPCODE_EXP,
+			OPCODE_LOG,
+			OPCODE_POW,
+			OPCODE_F2B,   // Float to bool
+			OPCODE_B2F,   // Bool to float
+			OPCODE_F2I,   // Float to int
+			OPCODE_I2F,   // Int to float
+			OPCODE_F2U,   // Float to uint
+			OPCODE_U2F,   // Uint to float
+			OPCODE_I2B,   // Int to bool
+			OPCODE_B2I,   // Bool to int
+			OPCODE_DET2,
+			OPCODE_DET3,
+			OPCODE_DET4,
+			OPCODE_ALL,
+			OPCODE_ANY,
+			OPCODE_NEG,
+			OPCODE_NOT,
+			OPCODE_OR,
+			OPCODE_XOR,
+			OPCODE_AND,
+			OPCODE_EQ,
+			OPCODE_NE,
+			OPCODE_STEP,
+			OPCODE_SMOOTH,
+			OPCODE_ISNAN,
+			OPCODE_ISINF,
+			OPCODE_TEXOFFSET,
+			OPCODE_TEXLDLOFFSET,
+			OPCODE_TEXELFETCH,
+			OPCODE_TEXELFETCHOFFSET,
+			OPCODE_TEXGRAD,
+			OPCODE_TEXGRADOFFSET,
+			OPCODE_FLOATBITSTOINT,
+			OPCODE_FLOATBITSTOUINT,
+			OPCODE_INTBITSTOFLOAT,
+			OPCODE_UINTBITSTOFLOAT,
+			OPCODE_PACKSNORM2x16,
+			OPCODE_PACKUNORM2x16,
+			OPCODE_PACKHALF2x16,
+			OPCODE_UNPACKSNORM2x16,
+			OPCODE_UNPACKUNORM2x16,
+			OPCODE_UNPACKHALF2x16,
+			OPCODE_FORWARD1,
+			OPCODE_FORWARD2,
+			OPCODE_FORWARD3,
+			OPCODE_FORWARD4,
+			OPCODE_REFLECT1,
+			OPCODE_REFLECT2,
+			OPCODE_REFLECT3,
+			OPCODE_REFLECT4,
+			OPCODE_REFRACT1,
+			OPCODE_REFRACT2,
+			OPCODE_REFRACT3,
+			OPCODE_REFRACT4,
+			OPCODE_ICMP,
+			OPCODE_UCMP,
+			OPCODE_SELECT,
+			OPCODE_EXTRACT,
+			OPCODE_INSERT,
+			OPCODE_DISCARD,
+			OPCODE_FWIDTH,
+			OPCODE_LEAVE,   // Return before the end of the function
+			OPCODE_CONTINUE,
+			OPCODE_TEST,   // Marks the end of the code that can be skipped by 'continue'
+
+			// Integer opcodes
+			OPCODE_INEG,
+			OPCODE_IABS,
+			OPCODE_ISGN,
+			OPCODE_IADD,
+			OPCODE_ISUB,
+			OPCODE_IMUL,
+			OPCODE_IDIV,
+			OPCODE_IMAD,
+			OPCODE_IMOD,
+			OPCODE_SHL,
+			OPCODE_ISHR,
+			OPCODE_IMIN,
+			OPCODE_IMAX,
+
+			// Unsigned integer opcodes
+			OPCODE_UDIV,
+			OPCODE_UMOD,
+			OPCODE_USHR,
+			OPCODE_UMIN,
+			OPCODE_UMAX,
+		};
+
+		static Opcode OPCODE_DP(int);
+		static Opcode OPCODE_LEN(int);
+		static Opcode OPCODE_DIST(int);
+		static Opcode OPCODE_NRM(int);
+		static Opcode OPCODE_FORWARD(int);
+		static Opcode OPCODE_REFLECT(int);
+		static Opcode OPCODE_REFRACT(int);
+
+		enum Control
+		{
+			CONTROL_RESERVED0,
+			CONTROL_GT,
+			CONTROL_EQ,
+			CONTROL_GE,
+			CONTROL_LT,
+			CONTROL_NE,
+			CONTROL_LE,
+			CONTROL_RESERVED1
+		};
+
+		enum SamplerType
+		{
+			SAMPLER_UNKNOWN,
+			SAMPLER_1D,
+			SAMPLER_2D,
+			SAMPLER_CUBE,
+			SAMPLER_VOLUME
+		};
+
+		enum Usage   // For vertex input/output declarations
+		{
+			USAGE_POSITION = 0,
+			USAGE_BLENDWEIGHT = 1,
+			USAGE_BLENDINDICES = 2,
+			USAGE_NORMAL = 3,
+			USAGE_PSIZE = 4,
+			USAGE_TEXCOORD = 5,
+			USAGE_TANGENT = 6,
+			USAGE_BINORMAL = 7,
+			USAGE_TESSFACTOR = 8,
+			USAGE_POSITIONT = 9,
+			USAGE_COLOR = 10,
+			USAGE_FOG = 11,
+			USAGE_DEPTH = 12,
+			USAGE_SAMPLE = 13
+		};
+
+		enum ParameterType
+		{
+			PARAMETER_TEMP = 0,
+			PARAMETER_INPUT = 1,
+			PARAMETER_CONST = 2,
+			PARAMETER_TEXTURE = 3,
+			PARAMETER_ADDR = 3,
+			PARAMETER_RASTOUT = 4,
+			PARAMETER_ATTROUT = 5,
+			PARAMETER_TEXCRDOUT = 6,
+			PARAMETER_OUTPUT = 6,
+			PARAMETER_CONSTINT = 7,
+			PARAMETER_COLOROUT = 8,
+			PARAMETER_DEPTHOUT = 9,
+			PARAMETER_SAMPLER = 10,
+			PARAMETER_CONST2 = 11,
+			PARAMETER_CONST3 = 12,
+			PARAMETER_CONST4 = 13,
+			PARAMETER_CONSTBOOL = 14,
+			PARAMETER_LOOP = 15,
+			PARAMETER_TEMPFLOAT16 = 16,
+			PARAMETER_MISCTYPE = 17,
+			PARAMETER_LABEL = 18,
+			PARAMETER_PREDICATE = 19,
+
+		//	PARAMETER_FLOAT1LITERAL,
+		//	PARAMETER_FLOAT2LITERAL,
+		//	PARAMETER_FLOAT3LITERAL,
+			PARAMETER_FLOAT4LITERAL,
+			PARAMETER_BOOL1LITERAL,
+		//	PARAMETER_BOOL2LITERAL,
+		//	PARAMETER_BOOL3LITERAL,
+		//	PARAMETER_BOOL4LITERAL,
+		//	PARAMETER_INT1LITERAL,
+		//	PARAMETER_INT2LITERAL,
+		//	PARAMETER_INT3LITERAL,
+			PARAMETER_INT4LITERAL,
+
+			PARAMETER_VOID
+		};
+
+		enum Modifier
+		{
+			MODIFIER_NONE,
+			MODIFIER_NEGATE,
+			MODIFIER_BIAS,
+			MODIFIER_BIAS_NEGATE,
+			MODIFIER_SIGN,
+			MODIFIER_SIGN_NEGATE,
+			MODIFIER_COMPLEMENT,
+			MODIFIER_X2,
+			MODIFIER_X2_NEGATE,
+			MODIFIER_DZ,
+			MODIFIER_DW,
+			MODIFIER_ABS,
+			MODIFIER_ABS_NEGATE,
+			MODIFIER_NOT
+		};
+
+		enum Analysis
+		{
+			// Flags indicating whether an instruction is affected by an execution enable mask
+			ANALYSIS_BRANCH   = 0x00000001,
+			ANALYSIS_BREAK    = 0x00000002,
+			ANALYSIS_CONTINUE = 0x00000004,
+			ANALYSIS_LEAVE    = 0x00000008,
+		};
+
+		struct Parameter
+		{
+			union
+			{
+				struct
+				{
+					unsigned int index;   // For registers types
+
+					struct
+					{
+						ParameterType type : 8;
+						unsigned int index;
+						unsigned int swizzle : 8;
+						unsigned int scale;
+						bool deterministic;   // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
+					} rel;
+				};
+
+				float value[4];       // For float constants
+				int integer[4];       // For integer constants
+				int boolean[4];       // For boolean constants
+
+				struct
+				{
+					unsigned int label;      // Label index
+					unsigned int callSite;   // Call index (per label)
+				};
+			};
+
+			Parameter() : index(0), type(PARAMETER_VOID)
+			{
+				rel.type = PARAMETER_VOID;
+				rel.index = 0;
+				rel.swizzle = 0;
+				rel.scale = 1;
+				rel.deterministic = false;
+			}
+
+			std::string string(ShaderType shaderType, unsigned short version) const;
+			std::string typeString(ShaderType shaderType, unsigned short version) const;
+			std::string relativeString() const;
+
+			ParameterType type : 8;
+		};
+
+		struct DestinationParameter : Parameter
+		{
+			union
+			{
+				unsigned char mask;
+
+				struct
+				{
+					bool x : 1;
+					bool y : 1;
+					bool z : 1;
+					bool w : 1;
+				};
+			};
+
+			DestinationParameter() : mask(0xF), integer(false), saturate(false), partialPrecision(false), centroid(false), shift(0)
+			{
+			}
+
+			std::string modifierString() const;
+			std::string shiftString() const;
+			std::string maskString() const;
+
+			bool integer          : 1;
+			bool saturate         : 1;
+			bool partialPrecision : 1;
+			bool centroid         : 1;
+			signed char shift     : 4;
+		};
+
+		struct SourceParameter : Parameter
+		{
+			SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE), bufferIndex(-1)
+			{
+			}
+
+			std::string swizzleString() const;
+			std::string preModifierString() const;
+			std::string postModifierString() const;
+
+			unsigned int swizzle : 8;
+			Modifier modifier : 8;
+			int bufferIndex : 8;
+		};
+
+		struct Instruction
+		{
+			explicit Instruction(Opcode opcode);
+			Instruction(const unsigned long *token, int size, unsigned char majorVersion);
+
+			virtual ~Instruction();
+
+			void parseOperationToken(unsigned long token, unsigned char majorVersion);
+			void parseDeclarationToken(unsigned long token);
+			void parseDestinationToken(const unsigned long *token, unsigned char majorVersion);
+			void parseSourceToken(int i, const unsigned long *token, unsigned char majorVersion);
+
+			std::string string(ShaderType shaderType, unsigned short version) const;
+			static std::string swizzleString(ParameterType type, unsigned char swizzle);
+			std::string operationString(unsigned short version) const;
+			std::string controlString() const;
+
+			bool isBranch() const;
+			bool isCall() const;
+			bool isBreak() const;
+			bool isLoop() const;
+			bool isEndLoop() const;
+
+			bool isPredicated() const;
+
+			Opcode opcode;
+
+			union
+			{
+				Control control;
+
+				struct
+				{
+					unsigned char project : 1;
+					unsigned char bias : 1;
+				};
+			};
+
+			bool predicate;
+			bool predicateNot;   // Negative predicate
+			unsigned char predicateSwizzle;
+
+			bool coissue;
+			SamplerType samplerType;
+			Usage usage;
+			unsigned char usageIndex;
+
+			DestinationParameter dst;
+			SourceParameter src[5];
+
+			union
+			{
+				unsigned int analysis;
+
+				struct
+				{
+					// Keep in sync with Shader::Analysis flags
+					unsigned int analysisBranch : 1;
+					unsigned int analysisBreak : 1;
+					unsigned int analysisContinue : 1;
+					unsigned int analysisLeave : 1;
+				};
+			};
+		};
+
+		Shader();
+
+		virtual ~Shader();
+
+		int getSerialID() const;
+		size_t getLength() const;
+		ShaderType getShaderType() const;
+		unsigned short getVersion() const;
+
+		void append(Instruction *instruction);
+		void declareSampler(int i);
+
+		const Instruction *getInstruction(unsigned int i) const;
+		int size(unsigned long opcode) const;
+		static int size(unsigned long opcode, unsigned short version);
+
+		void print(const char *fileName, ...) const;
+		void printInstruction(int index, const char *fileName) const;
+
+		static bool maskContainsComponent(int mask, int component);
+		static bool swizzleContainsComponent(int swizzle, int component);
+		static bool swizzleContainsComponentMasked(int swizzle, int component, int mask);
+
+		bool containsDynamicBranching() const;
+		bool containsBreakInstruction() const;
+		bool containsContinueInstruction() const;
+		bool containsLeaveInstruction() const;
+		bool containsDefineInstruction() const;
+		bool usesSampler(int i) const;
+
+		struct Semantic
+		{
+			Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF) : usage(usage), index(index), centroid(false)
+			{
+			}
+
+			bool operator==(const Semantic &semantic) const
+			{
+				return usage == semantic.usage && index == semantic.index;
+			}
+
+			bool active() const
+			{
+				return usage != 0xFF;
+			}
+
+			unsigned char usage;
+			unsigned char index;
+			bool centroid;
+		};
+
+		void optimize();
+		virtual void analyze() = 0;
+
+		// FIXME: Private
+		unsigned int dirtyConstantsF;
+		unsigned int dirtyConstantsI;
+		unsigned int dirtyConstantsB;
+
+		bool dynamicallyIndexedTemporaries;
+		bool dynamicallyIndexedInput;
+		bool dynamicallyIndexedOutput;
+
+	protected:
+		void parse(const unsigned long *token);
+
+		void optimizeLeave();
+		void optimizeCall();
+		void removeNull();
+
+		void analyzeDirtyConstants();
+		void analyzeDynamicBranching();
+		void analyzeSamplers();
+		void analyzeCallSites();
+		void analyzeDynamicIndexing();
+		void markFunctionAnalysis(unsigned int functionLabel, Analysis flag);
+
+		ShaderType shaderType;
+
+		union
+		{
+			unsigned short version;
+
+			struct
+			{
+				unsigned char minorVersion;
+				unsigned char majorVersion;
+			};
+		};
+
+		std::vector<Instruction*> instruction;
+
+		unsigned short usedSamplers;   // Bit flags
+
+	private:
+		const int serialID;
+		static volatile int serialCounter;
+
+		bool dynamicBranching;
+		bool containsBreak;
+		bool containsContinue;
+		bool containsLeave;
+		bool containsDefine;
+	};
+}
+
+#endif   // sw_Shader_hpp
diff --git a/src/Shader/ShaderCore.cpp b/src/Shader/ShaderCore.cpp
index b978d9e..685848a 100644
--- a/src/Shader/ShaderCore.cpp
+++ b/src/Shader/ShaderCore.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "ShaderCore.hpp"
 
@@ -200,7 +203,7 @@
 		Float4 x0;
 		Float4 x1;
 		Int4 x2;
-	
+
 		x0 = x;
 
 		x0 = Min(x0, As<Float4>(Int4(0x43010000)));   // 129.00000e+0f
@@ -224,7 +227,7 @@
 		x1 *= x0;
 		x1 += As<Float4>(Int4(0x3F7FFFFF));   // 9.9999994e-1f
 		x1 *= As<Float4>(x2);
-			
+
 		return x1;
 	}
 
@@ -234,9 +237,9 @@
 		Float4 x1;
 		Float4 x2;
 		Float4 x3;
-		
+
 		x0 = x;
-		
+
 		x1 = As<Float4>(As<Int4>(x0) & Int4(0x7F800000));
 		x1 = As<Float4>(As<UInt4>(x1) >> 8);
 		x1 = As<Float4>(As<Int4>(x1) | As<Int4>(Float4(1.0f)));
@@ -248,7 +251,7 @@
 		x2 /= x3;
 
 		x1 += (x0 - Float4(1.0f)) * x2;
-				
+
 		return x1;
 	}
 
@@ -357,7 +360,7 @@
 	{
 		// cos(x) = sin(x + pi/2)
 		Float4 y = x + Float4(1.57079632e+0f);
-		
+
 		// Wrap around
 		y -= As<Float4>(CmpNLT(y, Float4(3.14159265e+0f)) & As<Int4>(Float4(6.28318530e+0f)));
 
@@ -418,7 +421,7 @@
 
 		// Approximation of atan in [-1..1]
 		Float4 theta = y * (Float4(-0.27f) * Abs(y) + Float4(1.05539816f));
-		
+
 		// +/-pi/2 depending on sign of x
 		Float4 sgnPi_2 = As<Float4>(As<Int4>(Float4(1.57079632e+0f)) ^ (As<Int4>(x) & Int4(0x80000000)));
 
@@ -1029,7 +1032,7 @@
 	}
 
 	void ShaderCore::exp2x(Vector4f &dst, const Vector4f &src, bool pp)
-	{ 
+	{
 		Float4 exp = exponential2(src.x, pp);
 
 		dst.x = exp;
@@ -1132,7 +1135,7 @@
 		static const uint32_t c_nanbit = 0x200;
 		static const uint32_t c_infty_as_fp16 = 0x7c00;
 		static const uint32_t c_clamp = (31 << 23) - 0x1000;
-		
+
 		UInt4 justsign = UInt4(mask_sign) & As<UInt4>(floatBits);
 		UInt4 absf = As<UInt4>(floatBits) ^ justsign;
 		UInt4 b_isnormal = CmpNLE(UInt4(c_f32infty), absf);
@@ -1347,7 +1350,7 @@
 		dst.z =  As<Float4>(flip ^ As<Int4>(N.z));
 		dst.w =  As<Float4>(flip ^ As<Int4>(N.w));
 	}
-	
+
 	void ShaderCore::reflect1(Vector4f &dst, const Vector4f &I, const Vector4f &N)
 	{
 		Float4 d = N.x * I.x;
@@ -1492,7 +1495,7 @@
 		dst.z = src.z * rsq;
 		dst.w = src.w * rsq;
 	}
-	
+
 	void ShaderCore::sincos(Vector4f &dst, const Vector4f &src, bool pp)
 	{
 		dst.x = cosine_pi(src.x, pp);
@@ -1620,7 +1623,7 @@
 			exp2x(dst, src, true);   // FIXME: 10-bit precision suffices
 		}
 	}
-	
+
 	void ShaderCore::logp(Vector4f &dst, const Vector4f &src, unsigned short version)
 	{
 		if(version < 0x0200)
@@ -1651,7 +1654,7 @@
 			log2x(dst, src, true);
 		}
 	}
-	
+
 	void ShaderCore::cmp0(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2)
 	{
 		cmp0(dst.x, src0.x, src1.x, src2.x);
diff --git a/src/Shader/ShaderCore.hpp b/src/Shader/ShaderCore.hpp
index 7eeec42..f105c50 100644
--- a/src/Shader/ShaderCore.hpp
+++ b/src/Shader/ShaderCore.hpp
@@ -1,393 +1,396 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_ShaderCore_hpp

-#define sw_ShaderCore_hpp

-

-#include "Debug.hpp"

-#include "Shader.hpp"

-#include "Reactor/Reactor.hpp"

-

-namespace sw

-{

-	class Vector4s

-	{

-	public:

-		Vector4s();

-		Vector4s(unsigned short x, unsigned short y, unsigned short z, unsigned short w);

-		Vector4s(const Vector4s &rhs);

-

-		Short4 &operator[](int i);

-		Vector4s &operator=(const Vector4s &rhs);

-

-		Short4 x;

-		Short4 y;

-		Short4 z;

-		Short4 w;

-	};

-

-	class Vector4i

-	{

-	public:

-		Vector4i();

-		Vector4i(int x, int y, int z, int w);

-		Vector4i(const Vector4i &rhs);

-

-		Int4 &operator[](int i);

-		Vector4i &operator=(const Vector4i &rhs);

-

-		Int4 x;

-		Int4 y;

-		Int4 z;

-		Int4 w;

-	};

-

-	class Vector4u

-	{

-	public:

-		Vector4u();

-		Vector4u(unsigned int x, unsigned int y, unsigned int z, unsigned int w);

-		Vector4u(const Vector4u &rhs);

-

-		UInt4 &operator[](int i);

-		Vector4u &operator=(const Vector4u &rhs);

-

-		UInt4 x;

-		UInt4 y;

-		UInt4 z;

-		UInt4 w;

-	};

-

-	class Vector4f

-	{

-	public:

-		Vector4f();

-		Vector4f(float x, float y, float z, float w);

-		Vector4f(const Vector4f &rhs);

-

-		Float4 &operator[](int i);

-		Vector4f &operator=(const Vector4f &rhs);

-

-		Float4 x;

-		Float4 y;

-		Float4 z;

-		Float4 w;

-	};

-

-	Float4 exponential2(RValue<Float4> x, bool pp = false);

-	Float4 logarithm2(RValue<Float4> x, bool abs, bool pp = false);

-	Float4 exponential(RValue<Float4> x, bool pp = false);

-	Float4 logarithm(RValue<Float4> x, bool abs, bool pp = false);

-	Float4 power(RValue<Float4> x, RValue<Float4> y, bool pp = false);

-	Float4 reciprocal(RValue<Float4> x, bool pp = false, bool finite = false, bool exactAtPow2 = false);

-	Float4 reciprocalSquareRoot(RValue<Float4> x, bool abs, bool pp = false);

-	Float4 modulo(RValue<Float4> x, RValue<Float4> y);

-	Float4 sine_pi(RValue<Float4> x, bool pp = false);     // limited to [-pi, pi] range

-	Float4 cosine_pi(RValue<Float4> x, bool pp = false);   // limited to [-pi, pi] range

-	Float4 sine(RValue<Float4> x, bool pp = false);

-	Float4 cosine(RValue<Float4> x, bool pp = false);

-	Float4 tangent(RValue<Float4> x, bool pp = false);

-	Float4 arccos(RValue<Float4> x, bool pp = false);

-	Float4 arcsin(RValue<Float4> x, bool pp = false);

-	Float4 arctan(RValue<Float4> x, bool pp = false);

-	Float4 arctan(RValue<Float4> y, RValue<Float4> x, bool pp = false);

-	Float4 sineh(RValue<Float4> x, bool pp = false);

-	Float4 cosineh(RValue<Float4> x, bool pp = false);

-	Float4 tangenth(RValue<Float4> x, bool pp = false);

-	Float4 arccosh(RValue<Float4> x, bool pp = false);  // Limited to x >= 1

-	Float4 arcsinh(RValue<Float4> x, bool pp = false);

-	Float4 arctanh(RValue<Float4> x, bool pp = false);  // Limited to ]-1, 1[ range

-

-	Float4 dot2(const Vector4f &v0, const Vector4f &v1);

-	Float4 dot3(const Vector4f &v0, const Vector4f &v1);

-	Float4 dot4(const Vector4f &v0, const Vector4f &v1);

-

-	void transpose4x4(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3);

-	void transpose4x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4x3(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4x2(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4x1(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose2x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose2x4h(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);

-	void transpose4xN(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3, int N);

-

-	class Register

-	{

-	public:

-		Register(const Reference<Float4> &x, const Reference<Float4> &y, const Reference<Float4> &z, const Reference<Float4> &w) : x(x), y(y), z(z), w(w)

-		{

-		}

-

-		Reference<Float4> &operator[](int i)

-		{

-			switch(i)

-			{

-			default:

-			case 0: return x;

-			case 1: return y;

-			case 2: return z;

-			case 3: return w;

-			}

-		}

-

-		Register &operator=(const Register &rhs)

-		{

-			x = rhs.x;

-			y = rhs.y;

-			z = rhs.z;

-			w = rhs.w;

-

-			return *this;

-		}

-

-		Register &operator=(const Vector4f &rhs)

-		{

-			x = rhs.x;

-			y = rhs.y;

-			z = rhs.z;

-			w = rhs.w;

-

-			return *this;

-		}

-

-		operator Vector4f()

-		{

-			Vector4f v;

-

-			v.x = x;

-			v.y = y;

-			v.z = z;

-			v.w = w;

-

-			return v;

-		}

-

-		Reference<Float4> x;

-		Reference<Float4> y;

-		Reference<Float4> z;

-		Reference<Float4> w;

-	};

-

-	template<int S, bool D = false>

-	class RegisterArray

-	{

-	public:

-		RegisterArray(bool dynamic = D) : dynamic(dynamic)

-		{

-			if(dynamic)

-			{

-				x = new Array<Float4>(S);

-				y = new Array<Float4>(S);

-				z = new Array<Float4>(S);

-				w = new Array<Float4>(S);

-			}

-			else

-			{

-				x = new Array<Float4>[S];

-				y = new Array<Float4>[S];

-				z = new Array<Float4>[S];

-				w = new Array<Float4>[S];

-			}

-		}

-

-		~RegisterArray()

-		{

-			if(dynamic)

-			{

-				delete x;

-				delete y;

-				delete z;

-				delete w;

-			}

-			else

-			{

-				delete[] x;

-				delete[] y;

-				delete[] z;

-				delete[] w;

-			}

-		}

-

-		Register operator[](int i)

-		{

-			if(dynamic)

-			{

-				return Register(x[0][i], y[0][i], z[0][i], w[0][i]);

-			}

-			else

-			{

-				return Register(x[i][0], y[i][0], z[i][0], w[i][0]);

-			}

-		}

-

-		Register operator[](RValue<Int> i)

-		{

-			ASSERT(dynamic);

-

-			return Register(x[0][i], y[0][i], z[0][i], w[0][i]);

-		}

-

-	private:

-		const bool dynamic;

-		Array<Float4> *x;

-		Array<Float4> *y;

-		Array<Float4> *z;

-		Array<Float4> *w;

-	};

-

-	class ShaderCore

-	{

-		typedef Shader::Control Control;

-

-	public:

-		void mov(Vector4f &dst, const Vector4f &src, bool integerDestination = false);

-		void neg(Vector4f &dst, const Vector4f &src);

-		void ineg(Vector4f &dst, const Vector4f &src);

-		void f2b(Vector4f &dst, const Vector4f &src);

-		void b2f(Vector4f &dst, const Vector4f &src);

-		void f2i(Vector4f &dst, const Vector4f &src);

-		void i2f(Vector4f &dst, const Vector4f &src);

-		void f2u(Vector4f &dst, const Vector4f &src);

-		void u2f(Vector4f &dst, const Vector4f &src);

-		void i2b(Vector4f &dst, const Vector4f &src);

-		void b2i(Vector4f &dst, const Vector4f &src);

-		void add(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void iadd(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void sub(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void isub(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void mad(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void imad(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void mul(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void imul(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void rcpx(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void div(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void idiv(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void udiv(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void mod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void imod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void umod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void shl(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void ishr(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void ushr(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void rsqx(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void sqrt(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void rsq(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void len2(Float4 &dst, const Vector4f &src, bool pp = false);

-		void len3(Float4 &dst, const Vector4f &src, bool pp = false);

-		void len4(Float4 &dst, const Vector4f &src, bool pp = false);

-		void dist1(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);

-		void dist2(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);

-		void dist3(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);

-		void dist4(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);

-		void dp1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void dp2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void dp2add(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void dp3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void dp4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void det2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void det3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void det4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2, const Vector4f &src3);

-		void min(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void imin(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void umin(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void max(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void imax(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void umax(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void slt(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void step(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void exp2x(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void exp2(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void exp(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void log2x(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void log2(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void log(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void lit(Vector4f &dst, const Vector4f &src);

-		void att(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void lrp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void smooth(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void packHalf2x16(Vector4f &dst, const Vector4f &src);

-		void unpackHalf2x16(Vector4f &dst, const Vector4f &src);

-		void packSnorm2x16(Vector4f &dst, const Vector4f &src);

-		void packUnorm2x16(Vector4f &dst, const Vector4f &src);

-		void unpackSnorm2x16(Vector4f &dst, const Vector4f &src);

-		void unpackUnorm2x16(Vector4f &dst, const Vector4f &src);

-		void frc(Vector4f &dst, const Vector4f &src);

-		void trunc(Vector4f &dst, const Vector4f &src);

-		void floor(Vector4f &dst, const Vector4f &src);

-		void round(Vector4f &dst, const Vector4f &src);

-		void roundEven(Vector4f &dst, const Vector4f &src);

-		void ceil(Vector4f &dst, const Vector4f &src);

-		void powx(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);

-		void pow(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);

-		void crs(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void forward1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void forward2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void forward3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void forward4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void reflect1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void reflect2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void reflect3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void reflect4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void refract1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);

-		void refract2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);

-		void refract3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);

-		void refract4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);

-		void sgn(Vector4f &dst, const Vector4f &src);

-		void isgn(Vector4f &dst, const Vector4f &src);

-		void abs(Vector4f &dst, const Vector4f &src);

-		void iabs(Vector4f &dst, const Vector4f &src);

-		void nrm2(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void nrm3(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void nrm4(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void sincos(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void cos(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void sin(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void tan(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void acos(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void asin(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void atan(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void atan2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);

-		void cosh(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void sinh(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void tanh(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void acosh(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void asinh(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void atanh(Vector4f &dst, const Vector4f &src, bool pp = false);

-		void expp(Vector4f &dst, const Vector4f &src, unsigned short version);

-		void logp(Vector4f &dst, const Vector4f &src, unsigned short version);

-		void cmp0(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void cmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);

-		void icmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);

-		void ucmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);

-		void select(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);

-		void extract(Float4 &dst, const Vector4f &src0, const Float4 &src1);

-		void insert(Vector4f &dst, const Vector4f &src, const Float4 &element, const Float4 &index);

-		void all(Float4 &dst, const Vector4f &src);

-		void any(Float4 &dst, const Vector4f &src);

-		void not(Vector4f &dst, const Vector4f &src);

-		void or(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void xor(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void and(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void equal(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-		void notEqual(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);

-

-	private:

-		void sgn(Float4 &dst, const Float4 &src);

-		void isgn(Float4 &dst, const Float4 &src);

-		void cmp0(Float4 &dst, const Float4 &src0, const Float4 &src1, const Float4 &src2);

-		void cmp0i(Float4 &dst, const Float4 &src0, const Float4 &src1, const Float4 &src2);

-		void select(Float4 &dst, RValue<Int4> src0, const Float4 &src1, const Float4 &src2);

-		void floatToHalfBits(Float4& dst, const Float4& floatBits, bool storeInUpperBits);

-		void halfToFloatBits(Float4& dst, const Float4& halfBits);

-	};

-}

-

-#endif   // sw_ShaderCore_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_ShaderCore_hpp
+#define sw_ShaderCore_hpp
+
+#include "Debug.hpp"
+#include "Shader.hpp"
+#include "Reactor/Reactor.hpp"
+
+namespace sw
+{
+	class Vector4s
+	{
+	public:
+		Vector4s();
+		Vector4s(unsigned short x, unsigned short y, unsigned short z, unsigned short w);
+		Vector4s(const Vector4s &rhs);
+
+		Short4 &operator[](int i);
+		Vector4s &operator=(const Vector4s &rhs);
+
+		Short4 x;
+		Short4 y;
+		Short4 z;
+		Short4 w;
+	};
+
+	class Vector4i
+	{
+	public:
+		Vector4i();
+		Vector4i(int x, int y, int z, int w);
+		Vector4i(const Vector4i &rhs);
+
+		Int4 &operator[](int i);
+		Vector4i &operator=(const Vector4i &rhs);
+
+		Int4 x;
+		Int4 y;
+		Int4 z;
+		Int4 w;
+	};
+
+	class Vector4u
+	{
+	public:
+		Vector4u();
+		Vector4u(unsigned int x, unsigned int y, unsigned int z, unsigned int w);
+		Vector4u(const Vector4u &rhs);
+
+		UInt4 &operator[](int i);
+		Vector4u &operator=(const Vector4u &rhs);
+
+		UInt4 x;
+		UInt4 y;
+		UInt4 z;
+		UInt4 w;
+	};
+
+	class Vector4f
+	{
+	public:
+		Vector4f();
+		Vector4f(float x, float y, float z, float w);
+		Vector4f(const Vector4f &rhs);
+
+		Float4 &operator[](int i);
+		Vector4f &operator=(const Vector4f &rhs);
+
+		Float4 x;
+		Float4 y;
+		Float4 z;
+		Float4 w;
+	};
+
+	Float4 exponential2(RValue<Float4> x, bool pp = false);
+	Float4 logarithm2(RValue<Float4> x, bool abs, bool pp = false);
+	Float4 exponential(RValue<Float4> x, bool pp = false);
+	Float4 logarithm(RValue<Float4> x, bool abs, bool pp = false);
+	Float4 power(RValue<Float4> x, RValue<Float4> y, bool pp = false);
+	Float4 reciprocal(RValue<Float4> x, bool pp = false, bool finite = false, bool exactAtPow2 = false);
+	Float4 reciprocalSquareRoot(RValue<Float4> x, bool abs, bool pp = false);
+	Float4 modulo(RValue<Float4> x, RValue<Float4> y);
+	Float4 sine_pi(RValue<Float4> x, bool pp = false);     // limited to [-pi, pi] range
+	Float4 cosine_pi(RValue<Float4> x, bool pp = false);   // limited to [-pi, pi] range
+	Float4 sine(RValue<Float4> x, bool pp = false);
+	Float4 cosine(RValue<Float4> x, bool pp = false);
+	Float4 tangent(RValue<Float4> x, bool pp = false);
+	Float4 arccos(RValue<Float4> x, bool pp = false);
+	Float4 arcsin(RValue<Float4> x, bool pp = false);
+	Float4 arctan(RValue<Float4> x, bool pp = false);
+	Float4 arctan(RValue<Float4> y, RValue<Float4> x, bool pp = false);
+	Float4 sineh(RValue<Float4> x, bool pp = false);
+	Float4 cosineh(RValue<Float4> x, bool pp = false);
+	Float4 tangenth(RValue<Float4> x, bool pp = false);
+	Float4 arccosh(RValue<Float4> x, bool pp = false);  // Limited to x >= 1
+	Float4 arcsinh(RValue<Float4> x, bool pp = false);
+	Float4 arctanh(RValue<Float4> x, bool pp = false);  // Limited to ]-1, 1[ range
+
+	Float4 dot2(const Vector4f &v0, const Vector4f &v1);
+	Float4 dot3(const Vector4f &v0, const Vector4f &v1);
+	Float4 dot4(const Vector4f &v0, const Vector4f &v1);
+
+	void transpose4x4(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3);
+	void transpose4x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
+	void transpose4x3(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
+	void transpose4x2(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
+	void transpose4x1(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
+	void transpose2x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
+	void transpose2x4h(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
+	void transpose4xN(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3, int N);
+
+	class Register
+	{
+	public:
+		Register(const Reference<Float4> &x, const Reference<Float4> &y, const Reference<Float4> &z, const Reference<Float4> &w) : x(x), y(y), z(z), w(w)
+		{
+		}
+
+		Reference<Float4> &operator[](int i)
+		{
+			switch(i)
+			{
+			default:
+			case 0: return x;
+			case 1: return y;
+			case 2: return z;
+			case 3: return w;
+			}
+		}
+
+		Register &operator=(const Register &rhs)
+		{
+			x = rhs.x;
+			y = rhs.y;
+			z = rhs.z;
+			w = rhs.w;
+
+			return *this;
+		}
+
+		Register &operator=(const Vector4f &rhs)
+		{
+			x = rhs.x;
+			y = rhs.y;
+			z = rhs.z;
+			w = rhs.w;
+
+			return *this;
+		}
+
+		operator Vector4f()
+		{
+			Vector4f v;
+
+			v.x = x;
+			v.y = y;
+			v.z = z;
+			v.w = w;
+
+			return v;
+		}
+
+		Reference<Float4> x;
+		Reference<Float4> y;
+		Reference<Float4> z;
+		Reference<Float4> w;
+	};
+
+	template<int S, bool D = false>
+	class RegisterArray
+	{
+	public:
+		RegisterArray(bool dynamic = D) : dynamic(dynamic)
+		{
+			if(dynamic)
+			{
+				x = new Array<Float4>(S);
+				y = new Array<Float4>(S);
+				z = new Array<Float4>(S);
+				w = new Array<Float4>(S);
+			}
+			else
+			{
+				x = new Array<Float4>[S];
+				y = new Array<Float4>[S];
+				z = new Array<Float4>[S];
+				w = new Array<Float4>[S];
+			}
+		}
+
+		~RegisterArray()
+		{
+			if(dynamic)
+			{
+				delete x;
+				delete y;
+				delete z;
+				delete w;
+			}
+			else
+			{
+				delete[] x;
+				delete[] y;
+				delete[] z;
+				delete[] w;
+			}
+		}
+
+		Register operator[](int i)
+		{
+			if(dynamic)
+			{
+				return Register(x[0][i], y[0][i], z[0][i], w[0][i]);
+			}
+			else
+			{
+				return Register(x[i][0], y[i][0], z[i][0], w[i][0]);
+			}
+		}
+
+		Register operator[](RValue<Int> i)
+		{
+			ASSERT(dynamic);
+
+			return Register(x[0][i], y[0][i], z[0][i], w[0][i]);
+		}
+
+	private:
+		const bool dynamic;
+		Array<Float4> *x;
+		Array<Float4> *y;
+		Array<Float4> *z;
+		Array<Float4> *w;
+	};
+
+	class ShaderCore
+	{
+		typedef Shader::Control Control;
+
+	public:
+		void mov(Vector4f &dst, const Vector4f &src, bool integerDestination = false);
+		void neg(Vector4f &dst, const Vector4f &src);
+		void ineg(Vector4f &dst, const Vector4f &src);
+		void f2b(Vector4f &dst, const Vector4f &src);
+		void b2f(Vector4f &dst, const Vector4f &src);
+		void f2i(Vector4f &dst, const Vector4f &src);
+		void i2f(Vector4f &dst, const Vector4f &src);
+		void f2u(Vector4f &dst, const Vector4f &src);
+		void u2f(Vector4f &dst, const Vector4f &src);
+		void i2b(Vector4f &dst, const Vector4f &src);
+		void b2i(Vector4f &dst, const Vector4f &src);
+		void add(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void iadd(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void sub(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void isub(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void mad(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void imad(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void mul(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void imul(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void rcpx(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void div(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void idiv(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void udiv(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void mod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void imod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void umod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void shl(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void ishr(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void ushr(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void rsqx(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void sqrt(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void rsq(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void len2(Float4 &dst, const Vector4f &src, bool pp = false);
+		void len3(Float4 &dst, const Vector4f &src, bool pp = false);
+		void len4(Float4 &dst, const Vector4f &src, bool pp = false);
+		void dist1(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);
+		void dist2(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);
+		void dist3(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);
+		void dist4(Float4 &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);
+		void dp1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void dp2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void dp2add(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void dp3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void dp4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void det2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void det3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void det4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2, const Vector4f &src3);
+		void min(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void imin(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void umin(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void max(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void imax(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void umax(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void slt(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void step(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void exp2x(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void exp2(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void exp(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void log2x(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void log2(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void log(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void lit(Vector4f &dst, const Vector4f &src);
+		void att(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void lrp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void smooth(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void packHalf2x16(Vector4f &dst, const Vector4f &src);
+		void unpackHalf2x16(Vector4f &dst, const Vector4f &src);
+		void packSnorm2x16(Vector4f &dst, const Vector4f &src);
+		void packUnorm2x16(Vector4f &dst, const Vector4f &src);
+		void unpackSnorm2x16(Vector4f &dst, const Vector4f &src);
+		void unpackUnorm2x16(Vector4f &dst, const Vector4f &src);
+		void frc(Vector4f &dst, const Vector4f &src);
+		void trunc(Vector4f &dst, const Vector4f &src);
+		void floor(Vector4f &dst, const Vector4f &src);
+		void round(Vector4f &dst, const Vector4f &src);
+		void roundEven(Vector4f &dst, const Vector4f &src);
+		void ceil(Vector4f &dst, const Vector4f &src);
+		void powx(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);
+		void pow(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);
+		void crs(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void forward1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void forward2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void forward3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void forward4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void reflect1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void reflect2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void reflect3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void reflect4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void refract1(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);
+		void refract2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);
+		void refract3(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);
+		void refract4(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Float4 &src2);
+		void sgn(Vector4f &dst, const Vector4f &src);
+		void isgn(Vector4f &dst, const Vector4f &src);
+		void abs(Vector4f &dst, const Vector4f &src);
+		void iabs(Vector4f &dst, const Vector4f &src);
+		void nrm2(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void nrm3(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void nrm4(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void sincos(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void cos(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void sin(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void tan(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void acos(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void asin(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void atan(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void atan2(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, bool pp = false);
+		void cosh(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void sinh(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void tanh(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void acosh(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void asinh(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void atanh(Vector4f &dst, const Vector4f &src, bool pp = false);
+		void expp(Vector4f &dst, const Vector4f &src, unsigned short version);
+		void logp(Vector4f &dst, const Vector4f &src, unsigned short version);
+		void cmp0(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void cmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);
+		void icmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);
+		void ucmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);
+		void select(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+		void extract(Float4 &dst, const Vector4f &src0, const Float4 &src1);
+		void insert(Vector4f &dst, const Vector4f &src, const Float4 &element, const Float4 &index);
+		void all(Float4 &dst, const Vector4f &src);
+		void any(Float4 &dst, const Vector4f &src);
+		void not(Vector4f &dst, const Vector4f &src);
+		void or(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void xor(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void and(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void equal(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+		void notEqual(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
+
+	private:
+		void sgn(Float4 &dst, const Float4 &src);
+		void isgn(Float4 &dst, const Float4 &src);
+		void cmp0(Float4 &dst, const Float4 &src0, const Float4 &src1, const Float4 &src2);
+		void cmp0i(Float4 &dst, const Float4 &src0, const Float4 &src1, const Float4 &src2);
+		void select(Float4 &dst, RValue<Int4> src0, const Float4 &src1, const Float4 &src2);
+		void floatToHalfBits(Float4& dst, const Float4& floatBits, bool storeInUpperBits);
+		void halfToFloatBits(Float4& dst, const Float4& halfBits);
+	};
+}
+
+#endif   // sw_ShaderCore_hpp
diff --git a/src/Shader/VertexPipeline.cpp b/src/Shader/VertexPipeline.cpp
index c2fa31f..a214d90 100644
--- a/src/Shader/VertexPipeline.cpp
+++ b/src/Shader/VertexPipeline.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "VertexPipeline.hpp"
 
diff --git a/src/Shader/VertexPipeline.hpp b/src/Shader/VertexPipeline.hpp
index babe214..e8b954c 100644
--- a/src/Shader/VertexPipeline.hpp
+++ b/src/Shader/VertexPipeline.hpp
@@ -1,42 +1,45 @@
-// SwiftShader Software Renderer

-//

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

-//

-

-#ifndef sw_VertexPipeline_hpp

-#define sw_VertexPipeline_hpp

-

-#include "VertexRoutine.hpp"

-

-#include "Context.hpp"

-#include "VertexProcessor.hpp"

-

-namespace sw

-{

-	class VertexPipeline : public VertexRoutine

-	{

-	public:

-		VertexPipeline(const VertexProcessor::State &state);

-

-		virtual ~VertexPipeline();

-

-	private:

-		void pipeline() override;

-		void processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position);

-		void processPointSize();

-

-		Vector4f transformBlend(const Register &src, const Pointer<Byte> &matrix, bool homogenous);

-		Vector4f transform(const Register &src, const Pointer<Byte> &matrix, bool homogenous);

-		Vector4f transform(const Register &src, const Pointer<Byte> &matrix, UInt index[4], bool homogenous);

-		Vector4f normalize(Vector4f &src);

-		Float4 power(Float4 &src0, Float4 &src1);

-	};

-};

-

-#endif   // sw_VertexPipeline_hpp

+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_VertexPipeline_hpp
+#define sw_VertexPipeline_hpp
+
+#include "VertexRoutine.hpp"
+
+#include "Context.hpp"
+#include "VertexProcessor.hpp"
+
+namespace sw
+{
+	class VertexPipeline : public VertexRoutine
+	{
+	public:
+		VertexPipeline(const VertexProcessor::State &state);
+
+		virtual ~VertexPipeline();
+
+	private:
+		void pipeline() override;
+		void processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position);
+		void processPointSize();
+
+		Vector4f transformBlend(const Register &src, const Pointer<Byte> &matrix, bool homogenous);
+		Vector4f transform(const Register &src, const Pointer<Byte> &matrix, bool homogenous);
+		Vector4f transform(const Register &src, const Pointer<Byte> &matrix, UInt index[4], bool homogenous);
+		Vector4f normalize(Vector4f &src);
+		Float4 power(Float4 &src0, Float4 &src1);
+	};
+};
+
+#endif   // sw_VertexPipeline_hpp
diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp
index 492dd41..5be2070 100644
--- a/src/Shader/VertexProgram.cpp
+++ b/src/Shader/VertexProgram.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "VertexProgram.hpp"
 
@@ -674,7 +677,7 @@
 			reg = readConstant(src, offset);
 			break;
 		case Shader::PARAMETER_INPUT:
-            if(src.rel.type == Shader::PARAMETER_VOID)
+			if(src.rel.type == Shader::PARAMETER_VOID)
 			{
 				reg = v[i];
 			}
@@ -682,7 +685,7 @@
 			{
 				reg = v[i + relativeAddress(src, src.bufferIndex)];
 			}
-            break;
+			break;
 		case Shader::PARAMETER_VOID: return r[0];   // Dummy
 		case Shader::PARAMETER_FLOAT4LITERAL:
 			reg.x = Float4(src.value[0]);
@@ -706,7 +709,7 @@
 			}
 			return reg;
 		case Shader::PARAMETER_OUTPUT:
-            if(src.rel.type == Shader::PARAMETER_VOID)
+			if(src.rel.type == Shader::PARAMETER_VOID)
 			{
 				reg = o[i];
 			}
diff --git a/src/Shader/VertexProgram.hpp b/src/Shader/VertexProgram.hpp
index 98e09cd..f4f1677 100644
--- a/src/Shader/VertexProgram.hpp
+++ b/src/Shader/VertexProgram.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_VertexProgram_hpp
 #define sw_VertexProgram_hpp
diff --git a/src/Shader/VertexRoutine.cpp b/src/Shader/VertexRoutine.cpp
index 812bf0c..e5405ef 100644
--- a/src/Shader/VertexRoutine.cpp
+++ b/src/Shader/VertexRoutine.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "VertexRoutine.hpp"
 
diff --git a/src/Shader/VertexRoutine.hpp b/src/Shader/VertexRoutine.hpp
index 1861d10..71aeb5b 100644
--- a/src/Shader/VertexRoutine.hpp
+++ b/src/Shader/VertexRoutine.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_VertexRoutine_hpp
 #define sw_VertexRoutine_hpp
diff --git a/src/Shader/VertexShader.cpp b/src/Shader/VertexShader.cpp
index dc8bd06..1de8c93 100644
--- a/src/Shader/VertexShader.cpp
+++ b/src/Shader/VertexShader.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #include "VertexShader.hpp"
 
diff --git a/src/Shader/VertexShader.hpp b/src/Shader/VertexShader.hpp
index 127d64c..f8760fb 100644
--- a/src/Shader/VertexShader.hpp
+++ b/src/Shader/VertexShader.hpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// 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.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
 
 #ifndef sw_VertexShader_hpp
 #define sw_VertexShader_hpp
diff --git a/src/SwiftShader/SwiftShader.vcxproj b/src/SwiftShader/SwiftShader.vcxproj
index eb817c5..8bf7b8b 100644
--- a/src/SwiftShader/SwiftShader.vcxproj
+++ b/src/SwiftShader/SwiftShader.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>

+<?xml version="1.0" encoding="utf-8"?>

 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

@@ -387,6 +387,7 @@
     <ClInclude Include="..\Common\Version.h" />

     <ClInclude Include="..\Main\FrameBufferWin.hpp" />

     <ClInclude Include="..\Renderer\ETC_Decoder.hpp" />

+    <ClInclude Include="..\Renderer\Polygon.hpp" />

     <ClInclude Include="..\Renderer\RoutineCache.hpp" />

     <ClInclude Include="..\Shader\PixelPipeline.hpp" />

     <ClInclude Include="..\Shader\PixelProgram.hpp" />

diff --git a/src/SwiftShader/SwiftShader.vcxproj.filters b/src/SwiftShader/SwiftShader.vcxproj.filters
index 287b72b..c46f397 100644
--- a/src/SwiftShader/SwiftShader.vcxproj.filters
+++ b/src/SwiftShader/SwiftShader.vcxproj.filters
@@ -347,6 +347,9 @@
     <ClInclude Include="..\Renderer\ETC_Decoder.hpp">

       <Filter>Header Files\Renderer</Filter>

     </ClInclude>

+    <ClInclude Include="..\Renderer\Polygon.hpp">

+      <Filter>Header Files\Renderer</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <None Include="SwiftShader.ini" />