Duplicate source files for Vulkan.

The Vulkan implementation needs a directory for each architectural
layer, similar to the OpenGL ES stack. The entire rendering stack is
duplicated, leaving only Reactor common between them:

Renderer -> Device
Shader -> Pipeline
Common -> System
Main -> WSI

Bug b/117152542

Change-Id: I9c26b23654016d637f88ec2416f019ef65b9afbd
Reviewed-on: https://swiftshader-review.googlesource.com/c/21248
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/System/CPUID.cpp b/src/System/CPUID.cpp
new file mode 100644
index 0000000..c080034
--- /dev/null
+++ b/src/System/CPUID.cpp
@@ -0,0 +1,301 @@
+// 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 "CPUID.hpp"
+
+#if defined(_WIN32)
+	#ifndef WIN32_LEAN_AND_MEAN
+		#define WIN32_LEAN_AND_MEAN
+	#endif
+	#include <windows.h>
+	#include <intrin.h>
+	#include <float.h>
+#else
+	#include <unistd.h>
+	#include <sched.h>
+	#include <sys/types.h>
+#endif
+
+namespace sw
+{
+	bool CPUID::MMX = detectMMX();
+	bool CPUID::CMOV = detectCMOV();
+	bool CPUID::SSE = detectSSE();
+	bool CPUID::SSE2 = detectSSE2();
+	bool CPUID::SSE3 = detectSSE3();
+	bool CPUID::SSSE3 = detectSSSE3();
+	bool CPUID::SSE4_1 = detectSSE4_1();
+	int CPUID::cores = detectCoreCount();
+	int CPUID::affinity = detectAffinity();
+
+	bool CPUID::enableMMX = true;
+	bool CPUID::enableCMOV = true;
+	bool CPUID::enableSSE = true;
+	bool CPUID::enableSSE2 = true;
+	bool CPUID::enableSSE3 = true;
+	bool CPUID::enableSSSE3 = true;
+	bool CPUID::enableSSE4_1 = true;
+
+	void CPUID::setEnableMMX(bool enable)
+	{
+		enableMMX = enable;
+
+		if(!enableMMX)
+		{
+			enableSSE = false;
+			enableSSE2 = false;
+			enableSSE3 = false;
+			enableSSSE3 = false;
+			enableSSE4_1 = false;
+		}
+	}
+
+	void CPUID::setEnableCMOV(bool enable)
+	{
+		enableCMOV = enable;
+
+		if(!CMOV)
+		{
+			enableSSE = false;
+			enableSSE2 = false;
+			enableSSE3 = false;
+			enableSSSE3 = false;
+			enableSSE4_1 = false;
+		}
+	}
+
+	void CPUID::setEnableSSE(bool enable)
+	{
+		enableSSE = enable;
+
+		if(enableSSE)
+		{
+			enableMMX = true;
+			enableCMOV = true;
+		}
+		else
+		{
+			enableSSE2 = false;
+			enableSSE3 = false;
+			enableSSSE3 = false;
+			enableSSE4_1 = false;
+		}
+	}
+
+	void CPUID::setEnableSSE2(bool enable)
+	{
+		enableSSE2 = enable;
+
+		if(enableSSE2)
+		{
+			enableMMX = true;
+			enableCMOV = true;
+			enableSSE = true;
+		}
+		else
+		{
+			enableSSE3 = false;
+			enableSSSE3 = false;
+			enableSSE4_1 = false;
+		}
+	}
+
+	void CPUID::setEnableSSE3(bool enable)
+	{
+		enableSSE3 = enable;
+
+		if(enableSSE3)
+		{
+			enableMMX = true;
+			enableCMOV = true;
+			enableSSE = true;
+			enableSSE2 = true;
+		}
+		else
+		{
+			enableSSSE3 = false;
+			enableSSE4_1 = false;
+		}
+	}
+
+	void CPUID::setEnableSSSE3(bool enable)
+	{
+		enableSSSE3 = enable;
+
+		if(enableSSSE3)
+		{
+			enableMMX = true;
+			enableCMOV = true;
+			enableSSE = true;
+			enableSSE2 = true;
+			enableSSE3 = true;
+		}
+		else
+		{
+			enableSSE4_1 = false;
+		}
+	}
+
+	void CPUID::setEnableSSE4_1(bool enable)
+	{
+		enableSSE4_1 = enable;
+
+		if(enableSSE4_1)
+		{
+			enableMMX = true;
+			enableCMOV = true;
+			enableSSE = true;
+			enableSSE2 = true;
+			enableSSE3 = true;
+			enableSSSE3 = true;
+		}
+	}
+
+	static void cpuid(int registers[4], int info)
+	{
+		#if defined(__i386__) || defined(__x86_64__)
+			#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
+		#else
+			registers[0] = 0;
+			registers[1] = 0;
+			registers[2] = 0;
+			registers[3] = 0;
+		#endif
+	}
+
+	bool CPUID::detectMMX()
+	{
+		int registers[4];
+		cpuid(registers, 1);
+		return MMX = (registers[3] & 0x00800000) != 0;
+	}
+
+	bool CPUID::detectCMOV()
+	{
+		int registers[4];
+		cpuid(registers, 1);
+		return CMOV = (registers[3] & 0x00008000) != 0;
+	}
+
+	bool CPUID::detectSSE()
+	{
+		int registers[4];
+		cpuid(registers, 1);
+		return SSE = (registers[3] & 0x02000000) != 0;
+	}
+
+	bool CPUID::detectSSE2()
+	{
+		int registers[4];
+		cpuid(registers, 1);
+		return SSE2 = (registers[3] & 0x04000000) != 0;
+	}
+
+	bool CPUID::detectSSE3()
+	{
+		int registers[4];
+		cpuid(registers, 1);
+		return SSE3 = (registers[2] & 0x00000001) != 0;
+	}
+
+	bool CPUID::detectSSSE3()
+	{
+		int registers[4];
+		cpuid(registers, 1);
+		return SSSE3 = (registers[2] & 0x00000200) != 0;
+	}
+
+	bool CPUID::detectSSE4_1()
+	{
+		int registers[4];
+		cpuid(registers, 1);
+		return SSE4_1 = (registers[2] & 0x00080000) != 0;
+	}
+
+	int CPUID::detectCoreCount()
+	{
+		int cores = 0;
+
+		#if defined(_WIN32)
+			DWORD_PTR processAffinityMask = 1;
+			DWORD_PTR systemAffinityMask = 1;
+
+			GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask);
+
+			while(systemAffinityMask)
+			{
+				if(systemAffinityMask & 1)
+				{
+					cores++;
+				}
+
+				systemAffinityMask >>= 1;
+			}
+		#else
+			cores = sysconf(_SC_NPROCESSORS_ONLN);
+		#endif
+
+		if(cores < 1)  cores = 1;
+		if(cores > 16) cores = 16;
+
+		return cores;   // FIXME: Number of physical cores
+	}
+
+	int CPUID::detectAffinity()
+	{
+		int cores = 0;
+
+		#if defined(_WIN32)
+			DWORD_PTR processAffinityMask = 1;
+			DWORD_PTR systemAffinityMask = 1;
+
+			GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask);
+
+			while(processAffinityMask)
+			{
+				if(processAffinityMask & 1)
+				{
+					cores++;
+				}
+
+				processAffinityMask >>= 1;
+			}
+		#else
+			return detectCoreCount();   // FIXME: Assumes no affinity limitation
+		#endif
+
+		if(cores < 1)  cores = 1;
+		if(cores > 16) cores = 16;
+
+		return cores;
+	}
+
+	void CPUID::setFlushToZero(bool enable)
+	{
+		#if defined(_MSC_VER)
+			_controlfp(enable ? _DN_FLUSH : _DN_SAVE, _MCW_DN);
+		#else
+			// Unimplemented
+		#endif
+	}
+
+	void CPUID::setDenormalsAreZero(bool enable)
+	{
+		// Unimplemented
+	}
+}
diff --git a/src/System/CPUID.hpp b/src/System/CPUID.hpp
new file mode 100644
index 0000000..3c21cd7
--- /dev/null
+++ b/src/System/CPUID.hpp
@@ -0,0 +1,137 @@
+// 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(__i386__) && defined(_M_IX86)
+		#define __i386__ 1
+	#endif
+
+	#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/System/Configurator.cpp b/src/System/Configurator.cpp
new file mode 100644
index 0000000..ead1d28
--- /dev/null
+++ b/src/System/Configurator.cpp
@@ -0,0 +1,255 @@
+// 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 "Configurator.hpp"
+
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#if defined(__unix__)
+#include <unistd.h>
+#endif
+
+namespace sw
+{
+	Configurator::Configurator(string iniPath)
+	{
+		path = iniPath;
+
+		readFile();
+	}
+
+	Configurator::~Configurator()
+	{
+	}
+
+	bool Configurator::readFile()
+	{
+		#if defined(__unix__)
+			if(access(path.c_str(), R_OK) != 0)
+			{
+				return false;
+			}
+		#endif
+
+		fstream file(path.c_str(), ios::in);
+		if(file.fail()) return false;
+
+		string line;
+		string keyName;
+
+		while(getline(file, line))
+		{
+			if(line.length())
+			{
+				if(line[line.length() - 1] == '\r')
+				{
+					line = line.substr(0, line.length() - 1);
+				}
+
+				if(!isprint(line[0]))
+				{
+				//	printf("Failing on char %d\n", line[0]);
+					file.close();
+					return false;
+				}
+
+				string::size_type pLeft = line.find_first_of(";#[=");
+
+				if(pLeft != string::npos)
+				{
+					switch(line[pLeft])
+					{
+					case '[':
+						{
+							string::size_type pRight = line.find_last_of("]");
+
+							if(pRight != string::npos && pRight > pLeft)
+							{
+								keyName = line.substr(pLeft + 1, pRight - pLeft - 1);
+								addKeyName(keyName);
+							}
+						}
+						break;
+					case '=':
+						{
+							string valueName = line.substr(0, pLeft);
+							string value = line.substr(pLeft + 1);
+							addValue(keyName, valueName, value);
+						}
+						break;
+					case ';':
+					case '#':
+						// Ignore comments
+						break;
+					}
+				}
+			}
+		}
+
+		file.close();
+
+		if(names.size())
+		{
+			return true;
+		}
+
+		return false;
+	}
+
+	void Configurator::writeFile(std::string title)
+	{
+		#if defined(__unix__)
+			if(access(path.c_str(), W_OK) != 0)
+			{
+				return;
+			}
+		#endif
+
+		fstream file(path.c_str(), ios::out);
+		if(file.fail()) return;
+
+		file << "; " << title << endl << endl;
+
+		for(unsigned int keyID = 0; keyID < sections.size(); keyID++)
+		{
+			file << "[" << names[keyID] << "]" << endl;
+
+			for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); valueID++)
+			{
+				file << sections[keyID].names[valueID] << "=" << sections[keyID].values[valueID] << endl;
+			}
+
+			file << endl;
+		}
+
+		file.close();
+	}
+
+	int Configurator::findKey(string keyName) const
+	{
+		for(unsigned int keyID = 0; keyID < names.size(); keyID++)
+		{
+			if(names[keyID] == keyName)
+			{
+				return keyID;
+			}
+		}
+
+		return -1;
+	}
+
+	int Configurator::findValue(unsigned int keyID, string valueName) const
+	{
+		if(!sections.size() || keyID >= sections.size())
+		{
+			return -1;
+		}
+
+		for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); ++valueID)
+		{
+			if(sections[keyID].names[valueID] == valueName)
+			{
+				return valueID;
+			}
+		}
+
+		return -1;
+	}
+
+	unsigned int Configurator::addKeyName(string keyName)
+	{
+		names.resize(names.size() + 1, keyName);
+		sections.resize(sections.size() + 1);
+		return (unsigned int)names.size() - 1;
+	}
+
+	void Configurator::addValue(string const keyName, string const valueName, string const value)
+	{
+		int keyID = findKey(keyName);
+
+		if(keyID == -1)
+		{
+			keyID = addKeyName(keyName);
+		}
+
+		int valueID = findValue(keyID, valueName);
+
+		if(valueID == -1)
+		{
+			sections[keyID].names.resize(sections[keyID].names.size() + 1, valueName);
+			sections[keyID].values.resize(sections[keyID].values.size() + 1, value);
+		}
+		else
+		{
+			sections[keyID].values[valueID] = value;
+		}
+	}
+
+	string Configurator::getValue(string keyName, string valueName, string defaultValue) const
+	{
+		int keyID = findKey(keyName);
+		if(keyID == -1) return defaultValue;
+		int valueID = findValue((unsigned int)keyID, valueName);
+		if(valueID == -1) return defaultValue;
+
+		return sections[keyID].values[valueID];
+	}
+
+	int Configurator::getInteger(string keyName, string valueName, int defaultValue) const
+	{
+		char svalue[256];
+
+		sprintf(svalue, "%d", defaultValue);
+
+		return atoi(getValue(keyName, valueName, svalue).c_str());
+	}
+
+	bool Configurator::getBoolean(string keyName, string valueName, bool defaultValue) const
+	{
+		return getInteger(keyName, valueName, (int)defaultValue) != 0;
+	}
+
+	double Configurator::getFloat(string keyName, string valueName, double defaultValue) const
+	{
+		char svalue[256];
+
+		sprintf(svalue, "%f", defaultValue);
+
+		return atof(getValue(keyName, valueName, svalue).c_str());
+	}
+
+	unsigned int Configurator::getFormatted(string keyName, string valueName, char *format,
+											void *v1, void *v2, void *v3, void *v4,
+											void *v5, void *v6, void *v7, void *v8,
+											void *v9, void *v10, void *v11, void *v12,
+											void *v13, void *v14, void *v15, void *v16)
+	{
+		string value = getValue(keyName, valueName);
+
+		if(!value.length()) return false;
+
+		unsigned int nVals = sscanf(value.c_str(), format,
+									v1, v2, v3, v4, v5, v6, v7, v8,
+									v9, v10, v11, v12, v13, v14, v15, v16);
+
+		return nVals;
+	}
+}
diff --git a/src/System/Configurator.hpp b/src/System/Configurator.hpp
new file mode 100644
index 0000000..6fd930c
--- /dev/null
+++ b/src/System/Configurator.hpp
@@ -0,0 +1,66 @@
+// 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_Configurator_hpp
+#define sw_Configurator_hpp
+
+#include <string>
+#include <vector>
+
+#include <stdlib.h>
+
+namespace sw
+{
+	class Configurator
+	{
+	public:
+		Configurator(std::string iniPath = "");
+
+		~Configurator();
+
+		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 addValue(std::string sectionName, std::string valueName, std::string value);
+
+		void writeFile(std::string title = "Configuration File");
+
+	private:
+		bool readFile();
+
+		unsigned int addKeyName(std::string sectionName);
+		int findKey(std::string sectionName) const;
+		int findValue(unsigned int sectionID, std::string valueName) const;
+
+		std::string path;
+
+		struct Section
+		{
+			std::vector<std::string> names;
+			std::vector<std::string> values;
+		};
+
+		std::vector<Section> sections;
+		std::vector<std::string> names;
+	};
+}
+
+#endif   // sw_Configurator_hpp
diff --git a/src/System/Debug.cpp b/src/System/Debug.cpp
new file mode 100644
index 0000000..acf469e
--- /dev/null
+++ b/src/System/Debug.cpp
@@ -0,0 +1,39 @@
+// 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 "Debug.hpp"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+namespace sw
+{
+void trace(const char *format, ...)
+{
+	if(false)
+	{
+		FILE *file = fopen("debug.txt", "a");
+
+		if(file)
+		{
+			va_list vararg;
+			va_start(vararg, format);
+			vfprintf(file, format, vararg);
+			va_end(vararg);
+
+			fclose(file);
+		}
+	}
+}
+}
diff --git a/src/System/Debug.hpp b/src/System/Debug.hpp
new file mode 100644
index 0000000..9758c3b
--- /dev/null
+++ b/src/System/Debug.hpp
@@ -0,0 +1,58 @@
+// 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
+
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#include "DebugAndroid.hpp"
+#else
+
+#include <assert.h>
+#include <stdio.h>
+
+#undef min
+#undef max
+
+namespace sw
+{
+void trace(const char *format, ...);
+inline void trace() {}
+}
+
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+	#define TRACE(format, ...) sw::trace("[0x%0.8X]%s(" format ")\n", this, __FUNCTION__, ##__VA_ARGS__)
+#else
+	#define TRACE(...) ((void)0)
+#endif
+
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+	#define UNIMPLEMENTED(...) do { \
+		sw::trace("\t! Unimplemented: %s(%d): ", __FUNCTION__, __LINE__); \
+		sw::trace(__VA_ARGS__); \
+		sw::trace("\n"); \
+		ASSERT(false); \
+	} while(0)
+#else
+	#define UNIMPLEMENTED(...) ((void)0)
+#endif
+
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+	#define ASSERT(expression) {if(!(expression)) sw::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/System/DebugAndroid.cpp b/src/System/DebugAndroid.cpp
new file mode 100644
index 0000000..c511fc3
--- /dev/null
+++ b/src/System/DebugAndroid.cpp
@@ -0,0 +1,53 @@
+// 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 "DebugAndroid.hpp"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <cutils/properties.h>
+
+void AndroidEnterDebugger()
+{
+	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");
+	}
+#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);
+#endif
+}
diff --git a/src/System/DebugAndroid.hpp b/src/System/DebugAndroid.hpp
new file mode 100644
index 0000000..eced194
--- /dev/null
+++ b/src/System/DebugAndroid.hpp
@@ -0,0 +1,99 @@
+// 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 DebugAndroid_hpp
+#define DebugAndroid_hpp
+
+#if ANDROID_PLATFORM_SDK_VERSION < 27
+#include <cutils/log.h>
+#elif ANDROID_PLATFORM_SDK_VERSION >= 27
+#include <log/log.h>
+#else
+#error "ANDROID_PLATFORM_SDK_VERSION is not defined"
+#endif
+
+#include <cassert>
+
+// On Android Virtual Devices we heavily depend on logging, even in
+// production builds. We do this because AVDs are components of larger
+// systems, and may be configured in ways that are difficult to
+// reproduce locally. For example some system run tests against
+// third-party code that we cannot access.  Aborting (cf. assert) on
+// unimplemented functionality creates two problems. First, it produces
+// a service failure where none is needed. Second, it puts the
+// customer on the critical path for notifying us of a problem.
+// The alternative, skipping unimplemented functionality silently, is
+// arguably worse: neither the service provider nor the customer will
+// learn that unimplemented functionality may have compromised the test
+// results.
+// Logging invocations of unimplemented functionality is useful to both
+// service provider and the customer. The service provider can learn
+// that the functionality is needed. The customer learns that the test
+// results may be compromised.
+
+/**
+ * Enter the debugger with a memory fault iff debuggerd is set to capture this
+ * process. Otherwise return.
+ */
+void AndroidEnterDebugger();
+
+#define ASSERT(E) do { \
+		if (!(E)) { \
+			ALOGE("badness: assertion_failed %s in %s at %s:%d", #E,	\
+				  __FUNCTION__, __FILE__, __LINE__);					\
+			AndroidEnterDebugger();										\
+		}																\
+	} while(0)
+
+#undef assert
+#define assert(E) ASSERT(E)
+
+#define ERR(format, ...)												\
+	do {																\
+		ALOGE("badness: err %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+			  __LINE__, ##__VA_ARGS__);									\
+		AndroidEnterDebugger();											\
+	} while(0)
+
+#define FIXME(format, ...)												\
+	do {																\
+		ALOGE("badness: fixme %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+			  __LINE__, ##__VA_ARGS__);									\
+		AndroidEnterDebugger();											\
+	} while(0)
+
+// TODO: Handle __VA_ARGS__ (can be empty)
+#define UNIMPLEMENTED(...) do {						\
+		ALOGE("badness: unimplemented: %s %s:%d",	\
+			  __FUNCTION__, __FILE__, __LINE__);	\
+		AndroidEnterDebugger();						\
+	} while(0)
+
+#define UNREACHABLE(value) do {                                         \
+		ALOGE("badness: unreachable case reached: %s %s:%d. %s: %d", \
+			  __FUNCTION__, __FILE__, __LINE__, #value, value);			\
+		AndroidEnterDebugger();                                         \
+	} while(0)
+
+#ifndef NDEBUG
+	#define TRACE(format, ...)								   \
+		ALOGV("%s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+			  __LINE__, ##__VA_ARGS__)
+#else
+	#define TRACE(...) ((void)0)
+#endif
+
+void trace(const char *format, ...);
+
+#endif   // DebugAndroid_hpp
diff --git a/src/System/GrallocAndroid.cpp b/src/System/GrallocAndroid.cpp
new file mode 100644
index 0000000..c877e9933
--- /dev/null
+++ b/src/System/GrallocAndroid.cpp
@@ -0,0 +1,106 @@
+// 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 "Debug.hpp"
+
+#ifdef HAVE_GRALLOC1
+#include <sync/sync.h>
+#endif
+
+GrallocModule *GrallocModule::getInstance()
+{
+	static GrallocModule instance;
+	return &instance;
+}
+
+GrallocModule::GrallocModule()
+{
+	const hw_module_t *module = nullptr;
+	hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+
+	m_major_version = (module->module_api_version >> 8) & 0xff;
+	switch(m_major_version)
+	{
+	case 0:
+		m_module = reinterpret_cast<const gralloc_module_t*>(module);
+		break;
+	case 1:
+#ifdef HAVE_GRALLOC1
+		gralloc1_open(module, &m_gralloc1_device);
+		m_gralloc1_lock = (GRALLOC1_PFN_LOCK) m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_LOCK);
+		m_gralloc1_unlock = (GRALLOC1_PFN_UNLOCK)m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_UNLOCK);
+		break;
+#endif
+	default:
+		TRACE("unknown gralloc major version (%d)", m_major_version);
+		break;
+	}
+}
+
+int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
+{
+	switch(m_major_version)
+	{
+	case 0:
+		{
+			return m_module->lock(m_module, handle, usage, left, top, width, height, vaddr);
+		}
+	case 1:
+#ifdef HAVE_GRALLOC1
+		{
+			gralloc1_rect_t outRect{};
+			outRect.left = left;
+			outRect.top = top;
+			outRect.width = width;
+			outRect.height = height;
+			return m_gralloc1_lock(m_gralloc1_device, handle, usage, usage, &outRect, vaddr, -1);
+		}
+#endif
+	default:
+		{
+			TRACE("no gralloc module to lock");
+			return -1;
+		}
+	}
+}
+
+int GrallocModule::unlock(buffer_handle_t handle)
+{
+	switch(m_major_version)
+	{
+	case 0:
+		{
+			return m_module->unlock(m_module, handle);
+		}
+	case 1:
+#ifdef HAVE_GRALLOC1
+		{
+			int32_t fenceFd = -1;
+			int error = m_gralloc1_unlock(m_gralloc1_device, handle, &fenceFd);
+			if (!error)
+			{
+				sync_wait(fenceFd, -1);
+				close(fenceFd);
+			}
+			return error;
+		}
+#endif
+	default:
+		{
+			TRACE("no gralloc module to unlock");
+			return -1;
+		}
+	}
+}
diff --git a/src/System/GrallocAndroid.hpp b/src/System/GrallocAndroid.hpp
new file mode 100644
index 0000000..fe0b15a
--- /dev/null
+++ b/src/System/GrallocAndroid.hpp
@@ -0,0 +1,44 @@
+// 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 GRALLOC_ANDROID
+#define GRALLOC_ANDROID
+
+#include <hardware/gralloc.h>
+
+#ifdef HAVE_GRALLOC1
+#include <hardware/gralloc1.h>
+#endif
+
+#include <unistd.h> // for close()
+
+class GrallocModule
+{
+public:
+	static GrallocModule *getInstance();
+	int lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr);
+	int unlock(buffer_handle_t handle);
+
+private:
+	GrallocModule();
+	uint8_t m_major_version;
+	const gralloc_module_t *m_module;
+#ifdef HAVE_GRALLOC1
+	gralloc1_device_t *m_gralloc1_device = nullptr;
+	GRALLOC1_PFN_LOCK m_gralloc1_lock = nullptr;
+	GRALLOC1_PFN_UNLOCK m_gralloc1_unlock = nullptr;
+#endif
+};
+
+#endif  // GRALLOC_ANDROID
diff --git a/src/System/Half.cpp b/src/System/Half.cpp
new file mode 100644
index 0000000..cde8190
--- /dev/null
+++ b/src/System/Half.cpp
@@ -0,0 +1,102 @@
+// 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 "Half.hpp"
+
+namespace sw
+{
+	half::half(float fp32)
+	{
+		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(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;
+		}
+	}
+
+	half::operator float() const
+	{
+		unsigned int fp32i;
+
+		int s = (fp16i >> 15) & 0x00000001;
+		int e = (fp16i >> 10) & 0x0000001F;
+		int m =  fp16i        & 0x000003FF;
+
+		if(e == 0)
+		{
+			if(m == 0)
+			{
+				fp32i = s << 31;
+
+				return (float&)fp32i;
+			}
+			else
+			{
+				while(!(m & 0x00000400))
+				{
+					m <<= 1;
+					e -=  1;
+				}
+
+				e += 1;
+				m &= ~0x00000400;
+			}
+		}
+
+		e = e + (127 - 15);
+		m = m << 13;
+
+		fp32i = (s << 31) | (e << 23) | m;
+
+		return (float&)fp32i;
+	}
+
+	half &half::operator=(half h)
+	{
+		fp16i = h.fp16i;
+
+		return *this;
+	}
+
+
+	half &half::operator=(float f)
+	{
+		*this = half(f);
+
+		return *this;
+	}
+}
diff --git a/src/System/Half.hpp b/src/System/Half.hpp
new file mode 100644
index 0000000..f2d378e
--- /dev/null
+++ b/src/System/Half.hpp
@@ -0,0 +1,93 @@
+// 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:
+		half() = default;
+		explicit half(float f);
+
+		operator float() const;
+
+		half &operator=(half h);
+		half &operator=(float f);
+
+	private:
+		unsigned short fp16i;
+	};
+
+	inline half shortAsHalf(short s)
+	{
+		union
+		{
+			half h;
+			short s;
+		} hs;
+
+		hs.s = s;
+
+		return hs.h;
+	}
+
+	class RGB9E5
+	{
+		unsigned int R : 9;
+		unsigned int G : 9;
+		unsigned int B : 9;
+		unsigned int E : 5;
+
+	public:
+		void toRGB16F(half rgb[3]) const
+		{
+			constexpr int offset = 24;   // Exponent bias (15) + number of mantissa bits per component (9) = 24
+
+			const float factor = (1u << E) * (1.0f / (1 << offset));
+			rgb[0] = half(R * factor);
+			rgb[1] = half(G * factor);
+			rgb[2] = half(B * factor);
+		}
+	};
+
+	class R11G11B10F
+	{
+		unsigned int R : 11;
+		unsigned int G : 11;
+		unsigned int B : 10;
+
+		static inline half float11ToFloat16(unsigned short fp11)
+		{
+			return shortAsHalf(fp11 << 4);   // Sign bit 0
+		}
+
+		static inline half float10ToFloat16(unsigned short fp10)
+		{
+			return shortAsHalf(fp10 << 5);   // Sign bit 0
+		}
+
+	public:
+		void toRGB16F(half rgb[3]) const
+		{
+			rgb[0] = float11ToFloat16(R);
+			rgb[1] = float11ToFloat16(G);
+			rgb[2] = float10ToFloat16(B);
+		}
+	};
+}
+
+#endif   // sw_Half_hpp
diff --git a/src/System/Math.cpp b/src/System/Math.cpp
new file mode 100644
index 0000000..290d4ab
--- /dev/null
+++ b/src/System/Math.cpp
@@ -0,0 +1,49 @@
+// 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 "Math.hpp"
+
+namespace sw
+{
+	inline uint64_t FNV_1a(uint64_t hash, unsigned char data)
+	{
+		return (hash ^ data) * 1099511628211;
+	}
+
+	uint64_t FNV_1a(const unsigned char *data, int size)
+	{
+		int64_t hash = 0xCBF29CE484222325;
+
+		for(int i = 0; i < size; i++)
+		{
+			hash = FNV_1a(hash, data[i]);
+		}
+
+		return hash;
+	}
+
+	unsigned char sRGB8toLinear8(unsigned char value)
+	{
+		static unsigned char sRGBtoLinearTable[256] = { 255 };
+		if(sRGBtoLinearTable[0] == 255)
+		{
+			for(int i = 0; i < 256; i++)
+			{
+				sRGBtoLinearTable[i] = static_cast<unsigned char>(sw::sRGBtoLinear(static_cast<float>(i) / 255.0f) * 255.0f + 0.5f);
+			}
+		}
+
+		return sRGBtoLinearTable[value];
+	}
+}
diff --git a/src/System/Math.hpp b/src/System/Math.hpp
new file mode 100644
index 0000000..a35d2e0
--- /dev/null
+++ b/src/System/Math.hpp
@@ -0,0 +1,385 @@
+// 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 "Half.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;
+	}
+
+	template <typename destType, typename sourceType>
+	destType bitCast(const sourceType &source)
+	{
+		union
+		{
+			sourceType s;
+			destType d;
+		} sd;
+		sd.s = source;
+		return sd.d;
+	}
+
+	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 float minf = static_cast<float>(min);
+		static const unsigned int range = 0xFFFFFFFF >> (32 - n);
+
+		if(x > 0.0f)
+		{
+			if(x >= maxf)
+			{
+				return max;
+			}
+			else
+			{
+				return static_cast<int>(x + 0.5f);
+			}
+		}
+		else
+		{
+			if(x <= -minf)
+			{
+				return min;
+			}
+			else
+			{
+				return static_cast<int>(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
+	template<typename T>
+	inline T align(T value, unsigned int alignment)
+	{
+		return ((value + alignment - 1) / alignment) * alignment;
+	}
+
+	template<unsigned int alignment, typename T>
+	inline T align(T value)
+	{
+		return ((value + alignment - 1) / alignment) * alignment;
+	}
+
+	inline int clampToSignedInt(unsigned int x)
+	{
+		return static_cast<int>(min(x, 0x7FFFFFFFu));
+	}
+}
+
+#endif   // sw_Math_hpp
diff --git a/src/System/Memory.cpp b/src/System/Memory.cpp
new file mode 100644
index 0000000..45fef40
--- /dev/null
+++ b/src/System/Memory.cpp
@@ -0,0 +1,262 @@
+// 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 "Memory.hpp"
+
+#include "Types.hpp"
+#include "Debug.hpp"
+
+#if defined(_WIN32)
+	#ifndef WIN32_LEAN_AND_MEAN
+		#define WIN32_LEAN_AND_MEAN
+	#endif
+	#include <windows.h>
+	#include <intrin.h>
+#else
+	#include <errno.h>
+	#include <sys/mman.h>
+	#include <stdlib.h>
+	#include <unistd.h>
+#endif
+
+#include <memory.h>
+
+#undef allocate
+#undef deallocate
+
+#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined (_M_X64)) && !defined(__x86__)
+#define __x86__
+#endif
+
+namespace sw
+{
+namespace
+{
+struct Allocation
+{
+//	size_t bytes;
+	unsigned char *block;
+};
+
+void *allocateRaw(size_t bytes, size_t alignment)
+{
+	ASSERT((alignment & (alignment - 1)) == 0);   // Power of 2 alignment.
+
+	#if defined(LINUX_ENABLE_NAMED_MMAP)
+		void *allocation;
+		int result = posix_memalign(&allocation, alignment, bytes);
+		if(result != 0)
+		{
+			errno = result;
+			allocation = nullptr;
+		}
+		return allocation;
+	#else
+		unsigned char *block = new unsigned char[bytes + sizeof(Allocation) + alignment];
+		unsigned char *aligned = nullptr;
+
+		if(block)
+		{
+			aligned = (unsigned char*)((uintptr_t)(block + sizeof(Allocation) + alignment - 1) & -(intptr_t)alignment);
+			Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation));
+
+		//	allocation->bytes = bytes;
+			allocation->block = block;
+		}
+
+		return aligned;
+	#endif
+}
+
+#if defined(LINUX_ENABLE_NAMED_MMAP)
+// Create a file descriptor for anonymous memory with the given
+// name. Returns -1 on failure.
+// TODO: remove once libc wrapper exists.
+int memfd_create(const char* name, unsigned int flags)
+{
+	#if __aarch64__
+	#define __NR_memfd_create 279
+	#elif __arm__
+	#define __NR_memfd_create 279
+	#elif __powerpc64__
+	#define __NR_memfd_create 360
+	#elif __i386__
+	#define __NR_memfd_create 356
+	#elif __x86_64__
+	#define __NR_memfd_create 319
+	#endif /* __NR_memfd_create__ */
+	#ifdef __NR_memfd_create
+		// In the event of no system call this returns -1 with errno set
+		// as ENOSYS.
+		return syscall(__NR_memfd_create, name, flags);
+	#else
+		return -1;
+	#endif
+}
+
+// Returns a file descriptor for use with an anonymous mmap, if
+// memfd_create fails, -1 is returned. Note, the mappings should be
+// MAP_PRIVATE so that underlying pages aren't shared.
+int anonymousFd()
+{
+	static int fd = memfd_create("SwiftShader JIT", 0);
+	return fd;
+}
+
+// Ensure there is enough space in the "anonymous" fd for length.
+void ensureAnonFileSize(int anonFd, size_t length)
+{
+	static size_t fileSize = 0;
+	if(length > fileSize)
+	{
+		ftruncate(anonFd, length);
+		fileSize = length;
+	}
+}
+#endif  // defined(LINUX_ENABLE_NAMED_MMAP)
+
+}  // anonymous namespace
+
+size_t memoryPageSize()
+{
+	static int pageSize = 0;
+
+	if(pageSize == 0)
+	{
+		#if defined(_WIN32)
+			SYSTEM_INFO systemInfo;
+			GetSystemInfo(&systemInfo);
+			pageSize = systemInfo.dwPageSize;
+		#else
+			pageSize = sysconf(_SC_PAGESIZE);
+		#endif
+	}
+
+	return pageSize;
+}
+
+void *allocate(size_t bytes, size_t alignment)
+{
+	void *memory = allocateRaw(bytes, alignment);
+
+	if(memory)
+	{
+		memset(memory, 0, bytes);
+	}
+
+	return memory;
+}
+
+void deallocate(void *memory)
+{
+	#if defined(LINUX_ENABLE_NAMED_MMAP)
+		free(memory);
+	#else
+		if(memory)
+		{
+			unsigned char *aligned = (unsigned char*)memory;
+			Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation));
+
+			delete[] allocation->block;
+		}
+	#endif
+}
+
+void *allocateExecutable(size_t bytes)
+{
+	size_t pageSize = memoryPageSize();
+	size_t length = (bytes + pageSize - 1) & ~(pageSize - 1);
+	void *mapping;
+
+	#if defined(LINUX_ENABLE_NAMED_MMAP)
+		// Try to name the memory region for the executable code,
+		// to aid profilers.
+		int anonFd = anonymousFd();
+		if(anonFd == -1)
+		{
+			mapping = mmap(nullptr, length, PROT_READ | PROT_WRITE,
+			               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+		}
+		else
+		{
+			ensureAnonFileSize(anonFd, length);
+			mapping = mmap(nullptr, length, PROT_READ | PROT_WRITE,
+			               MAP_PRIVATE, anonFd, 0);
+		}
+
+		if(mapping == MAP_FAILED)
+		{
+			mapping = nullptr;
+		}
+	#else
+		mapping = allocate(length, pageSize);
+	#endif
+
+	return mapping;
+}
+
+void markExecutable(void *memory, size_t bytes)
+{
+	#if defined(_WIN32)
+		unsigned long oldProtection;
+		VirtualProtect(memory, bytes, PAGE_EXECUTE_READ, &oldProtection);
+	#else
+		mprotect(memory, bytes, PROT_READ | PROT_EXEC);
+	#endif
+}
+
+void deallocateExecutable(void *memory, size_t bytes)
+{
+	#if defined(_WIN32)
+		unsigned long oldProtection;
+		VirtualProtect(memory, bytes, PAGE_READWRITE, &oldProtection);
+		deallocate(memory);
+	#elif defined(LINUX_ENABLE_NAMED_MMAP)
+		size_t pageSize = memoryPageSize();
+		size_t length = (bytes + pageSize - 1) & ~(pageSize - 1);
+		munmap(memory, length);
+	#else
+		mprotect(memory, bytes, PROT_READ | PROT_WRITE);
+		deallocate(memory);
+	#endif
+}
+
+void clear(uint16_t *memory, uint16_t element, size_t count)
+{
+	#if defined(_MSC_VER) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+		__stosw(memory, element, count);
+	#elif defined(__GNUC__) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+		__asm__("rep stosw" : : "D"(memory), "a"(element), "c"(count));
+	#else
+		for(size_t i = 0; i < count; i++)
+		{
+			memory[i] = element;
+		}
+	#endif
+}
+
+void clear(uint32_t *memory, uint32_t element, size_t count)
+{
+	#if defined(_MSC_VER) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+		__stosd((unsigned long*)memory, element, count);
+	#elif defined(__GNUC__) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+		__asm__("rep stosl" : : "D"(memory), "a"(element), "c"(count));
+	#else
+		for(size_t i = 0; i < count; i++)
+		{
+			memory[i] = element;
+		}
+	#endif
+}
+}
diff --git a/src/System/Memory.hpp b/src/System/Memory.hpp
new file mode 100644
index 0000000..8d3a159
--- /dev/null
+++ b/src/System/Memory.hpp
@@ -0,0 +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.
+
+#ifndef Memory_hpp
+#define Memory_hpp
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace sw
+{
+size_t memoryPageSize();
+
+void *allocate(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);
+
+void clear(uint16_t *memory, uint16_t element, size_t count);
+void clear(uint32_t *memory, uint32_t element, size_t count);
+}
+
+#endif   // Memory_hpp
diff --git a/src/System/MutexLock.hpp b/src/System/MutexLock.hpp
new file mode 100644
index 0000000..65e9fa4
--- /dev/null
+++ b/src/System/MutexLock.hpp
@@ -0,0 +1,199 @@
+// 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"
+
+#if defined(__linux__)
+// Use a pthread mutex on Linux. Since many processes may use SwiftShader
+// at the same time it's best to just have the scheduler overhead.
+#include <pthread.h>
+
+namespace sw
+{
+	class MutexLock
+	{
+	public:
+		MutexLock()
+		{
+			pthread_mutex_init(&mutex, NULL);
+		}
+
+		~MutexLock()
+		{
+			pthread_mutex_destroy(&mutex);
+		}
+
+		bool attemptLock()
+		{
+			return pthread_mutex_trylock(&mutex) == 0;
+		}
+
+		void lock()
+		{
+			pthread_mutex_lock(&mutex);
+		}
+
+		void unlock()
+		{
+			pthread_mutex_unlock(&mutex);
+		}
+
+	private:
+		pthread_mutex_t mutex;
+	};
+}
+
+#else   // !__linux__
+
+#include <atomic>
+
+namespace sw
+{
+	class BackoffLock
+	{
+	public:
+		BackoffLock()
+		{
+			mutex = 0;
+		}
+
+		bool attemptLock()
+		{
+			if(!isLocked())
+			{
+				if(mutex.exchange(true) == false)
+				{
+					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.store(false, std::memory_order_release);
+		}
+
+		bool isLocked()
+		{
+			return mutex.load(std::memory_order_acquire);
+		}
+
+	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];
+			std::atomic<bool> mutex;
+			volatile int padding2[15];
+		};
+	};
+
+	using MutexLock = BackoffLock;
+}
+
+#endif   // !__ANDROID__
+
+class LockGuard
+{
+public:
+	explicit LockGuard(sw::MutexLock &mutex) : mutex(&mutex)
+	{
+		mutex.lock();
+	}
+
+	explicit LockGuard(sw::MutexLock *mutex) : mutex(mutex)
+	{
+		if (mutex) mutex->lock();
+	}
+
+	~LockGuard()
+	{
+		if (mutex) mutex->unlock();
+	}
+
+protected:
+	sw::MutexLock *mutex;
+};
+
+#endif   // sw_MutexLock_hpp
diff --git a/src/System/Resource.cpp b/src/System/Resource.cpp
new file mode 100644
index 0000000..3a63810
--- /dev/null
+++ b/src/System/Resource.cpp
@@ -0,0 +1,184 @@
+// 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 "Resource.hpp"
+
+#include "Memory.hpp"
+#include "Debug.hpp"
+
+namespace sw
+{
+	Resource::Resource(size_t bytes) : size(bytes)
+	{
+		blocked = 0;
+
+		accessor = PUBLIC;
+		count = 0;
+		orphaned = false;
+
+		buffer = allocate(bytes);
+	}
+
+	Resource::~Resource()
+	{
+		deallocate(buffer);
+	}
+
+	void *Resource::lock(Accessor claimer)
+	{
+		criticalSection.lock();
+
+		while(count > 0 && accessor != claimer)
+		{
+			blocked++;
+			criticalSection.unlock();
+
+			unblock.wait();
+
+			criticalSection.lock();
+			blocked--;
+		}
+
+		accessor = claimer;
+		count++;
+
+		criticalSection.unlock();
+
+		return buffer;
+	}
+
+	void *Resource::lock(Accessor relinquisher, Accessor claimer)
+	{
+		criticalSection.lock();
+
+		// Release
+		while(count > 0 && accessor == relinquisher)
+		{
+			count--;
+
+			if(count == 0)
+			{
+				if(blocked)
+				{
+					unblock.signal();
+				}
+				else if(orphaned)
+				{
+					criticalSection.unlock();
+
+					delete this;
+
+					return 0;
+				}
+			}
+		}
+
+		// Acquire
+		while(count > 0 && accessor != claimer)
+		{
+			blocked++;
+			criticalSection.unlock();
+
+			unblock.wait();
+
+			criticalSection.lock();
+			blocked--;
+		}
+
+		accessor = claimer;
+		count++;
+
+		criticalSection.unlock();
+
+		return buffer;
+	}
+
+	void Resource::unlock()
+	{
+		criticalSection.lock();
+		ASSERT(count > 0);
+
+		count--;
+
+		if(count == 0)
+		{
+			if(blocked)
+			{
+				unblock.signal();
+			}
+			else if(orphaned)
+			{
+				criticalSection.unlock();
+
+				delete this;
+
+				return;
+			}
+		}
+
+		criticalSection.unlock();
+	}
+
+	void Resource::unlock(Accessor relinquisher)
+	{
+		criticalSection.lock();
+		ASSERT(count > 0);
+
+		while(count > 0 && accessor == relinquisher)
+		{
+			count--;
+
+			if(count == 0)
+			{
+				if(blocked)
+				{
+					unblock.signal();
+				}
+				else if(orphaned)
+				{
+					criticalSection.unlock();
+
+					delete this;
+
+					return;
+				}
+			}
+		}
+
+		criticalSection.unlock();
+	}
+
+	void Resource::destruct()
+	{
+		criticalSection.lock();
+
+		if(count == 0 && !blocked)
+		{
+			criticalSection.unlock();
+
+			delete this;
+
+			return;
+		}
+
+		orphaned = true;
+
+		criticalSection.unlock();
+	}
+
+	const void *Resource::data() const
+	{
+		return buffer;
+	}
+}
diff --git a/src/System/Resource.hpp b/src/System/Resource.hpp
new file mode 100644
index 0000000..0acfa48
--- /dev/null
+++ b/src/System/Resource.hpp
@@ -0,0 +1,60 @@
+// 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
+		EXCLUSIVE
+	};
+
+	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
+
+		MutexLock criticalSection;
+		Event unblock;
+		volatile int blocked;
+
+		volatile Accessor accessor;
+		volatile int count;
+		bool orphaned;
+
+		void *buffer;
+	};
+}
+
+#endif   // sw_Resource_hpp
diff --git a/src/System/SharedLibrary.hpp b/src/System/SharedLibrary.hpp
new file mode 100644
index 0000000..8a8c3a1
--- /dev/null
+++ b/src/System/SharedLibrary.hpp
@@ -0,0 +1,171 @@
+// 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
+
+#include <string>
+
+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 std::string &libraryDirectory, const char *(&names)[n], const char *mustContainSymbol = nullptr)
+{
+	for(const char *libraryName : names)
+	{
+		std::string libraryPath = libraryDirectory + libraryName;
+		void *library = getLibraryHandle(libraryPath.c_str());
+
+		if(library)
+		{
+			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+			{
+				return library;
+			}
+
+			freeLibrary(library);
+		}
+	}
+
+	for(const char *libraryName : names)
+	{
+		std::string libraryPath = libraryDirectory + libraryName;
+		void *library = loadLibrary(libraryPath.c_str());
+
+		if(library)
+		{
+			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+			{
+				return library;
+			}
+
+			freeLibrary(library);
+		}
+	}
+
+	return nullptr;
+}
+
+#if defined(_WIN32)
+	inline void *loadLibrary(const char *path)
+	{
+		return (void*)LoadLibrary(path);
+	}
+
+	inline void *getLibraryHandle(const char *path)
+	{
+		HMODULE module = NULL;
+		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);
+	}
+
+	inline std::string getModuleDirectory()
+	{
+		static int dummy_symbol = 0;
+
+		HMODULE module = NULL;
+		GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&dummy_symbol, &module);
+
+		char filename[1024];
+		if(module && (GetModuleFileName(module, filename, sizeof(filename)) != 0))
+		{
+			std::string directory(filename);
+			return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
+		}
+		else
+		{
+			return "";
+		}
+	}
+#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 nullptr;
+		#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;
+	}
+
+	inline std::string getModuleDirectory()
+	{
+		static int dummy_symbol = 0;
+
+		Dl_info dl_info;
+		if(dladdr(&dummy_symbol, &dl_info) != 0)
+		{
+			std::string directory(dl_info.dli_fname);
+			return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
+		}
+		else
+		{
+			return "";
+		}
+	}
+#endif
+
+#endif   // SharedLibrary_hpp
diff --git a/src/System/Socket.cpp b/src/System/Socket.cpp
new file mode 100644
index 0000000..b098031
--- /dev/null
+++ b/src/System/Socket.cpp
@@ -0,0 +1,110 @@
+// 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>
+	#include <sys/select.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/System/Socket.hpp b/src/System/Socket.hpp
new file mode 100644
index 0000000..b6b9abd
--- /dev/null
+++ b/src/System/Socket.hpp
@@ -0,0 +1,49 @@
+// 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/System/Thread.cpp b/src/System/Thread.cpp
new file mode 100644
index 0000000..df9a0b7
--- /dev/null
+++ b/src/System/Thread.cpp
@@ -0,0 +1,91 @@
+// 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 "Thread.hpp"
+
+namespace sw
+{
+	Thread::Thread(void (*threadFunction)(void *parameters), void *parameters)
+	{
+		Event init;
+		Entry entry = {threadFunction, parameters, &init};
+
+		#if defined(_WIN32)
+			handle = CreateThread(NULL, 1024 * 1024, startFunction, &entry, 0, NULL);
+		#else
+			pthread_create(&handle, NULL, startFunction, &entry);
+		#endif
+
+		init.wait();
+	}
+
+	Thread::~Thread()
+	{
+		join();   // Make threads exit before deleting them to not block here
+	}
+
+	void Thread::join()
+	{
+		if(!hasJoined)
+		{
+			#if defined(_WIN32)
+				WaitForSingleObject(handle, INFINITE);
+				CloseHandle(handle);
+			#else
+				pthread_join(handle, NULL);
+			#endif
+
+			hasJoined = true;
+		}
+	}
+
+	#if defined(_WIN32)
+		unsigned long __stdcall Thread::startFunction(void *parameters)
+		{
+			Entry entry = *(Entry*)parameters;
+			entry.init->signal();
+			entry.threadFunction(entry.threadParameters);
+			return 0;
+		}
+	#else
+		void *Thread::startFunction(void *parameters)
+		{
+			Entry entry = *(Entry*)parameters;
+			entry.init->signal();
+			entry.threadFunction(entry.threadParameters);
+			return nullptr;
+		}
+	#endif
+
+	Event::Event()
+	{
+		#if defined(_WIN32)
+			handle = CreateEvent(NULL, FALSE, FALSE, NULL);
+		#else
+			pthread_cond_init(&handle, NULL);
+			pthread_mutex_init(&mutex, NULL);
+			signaled = false;
+		#endif
+	}
+
+	Event::~Event()
+	{
+		#if defined(_WIN32)
+			CloseHandle(handle);
+		#else
+			pthread_cond_destroy(&handle);
+			pthread_mutex_destroy(&mutex);
+		#endif
+	}
+}
diff --git a/src/System/Thread.hpp b/src/System/Thread.hpp
new file mode 100644
index 0000000..b8280f1
--- /dev/null
+++ b/src/System/Thread.hpp
@@ -0,0 +1,338 @@
+// 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 (pthread_key_t)(~0)
+#endif
+
+#include <stdlib.h>
+
+#if defined(__clang__)
+#if __has_include(<atomic>) // clang has an explicit check for the availability of atomic
+#define USE_STD_ATOMIC 1
+#endif
+// atomic is available in C++11 or newer, and in Visual Studio 2012 or newer
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1700)) || (__cplusplus >= 201103L)
+#define USE_STD_ATOMIC 1
+#endif
+
+#if USE_STD_ATOMIC
+#include <atomic>
+#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(void (*destructor)(void *storage) = free);
+		static void freeLocalStorageKey(LocalStorageKey key);
+		static void *allocateLocalStorage(LocalStorageKey key, size_t size);
+		static void *getLocalStorage(LocalStorageKey key);
+		static void freeLocalStorage(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
+
+		bool hasJoined = false;
+	};
+
+	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);
+	int atomicExchange(int volatile *target, int value);
+	#endif
+
+	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(void (*destructor)(void *storage))
+	{
+		#if defined(_WIN32)
+			return TlsAlloc();
+		#else
+			LocalStorageKey key;
+			pthread_key_create(&key, destructor);
+			return key;
+		#endif
+	}
+
+	inline void Thread::freeLocalStorageKey(LocalStorageKey key)
+	{
+		#if defined(_WIN32)
+			TlsFree(key);
+		#else
+			pthread_key_delete(key);   // Using an invalid key is an error but not undefined behavior.
+		#endif
+	}
+
+	inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size)
+	{
+		if(key == TLS_OUT_OF_INDEXES)
+		{
+			return nullptr;
+		}
+
+		freeLocalStorage(key);
+
+		void *storage = malloc(size);
+
+		#if defined(_WIN32)
+			TlsSetValue(key, storage);
+		#else
+			pthread_setspecific(key, storage);
+		#endif
+
+		return storage;
+	}
+
+	inline void *Thread::getLocalStorage(LocalStorageKey key)
+	{
+		#if defined(_WIN32)
+			return TlsGetValue(key);
+		#else
+			if(key == TLS_OUT_OF_INDEXES)   // Avoid undefined behavior.
+			{
+				return nullptr;
+			}
+
+			return pthread_getspecific(key);
+		#endif
+	}
+
+	inline void Thread::freeLocalStorage(LocalStorageKey key)
+	{
+		free(getLocalStorage(key));
+
+		#if defined(_WIN32)
+			TlsSetValue(key, nullptr);
+		#else
+			pthread_setspecific(key, nullptr);
+		#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 %x0,(%x1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );
+			return ret;
+		#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 %x0,(%x1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );
+			return ret;
+		#endif
+	}
+	#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(_WIN32)
+			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
+	}
+
+	#if USE_STD_ATOMIC
+		class AtomicInt
+		{
+		public:
+			AtomicInt() : ai() {}
+			AtomicInt(int i) : ai(i) {}
+
+			inline operator int() const { return ai.load(std::memory_order_acquire); }
+			inline void operator=(const AtomicInt& i) { ai.store(i.ai.load(std::memory_order_acquire), std::memory_order_release); }
+			inline void operator=(int i) { ai.store(i, std::memory_order_release); }
+			inline void operator--() { ai.fetch_sub(1, std::memory_order_acq_rel); }
+			inline void operator++() { ai.fetch_add(1, std::memory_order_acq_rel); }
+			inline int operator--(int) { return ai.fetch_sub(1, std::memory_order_acq_rel) - 1; }
+			inline int operator++(int) { return ai.fetch_add(1, std::memory_order_acq_rel) + 1; }
+			inline void operator-=(int i) { ai.fetch_sub(i, std::memory_order_acq_rel); }
+			inline void operator+=(int i) { ai.fetch_add(i, std::memory_order_acq_rel); }
+		private:
+			std::atomic<int> ai;
+		};
+	#else
+		class AtomicInt
+		{
+		public:
+			AtomicInt() {}
+			AtomicInt(int i) : vi(i) {}
+
+			inline operator int() const { return vi; } // Note: this isn't a guaranteed atomic operation
+			inline void operator=(const AtomicInt& i) { sw::atomicExchange(&vi, i.vi); }
+			inline void operator=(int i) { sw::atomicExchange(&vi, i); }
+			inline void operator--() { sw::atomicDecrement(&vi); }
+			inline void operator++() { sw::atomicIncrement(&vi); }
+			inline int operator--(int) { return sw::atomicDecrement(&vi); }
+			inline int operator++(int) { return sw::atomicIncrement(&vi); }
+			inline void operator-=(int i) { sw::atomicAdd(&vi, -i); }
+			inline void operator+=(int i) { sw::atomicAdd(&vi, i); }
+		private:
+			volatile int vi;
+		};
+	#endif
+}
+
+#endif   // sw_Thread_hpp
diff --git a/src/System/Timer.cpp b/src/System/Timer.cpp
new file mode 100644
index 0000000..8ff2cf3
--- /dev/null
+++ b/src/System/Timer.cpp
@@ -0,0 +1,95 @@
+// 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 "Timer.hpp"
+
+#if !defined(__i386__) && defined(_M_IX86)
+	#define __i386__ 1
+#endif
+
+#if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
+	#define __x86_64__ 1
+#endif
+
+#if defined(_WIN32)
+	#ifndef WIN32_LEAN_AND_MEAN
+		#define WIN32_LEAN_AND_MEAN
+	#endif
+	#include <windows.h>
+	#include <intrin.h>
+#else
+	#include <sys/time.h>
+	#if defined(__i386__) || defined(__x86_64__)
+		#include <x86intrin.h>
+	#endif
+#endif
+
+namespace sw
+{
+	Timer::Timer()
+	{
+	}
+
+	Timer::~Timer()
+	{
+	}
+
+	double Timer::seconds()
+	{
+		#if defined(_WIN32)
+			return (double)counter() / (double)frequency();
+		#else
+			timeval t;
+			gettimeofday(&t, 0);
+			return (double)t.tv_sec + (double)t.tv_usec * 1.0e-6;
+		#endif
+	}
+
+	int64_t Timer::ticks()
+	{
+		#if defined(_WIN32)
+			return __rdtsc();
+		#elif defined(__i386__) || defined(__x86_64__)
+			int64_t tsc;
+			__asm volatile("rdtsc": "=A" (tsc));
+			return tsc;
+		#else
+			return 0;
+		#endif
+	}
+
+	int64_t Timer::counter()
+	{
+		#if defined(_WIN32)
+			int64_t counter;
+			QueryPerformanceCounter((LARGE_INTEGER*)&counter);
+			return counter;
+		#else
+			timeval t;
+			gettimeofday(&t, 0);
+			return t.tv_sec * 1000000 + t.tv_usec;
+		#endif
+	}
+
+	int64_t Timer::frequency()
+	{
+		#if defined(_WIN32)
+			int64_t frequency;
+			QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
+			return frequency;
+		#else
+			return 1000000;   // gettimeofday uses microsecond resolution
+		#endif
+	}
+}
diff --git a/src/System/Timer.hpp b/src/System/Timer.hpp
new file mode 100644
index 0000000..977c877
--- /dev/null
+++ b/src/System/Timer.hpp
@@ -0,0 +1,37 @@
+// 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/System/Types.hpp b/src/System/Types.hpp
new file mode 100644
index 0000000..cd08ed5
--- /dev/null
+++ b/src/System/Types.hpp
@@ -0,0 +1,157 @@
+// 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_Types_hpp
+#define sw_Types_hpp
+
+#include <limits>
+#include <type_traits>
+
+// GCC warns against bitfields not fitting the entire range of an enum with a fixed underlying type of unsigned int, which gets promoted to an error with -Werror and cannot be suppressed.
+// However, GCC already defaults to using unsigned int as the underlying type of an unscoped enum without a fixed underlying type. So we can just omit it.
+#if defined(__GNUC__) && !defined(__clang__)
+namespace {enum E {}; static_assert(!std::numeric_limits<std::underlying_type<E>::type>::is_signed, "expected unscoped enum whose underlying type is not fixed to be unsigned");}
+#define ENUM_UNDERLYING_TYPE_UNSIGNED_INT
+#else
+#define ENUM_UNDERLYING_TYPE_UNSIGNED_INT : unsigned int
+#endif
+
+#if defined(_MSC_VER)
+	typedef signed __int8 int8_t;
+	typedef signed __int16 int16_t;
+	typedef signed __int32 int32_t;
+	typedef signed __int64 int64_t;
+	typedef unsigned __int8 uint8_t;
+	typedef unsigned __int16 uint16_t;
+	typedef unsigned __int32 uint32_t;
+	typedef unsigned __int64 uint64_t;
+	#define ALIGN(bytes, type) __declspec(align(bytes)) type
+#else
+	#include <stdint.h>
+	#define ALIGN(bytes, type) type __attribute__((aligned(bytes)))
+#endif
+
+namespace sw
+{
+	typedef ALIGN(1, uint8_t) byte;
+	typedef ALIGN(2, uint16_t) word;
+	typedef ALIGN(4, uint32_t) dword;
+	typedef ALIGN(8, uint64_t) qword;
+	typedef ALIGN(16, uint64_t) qword2[2];
+	typedef ALIGN(4, uint8_t) byte4[4];
+	typedef ALIGN(8, uint8_t) byte8[8];
+	typedef ALIGN(16, uint8_t) byte16[16];
+	typedef ALIGN(8, uint16_t) word4[4];
+	typedef ALIGN(8, uint32_t) dword2[2];
+	typedef ALIGN(16, uint32_t) dword4[4];
+	typedef ALIGN(16, uint64_t) xword[2];
+
+	typedef ALIGN(1, int8_t) sbyte;
+	typedef ALIGN(4, int8_t) sbyte4[4];
+	typedef ALIGN(8, int8_t) sbyte8[8];
+	typedef ALIGN(16, int8_t) sbyte16[16];
+	typedef ALIGN(8, short) short4[4];
+	typedef ALIGN(8, unsigned short) ushort4[4];
+	typedef ALIGN(16, short) short8[8];
+	typedef ALIGN(16, unsigned short) ushort8[8];
+	typedef ALIGN(8, int) int2[2];
+	typedef ALIGN(8, unsigned int) uint2[2];
+	typedef ALIGN(16, unsigned int) uint4[4];
+
+	typedef ALIGN(8, float) float2[2];
+
+	ALIGN(16, struct int4
+	{
+		int x;
+		int y;
+		int z;
+		int w;
+
+		int &operator[](int i)
+		{
+			return (&x)[i];
+		}
+
+		const int &operator[](int i) const
+		{
+			return (&x)[i];
+		}
+
+		bool operator!=(const int4 &rhs)
+		{
+			return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w;
+		}
+
+		bool operator==(const int4 &rhs)
+		{
+			return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
+		}
+	});
+
+	ALIGN(16, struct float4
+	{
+		float x;
+		float y;
+		float z;
+		float w;
+
+		float &operator[](int i)
+		{
+			return (&x)[i];
+		}
+
+		const float &operator[](int i) const
+		{
+			return (&x)[i];
+		}
+
+		bool operator!=(const float4 &rhs)
+		{
+			return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w;
+		}
+
+		bool operator==(const float4 &rhs)
+		{
+			return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
+		}
+	});
+
+	inline float4 vector(float x, float y, float z, float w)
+	{
+		float4 v;
+
+		v.x = x;
+		v.y = y;
+		v.z = z;
+		v.w = w;
+
+		return v;
+	}
+
+	inline float4 replicate(float f)
+	{
+		float4 v;
+
+		v.x = f;
+		v.y = f;
+		v.z = f;
+		v.w = f;
+
+		return v;
+	}
+
+	#define OFFSET(s,m) (int)(size_t)&reinterpret_cast<const volatile char&>((((s*)0)->m))
+}
+
+#endif   // sw_Types_hpp
diff --git a/src/System/Version.h b/src/System/Version.h
new file mode 100644
index 0000000..72bd15d
--- /dev/null
+++ b/src/System/Version.h
@@ -0,0 +1,24 @@
+// 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.
+
+#define MAJOR_VERSION 4
+#define MINOR_VERSION 1
+#define BUILD_VERSION 0
+#define BUILD_REVISION 2
+
+#define STRINGIFY(x) #x
+#define MACRO_STRINGIFY(x) STRINGIFY(x)
+
+#define REVISION_STRING MACRO_STRINGIFY(BUILD_REVISION)
+#define VERSION_STRING MACRO_STRINGIFY(MAJOR_VERSION) "." MACRO_STRINGIFY(MINOR_VERSION) "." MACRO_STRINGIFY(BUILD_VERSION) "." MACRO_STRINGIFY(BUILD_REVISION)