// 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 <algorithm>
#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)
	{
		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)
	{
		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;
	}

	GLint Program::getFragDataLocation(const GLchar *name)
	{
		if(name && linked)
		{
			std::string baseName(name);
			unsigned int subscript = GL_INVALID_INDEX;
			baseName = ParseUniformName(baseName, &subscript);
			for(auto const &input : fragmentShader->varyings)
			{
				if(input.name == baseName)
				{
					int rowCount = VariableRowCount(input.type);
					int colCount = VariableColumnCount(input.type);
					return (subscript == GL_INVALID_INDEX) ? input.reg : input.reg + (rowCount > 1 ? colCount * subscript : subscript);
				}
			}
		}

		return -1;
	}

	void Program::bindAttributeLocation(GLuint index, const char *name)
	{
		attributeBinding[name] = index;
	}

	GLint Program::getAttributeLocation(const char *name)
	{
		if(name)
		{
			std::string strName(name);
			for(auto const &it : linkedAttribute)
			{
				if(it.name == strName)
				{
					return getAttributeBinding(it);
				}
			}
		}

		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)
	{
		GLint 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;
	}

	bool Program::isUniformDefined(const std::string &name) const
	{
		unsigned int 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 unsigned int index = uniformIndex[location].index;
			if((uniformIndex[location].name == baseName) && ((index == GL_INVALID_INDEX) ||
			   ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) ||
			    (subscript == GL_INVALID_INDEX))))
			{
				return true;
			}
		}

		return false;
	}

	GLint Program::getUniformLocation(const std::string &name) const
	{
		unsigned int 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 unsigned int index = uniformIndex[location].index;
			if((index != GL_INVALID_INDEX) && (uniformIndex[location].name == baseName) &&
			   ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) ||
			    (subscript == GL_INVALID_INDEX)))
			{
				return (GLint)location;
			}
		}

		return -1;
	}

	GLuint Program::getUniformIndex(const std::string &name) const
	{
		unsigned int 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
	{
		unsigned int 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)
	{
		if(uniformBlockIndex >= getActiveUniformBlockCount())
		{
			return error(GL_INVALID_VALUE);
		}

		uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
	}

	GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
	{
		if(uniformBlockIndex >= getActiveUniformBlockCount())
		{
			return error(GL_INVALID_VALUE, GL_INVALID_INDEX);
		}
		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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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 || 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 boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };

		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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])
		{
			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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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_UNSIGNED_INT)
		{
			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 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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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])
		{
			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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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() || (uniformIndex[location].index == GL_INVALID_INDEX))
		{
			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(Device *device)
	{
		GLint numUniforms = static_cast<GLint>(uniformIndex.size());
		for(GLint location = 0; location < numUniforms; location++)
		{
			if((uniformIndex[location].element != 0) || (uniformIndex[location].index == GL_INVALID_INDEX))
			{
				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(device, location, size, b);       break;
				case GL_BOOL_VEC2:  applyUniform2bv(device, location, size, b);       break;
				case GL_BOOL_VEC3:  applyUniform3bv(device, location, size, b);       break;
				case GL_BOOL_VEC4:  applyUniform4bv(device, location, size, b);       break;
				case GL_FLOAT:      applyUniform1fv(device, location, size, f);       break;
				case GL_FLOAT_VEC2: applyUniform2fv(device, location, size, f);       break;
				case GL_FLOAT_VEC3: applyUniform3fv(device, location, size, f);       break;
				case GL_FLOAT_VEC4: applyUniform4fv(device, location, size, f);       break;
				case GL_FLOAT_MAT2:   applyUniformMatrix2fv(device, location, size, f);   break;
				case GL_FLOAT_MAT2x3: applyUniformMatrix2x3fv(device, location, size, f); break;
				case GL_FLOAT_MAT2x4: applyUniformMatrix2x4fv(device, location, size, f); break;
				case GL_FLOAT_MAT3x2: applyUniformMatrix3x2fv(device, location, size, f); break;
				case GL_FLOAT_MAT3:   applyUniformMatrix3fv(device, location, size, f);   break;
				case GL_FLOAT_MAT3x4: applyUniformMatrix3x4fv(device, location, size, f); break;
				case GL_FLOAT_MAT4x2: applyUniformMatrix4x2fv(device, location, size, f); break;
				case GL_FLOAT_MAT4x3: applyUniformMatrix4x3fv(device, location, size, f); break;
				case GL_FLOAT_MAT4:   applyUniformMatrix4fv(device, 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(device, location, size, i);       break;
				case GL_INT_VEC2:   applyUniform2iv(device, location, size, i);       break;
				case GL_INT_VEC3:   applyUniform3iv(device, location, size, i);       break;
				case GL_INT_VEC4:   applyUniform4iv(device, location, size, i);       break;
				case GL_UNSIGNED_INT:      applyUniform1uiv(device, location, size, ui); break;
				case GL_UNSIGNED_INT_VEC2: applyUniform2uiv(device, location, size, ui); break;
				case GL_UNSIGNED_INT_VEC3: applyUniform3uiv(device, location, size, ui); break;
				case GL_UNSIGNED_INT_VEC4: applyUniform4uiv(device, location, size, ui); break;
				default:
					UNREACHABLE(targetUniform->type);
				}

				targetUniform->dirty = false;
			}
		}
	}

	void Program::applyUniformBuffers(Device *device, 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];
			Buffer* vsBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr;
			device->VertexProcessor::setUniformBuffer(bufferBindingIndex,
				vsBuffer ? vsBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
			index = fragmentUniformBuffers[bufferBindingIndex];
			Buffer* psBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr;
			device->PixelProcessor::setUniformBuffer(bufferBindingIndex,
				psBuffer ? psBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
		}
	}

	void Program::applyTransformFeedback(Device *device, 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 = static_cast<unsigned int>(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 = static_cast<int>(totalLinkedVaryingsComponents);
			int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float));
			maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
			int 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()
	{
		glsl::VaryingList &psVaryings = fragmentShader->varyings;
		glsl::VaryingList &vsVaryings = vertexShader->varyings;

		for(auto const &input : psVaryings)
		{
			bool matched = false;

			for(auto const &output : vsVaryings)
			{
				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;
			}
		}

		for(auto const &output : vsVaryings)
		{
			bool matched = false;

			for(auto const &input : psVaryings)
			{
				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++)
						{
							vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, pixelBinary->getInput(in + i, 0).flat));
						}
					}
					else   // Vertex varying is declared but not written to
					{
						for(int i = 0; i < registers; i++)
						{
							pixelBinary->setInput(in + i, components, sw::Shader::Semantic());
						}
					}

					matched = true;
					break;
				}
			}

			if(!matched)
			{
				// For openGL ES 3.0, we need to still add the vertex shader outputs for unmatched varyings, for transform feedback.
				for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
				{
					std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, nullptr);

					if(tfVaryingName == output.name)
					{
						int out = output.reg;
						int components = VariableRegisterSize(output.type);
						int registers = VariableRegisterCount(output.type) * output.size();

						if(out >= 0)
						{
							if(out + registers > MAX_VARYING_VECTORS)
							{
								appendToInfoLog("Too many varyings");
								return false;
							}

							for(int i = 0; i < registers; i++)
							{
								vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR));
							}
						}
						break;
					}
				}
			}
		}

		return true;
	}

	bool Program::linkTransformFeedback()
	{
		size_t totalComponents = 0;
		totalLinkedVaryingsComponents = 0;

		std::set<std::string> uniqueNames;

		for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
		{
			unsigned int 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;
					}

					int size = hasSubscript ? 1 : varying.size();

					int rowCount = VariableRowCount(varying.type);
					int colCount = VariableColumnCount(varying.type);
					int 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(auto const &attribute : vertexShader->activeAttributes)
		{
			int location = (attributeBinding.find(attribute.name) != attributeBinding.end()) ? attributeBinding[attribute.name] : -1;

			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(vertexShader->getShaderVersion() >= 300)
				{
					for(auto const &it : linkedAttribute)
					{
						int itLocStart = getAttributeBinding(it);
						ASSERT(itLocStart >= 0);
						int itLocEnd = itLocStart + VariableRegisterCount(it.type);
						for(int i = 0; i < rows; i++)
						{
							int loc = location + i;
							if((loc >= itLocStart) && (loc < itLocEnd))
							{
								appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), it.name.c_str(), location);
								return false;
							}
						}
					}
				}

				linkedAttributeLocation[attribute.name] = location;
				linkedAttribute.push_back(attribute);
				for(int i = 0; i < rows; i++)
				{
					usedLocations |= 1 << (location + i);
				}
			}
		}

		// Link attributes that don't have a binding location
		for(auto const &attribute : vertexShader->activeAttributes)
		{
			int location = (attributeBinding.find(attribute.name) != attributeBinding.end()) ? attributeBinding[attribute.name] : -1;

			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
				}

				linkedAttributeLocation[attribute.name] = availableIndex;
				linkedAttribute.push_back(attribute);
			}
		}

		for(auto const &it : linkedAttribute)
		{
			int location = getAttributeBinding(it);
			ASSERT(location >= 0);
			int index = vertexShader->getSemanticIndex(it.name);
			int rows = std::max(VariableRegisterCount(it.type), 1);

			for(int r = 0; r < rows; r++)
			{
				attributeStream[r + location] = index++;
			}
		}

		return true;
	}

	int Program::getAttributeBinding(const glsl::Attribute &attribute)
	{
		if(attribute.location != -1)
		{
			return attribute.location;
		}

		std::unordered_map<std::string, GLuint>::const_iterator it = linkedAttributeLocation.find(attribute.name);
		if(it != linkedAttributeLocation.end())
		{
			return it->second;
		}

		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(!isUniformDefined(name))
		{
			uniforms.push_back(uniform);
			unsigned int index = (blockInfo.index == -1) ? static_cast<unsigned int>(uniforms.size() - 1) : GL_INVALID_INDEX;

			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(Device *device, 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(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform2bv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform3bv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform4bv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform1fv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform2fv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform3fv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform4fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
	{
		return applyUniform(device, location, (float*)v);
	}

	bool Program::applyUniformMatrix2fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniformMatrix2x3fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniformMatrix2x4fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniformMatrix3fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniformMatrix3x2fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniformMatrix3x4fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniformMatrix4fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
	{
		return applyUniform(device, location, (float*)value);
	}

	bool Program::applyUniformMatrix4x2fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniformMatrix4x3fv(Device *device, 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(device, location, (float*)matrix);
	}

	bool Program::applyUniform1iv(Device *device, 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(device, location, (float*)vector);
		}

		return true;
	}

	bool Program::applyUniform2iv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform3iv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform4iv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform1uiv(Device *device, 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(device, location, (float*)vector);
		}

		return true;
	}

	bool Program::applyUniform2uiv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform3uiv(Device *device, 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(device, location, (float*)vector);
	}

	bool Program::applyUniform4uiv(Device *device, 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(device, 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;

		linkedAttribute.clear();
		linkedAttributeLocation.clear();

		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
		{
			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
	{
		ASSERT(index < linkedAttribute.size());

		std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin() + index;

		if(bufsize > 0)
		{
			const char *string = it->name.c_str();

			strncpy(name, string, bufsize);
			name[bufsize - 1] = '\0';

			if(length)
			{
				*length = static_cast<GLsizei>(strlen(name));
			}
		}

		*size = 1;   // Always a single 'type' instance

		*type = it->type;
	}

	size_t Program::getActiveAttributeCount() const
	{
		return linkedAttribute.size();
	}

	GLint Program::getActiveAttributeMaxLength() const
	{
		int maxLength = 0;

		std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin();
		std::vector<glsl::Attribute>::const_iterator itEnd = linkedAttribute.end();
		for(; it != itEnd; ++it)
		{
			maxLength = std::max((int)(it->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 = static_cast<GLsizei>(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
	{
		if(index >= getActiveUniformBlockCount())
		{
			return error(GL_INVALID_VALUE);
		}

		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 = static_cast<GLsizei>(strlen(name));
			}
		}
	}

	size_t Program::getActiveUniformBlockCount() const
	{
		return uniformBlocks.size();
	}

	GLint Program::getActiveUniformBlockMaxLength() const
	{
		GLint 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())
				{
					GLint length = static_cast<GLint>(uniformBlock.name.length() + 1);

					// Counting in "[0]".
					const GLint 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(Device* device)
	{
		resetInfoLog();

		if(!isLinked())
		{
			appendToInfoLog("Program has not been successfully linked.");
			validated = false;
		}
		else
		{
			applyUniforms(device);
			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;
	}
}
