// 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 "VertexProcessor.hpp"

#include "Shader/VertexPipeline.hpp"
#include "Shader/VertexProgram.hpp"
#include "Shader/VertexShader.hpp"
#include "Shader/PixelShader.hpp"
#include "Shader/Constants.hpp"
#include "Common/Math.hpp"
#include "Common/Memory.hpp"
#include "Common/Debug.hpp"

#include <cstring>

namespace sw
{
	bool precacheVertex = false;

	void VertexCache::clear()
	{
		for(int i = 0; i < 16; i++)
		{
			tag[i] = 0x80000000;
		}
	}

	uint32_t VertexProcessor::States::computeHash()
	{
		uint32_t *state = reinterpret_cast<uint32_t*>(this);
		uint32_t hash = 0;

		for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++)
		{
			hash ^= state[i];
		}

		return hash;
	}

	bool VertexProcessor::State::operator==(const State &state) const
	{
		if(hash != state.hash)
		{
			return false;
		}

		static_assert(is_memcmparable<State>::value, "Cannot memcmp States");
		return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
	}

	VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo()
	{
		buffer = nullptr;
		offset = 0;
		reg = 0;
		row = 0;
		col = 0;
		stride = 0;
	}

	VertexProcessor::UniformBufferInfo::UniformBufferInfo()
	{
		buffer = nullptr;
		offset = 0;
	}

	VertexProcessor::VertexProcessor(Context *context) : context(context)
	{
		for(int i = 0; i < 12; i++)
		{
			M[i] = 1;
		}

		V = 1;
		B = 1;
		P = 0;
		PB = 0;
		PBV = 0;

		for(int i = 0; i < 12; i++)
		{
			PBVM[i] = 0;
		}

		setLightingEnable(true);
		setSpecularEnable(false);

		for(int i = 0; i < 8; i++)
		{
			setLightEnable(i, false);
			setLightPosition(i, 0);
		}

		updateMatrix = true;
		updateViewMatrix = true;
		updateBaseMatrix = true;
		updateProjectionMatrix = true;
		updateLighting = true;

		for(int i = 0; i < 12; i++)
		{
			updateModelMatrix[i] = true;
		}

		routineCache = nullptr;
		setRoutineCacheSize(1024);
	}

	VertexProcessor::~VertexProcessor()
	{
		delete routineCache;
		routineCache = nullptr;
	}

	// This object has to be mem aligned
	void *VertexProcessor::operator new(size_t size)
	{
		ASSERT(size == sizeof(VertexProcessor)); // This operator can't be called from a derived class
		return sw::allocate(sizeof(VertexProcessor), 16);
	}

	void VertexProcessor::operator delete(void *mem)
	{
		sw::deallocate(mem);
	}

	void VertexProcessor::setInputStream(int index, const Stream &stream)
	{
		context->input[index] = stream;
	}

	void VertexProcessor::resetInputStreams(bool preTransformed)
	{
		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
		{
			context->input[i].defaults();
		}

		context->preTransformed = preTransformed;
	}

	void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
	{
		if(index < VERTEX_UNIFORM_VECTORS)
		{
			c[index][0] = value[0];
			c[index][1] = value[1];
			c[index][2] = value[2];
			c[index][3] = value[3];
		}
		else ASSERT(false);
	}

	void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
	{
		if(index < 16)
		{
			i[index][0] = integer[0];
			i[index][1] = integer[1];
			i[index][2] = integer[2];
			i[index][3] = integer[3];
		}
		else ASSERT(false);
	}

	void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
	{
		if(index < 16)
		{
			b[index] = boolean != 0;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
	{
		uniformBufferInfo[index].buffer = buffer;
		uniformBufferInfo[index].offset = offset;
	}

	void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
	{
		for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
		{
			u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
			uniformBuffers[i] = uniformBufferInfo[i].buffer;
		}
	}

	void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, unsigned int stride)
	{
		transformFeedbackInfo[index].buffer = buffer;
		transformFeedbackInfo[index].offset = offset;
		transformFeedbackInfo[index].reg = reg;
		transformFeedbackInfo[index].row = row;
		transformFeedbackInfo[index].col = col;
		transformFeedbackInfo[index].stride = stride;
	}

	void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[])
	{
		for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
		{
			t[i] = transformFeedbackInfo[i].buffer ? static_cast<byte*>(transformFeedbackInfo[i].buffer->lock(PUBLIC, PRIVATE)) + transformFeedbackInfo[i].offset : nullptr;
			transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer;
			v[i] = transformFeedbackInfo[i].reg;
			r[i] = transformFeedbackInfo[i].row;
			c[i] = transformFeedbackInfo[i].col;
			s[i] = transformFeedbackInfo[i].stride;
		}
	}

	void VertexProcessor::setModelMatrix(const Matrix &M, int i)
	{
		if(i < 12)
		{
			this->M[i] = M;

			updateMatrix = true;
			updateModelMatrix[i] = true;
			updateLighting = true;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setViewMatrix(const Matrix &V)
	{
		this->V = V;

		updateMatrix = true;
		updateViewMatrix = true;
	}

	void VertexProcessor::setBaseMatrix(const Matrix &B)
	{
		this->B = B;

		updateMatrix = true;
		updateBaseMatrix = true;
	}

	void VertexProcessor::setProjectionMatrix(const Matrix &P)
	{
		this->P = P;
		context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);

		updateMatrix = true;
		updateProjectionMatrix = true;
	}

	void VertexProcessor::setLightingEnable(bool lightingEnable)
	{
		context->setLightingEnable(lightingEnable);

		updateLighting = true;
	}

	void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
	{
		if(light < 8)
		{
			context->setLightEnable(light, lightEnable);
		}
		else ASSERT(false);

		updateLighting = true;
	}

	void VertexProcessor::setSpecularEnable(bool specularEnable)
	{
		context->setSpecularEnable(specularEnable);

		updateLighting = true;
	}

	void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
	{
		if(light < 8)
		{
			context->setLightPosition(light, lightPosition);
		}
		else ASSERT(false);

		updateLighting = true;
	}

	void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
	{
		if(light < 8)
		{
			ff.lightDiffuse[light][0] = lightDiffuse.r;
			ff.lightDiffuse[light][1] = lightDiffuse.g;
			ff.lightDiffuse[light][2] = lightDiffuse.b;
			ff.lightDiffuse[light][3] = lightDiffuse.a;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
	{
		if(light < 8)
		{
			ff.lightSpecular[light][0] = lightSpecular.r;
			ff.lightSpecular[light][1] = lightSpecular.g;
			ff.lightSpecular[light][2] = lightSpecular.b;
			ff.lightSpecular[light][3] = lightSpecular.a;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
	{
		if(light < 8)
		{
			ff.lightAmbient[light][0] = lightAmbient.r;
			ff.lightAmbient[light][1] = lightAmbient.g;
			ff.lightAmbient[light][2] = lightAmbient.b;
			ff.lightAmbient[light][3] = lightAmbient.a;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
	{
		if(light < 8)
		{
			ff.attenuationConstant[light] = replicate(constant);
			ff.attenuationLinear[light] = replicate(linear);
			ff.attenuationQuadratic[light] = replicate(quadratic);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setLightRange(unsigned int light, float lightRange)
	{
		if(light < 8)
		{
			ff.lightRange[light] = lightRange;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setFogEnable(bool fogEnable)
	{
		context->fogEnable = fogEnable;
	}

	void VertexProcessor::setVertexFogMode(FogMode fogMode)
	{
		context->vertexFogMode = fogMode;
	}

	void VertexProcessor::setInstanceID(int instanceID)
	{
		context->instanceID = instanceID;
	}

	void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
	{
		context->setColorVertexEnable(colorVertexEnable);
	}

	void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
	{
		context->setDiffuseMaterialSource(diffuseMaterialSource);
	}

	void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
	{
		context->setSpecularMaterialSource(specularMaterialSource);
	}

	void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
	{
		context->setAmbientMaterialSource(ambientMaterialSource);
	}

	void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
	{
		context->setEmissiveMaterialSource(emissiveMaterialSource);
	}

	void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
	{
		ff.globalAmbient[0] = globalAmbient.r;
		ff.globalAmbient[1] = globalAmbient.g;
		ff.globalAmbient[2] = globalAmbient.b;
		ff.globalAmbient[3] = globalAmbient.a;
	}

	void VertexProcessor::setMaterialEmission(const Color<float> &emission)
	{
		ff.materialEmission[0] = emission.r;
		ff.materialEmission[1] = emission.g;
		ff.materialEmission[2] = emission.b;
		ff.materialEmission[3] = emission.a;
	}

	void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
	{
		ff.materialAmbient[0] = materialAmbient.r;
		ff.materialAmbient[1] = materialAmbient.g;
		ff.materialAmbient[2] = materialAmbient.b;
		ff.materialAmbient[3] = materialAmbient.a;
	}

	void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
	{
		ff.materialDiffuse[0] = diffuseColor.r;
		ff.materialDiffuse[1] = diffuseColor.g;
		ff.materialDiffuse[2] = diffuseColor.b;
		ff.materialDiffuse[3] = diffuseColor.a;
	}

	void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
	{
		ff.materialSpecular[0] = specularColor.r;
		ff.materialSpecular[1] = specularColor.g;
		ff.materialSpecular[2] = specularColor.b;
		ff.materialSpecular[3] = specularColor.a;
	}

	void VertexProcessor::setMaterialShininess(float specularPower)
	{
		ff.materialShininess = specularPower;
	}

	void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
	{
		if(light < 8)
		{
			ff.lightPosition[light][0] = P.x;
			ff.lightPosition[light][1] = P.y;
			ff.lightPosition[light][2] = P.z;
			ff.lightPosition[light][3] = 1;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setRangeFogEnable(bool enable)
	{
		context->rangeFogEnable = enable;
	}

	void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
	{
		context->indexedVertexBlendEnable = indexedVertexBlendEnable;
	}

	void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
	{
		if(vertexBlendMatrixCount <= 4)
		{
			context->vertexBlendMatrixCount = vertexBlendMatrixCount;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
	{
		if(stage < TEXTURE_IMAGE_UNITS)
		{
			context->textureWrap[stage] = mask;
		}
		else ASSERT(false);

		context->textureWrapActive = false;

		for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
		{
			context->textureWrapActive |= (context->textureWrap[i] != 0x00);
		}
	}

	void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
	{
		if(stage < 8)
		{
			context->texGen[stage] = texGen;
		}
		else ASSERT(false);
	}

	void VertexProcessor::setLocalViewer(bool localViewer)
	{
		context->localViewer = localViewer;
	}

	void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
	{
		context->normalizeNormals = normalizeNormals;
	}

	void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
	{
		for(int i = 0; i < 4; i++)
		{
			for(int j = 0; j < 4; j++)
			{
				ff.textureTransform[stage][i][j] = T[i][j];
			}
		}
	}

	void VertexProcessor::setTextureTransform(int stage, int count, bool project)
	{
		context->textureTransformCount[stage] = count;
		context->textureTransformProject[stage] = project;
	}

	void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
	{
		if(sampler < TEXTURE_IMAGE_UNITS)
		{
			context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
	{
		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
		{
			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
	{
		if(sampler < TEXTURE_IMAGE_UNITS)
		{
			context->sampler[sampler].setSyncRequired(isSincRequired);
		}
		else ASSERT(false);
	}

	void VertexProcessor::setPointSize(float pointSize)
	{
		point.pointSize = replicate(pointSize);
	}

	void VertexProcessor::setPointSizeMin(float pointSizeMin)
	{
		point.pointSizeMin = pointSizeMin;
	}

	void VertexProcessor::setPointSizeMax(float pointSizeMax)
	{
		point.pointSizeMax = pointSizeMax;
	}

	void VertexProcessor::setPointScaleA(float pointScaleA)
	{
		point.pointScaleA = pointScaleA;
	}

	void VertexProcessor::setPointScaleB(float pointScaleB)
	{
		point.pointScaleB = pointScaleB;
	}

	void VertexProcessor::setPointScaleC(float pointScaleC)
	{
		point.pointScaleC = pointScaleC;
	}

	void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
	{
		context->transformFeedbackQueryEnabled = enable;
	}

	void VertexProcessor::enableTransformFeedback(uint64_t enable)
	{
		context->transformFeedbackEnabled = enable;
	}

	const Matrix &VertexProcessor::getModelTransform(int i)
	{
		updateTransform();
		return PBVM[i];
	}

	const Matrix &VertexProcessor::getViewTransform()
	{
		updateTransform();
		return PBV;
	}

	bool VertexProcessor::isFixedFunction()
	{
		return !context->vertexShader;
	}

	void VertexProcessor::setTransform(const Matrix &M, int i)
	{
		ff.transformT[i][0][0] = M[0][0];
		ff.transformT[i][0][1] = M[1][0];
		ff.transformT[i][0][2] = M[2][0];
		ff.transformT[i][0][3] = M[3][0];

		ff.transformT[i][1][0] = M[0][1];
		ff.transformT[i][1][1] = M[1][1];
		ff.transformT[i][1][2] = M[2][1];
		ff.transformT[i][1][3] = M[3][1];

		ff.transformT[i][2][0] = M[0][2];
		ff.transformT[i][2][1] = M[1][2];
		ff.transformT[i][2][2] = M[2][2];
		ff.transformT[i][2][3] = M[3][2];

		ff.transformT[i][3][0] = M[0][3];
		ff.transformT[i][3][1] = M[1][3];
		ff.transformT[i][3][2] = M[2][3];
		ff.transformT[i][3][3] = M[3][3];
	}

	void VertexProcessor::setCameraTransform(const Matrix &M, int i)
	{
		ff.cameraTransformT[i][0][0] = M[0][0];
		ff.cameraTransformT[i][0][1] = M[1][0];
		ff.cameraTransformT[i][0][2] = M[2][0];
		ff.cameraTransformT[i][0][3] = M[3][0];

		ff.cameraTransformT[i][1][0] = M[0][1];
		ff.cameraTransformT[i][1][1] = M[1][1];
		ff.cameraTransformT[i][1][2] = M[2][1];
		ff.cameraTransformT[i][1][3] = M[3][1];

		ff.cameraTransformT[i][2][0] = M[0][2];
		ff.cameraTransformT[i][2][1] = M[1][2];
		ff.cameraTransformT[i][2][2] = M[2][2];
		ff.cameraTransformT[i][2][3] = M[3][2];

		ff.cameraTransformT[i][3][0] = M[0][3];
		ff.cameraTransformT[i][3][1] = M[1][3];
		ff.cameraTransformT[i][3][2] = M[2][3];
		ff.cameraTransformT[i][3][3] = M[3][3];
	}

	void VertexProcessor::setNormalTransform(const Matrix &M, int i)
	{
		ff.normalTransformT[i][0][0] = M[0][0];
		ff.normalTransformT[i][0][1] = M[1][0];
		ff.normalTransformT[i][0][2] = M[2][0];
		ff.normalTransformT[i][0][3] = M[3][0];

		ff.normalTransformT[i][1][0] = M[0][1];
		ff.normalTransformT[i][1][1] = M[1][1];
		ff.normalTransformT[i][1][2] = M[2][1];
		ff.normalTransformT[i][1][3] = M[3][1];

		ff.normalTransformT[i][2][0] = M[0][2];
		ff.normalTransformT[i][2][1] = M[1][2];
		ff.normalTransformT[i][2][2] = M[2][2];
		ff.normalTransformT[i][2][3] = M[3][2];

		ff.normalTransformT[i][3][0] = M[0][3];
		ff.normalTransformT[i][3][1] = M[1][3];
		ff.normalTransformT[i][3][2] = M[2][3];
		ff.normalTransformT[i][3][3] = M[3][3];
	}

	void VertexProcessor::updateTransform()
	{
		if(!updateMatrix) return;

		int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);

		if(updateProjectionMatrix)
		{
			PB = P * B;
			PBV = PB * V;

			for(int i = 0; i < activeMatrices; i++)
			{
				PBVM[i] = PBV * M[i];
				updateModelMatrix[i] = false;
			}

			updateProjectionMatrix = false;
			updateBaseMatrix = false;
			updateViewMatrix = false;
		}

		if(updateBaseMatrix)
		{
			PB = P * B;
			PBV = PB * V;

			for(int i = 0; i < activeMatrices; i++)
			{
				PBVM[i] = PBV * M[i];
				updateModelMatrix[i] = false;
			}

			updateBaseMatrix = false;
			updateViewMatrix = false;
		}

		if(updateViewMatrix)
		{
			PBV = PB * V;

			for(int i = 0; i < activeMatrices; i++)
			{
				PBVM[i] = PBV * M[i];
				updateModelMatrix[i] = false;
			}

			updateViewMatrix = false;
		}

		for(int i = 0; i < activeMatrices; i++)
		{
			if(updateModelMatrix[i])
			{
				PBVM[i] = PBV * M[i];
				updateModelMatrix[i] = false;
			}
		}

		for(int i = 0; i < activeMatrices; i++)
		{
			setTransform(PBVM[i], i);
			setCameraTransform(B * V * M[i], i);
			setNormalTransform(~!(B * V * M[i]), i);
		}

		updateMatrix = false;
	}

	void VertexProcessor::setRoutineCacheSize(int cacheSize)
	{
		delete routineCache;
		routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536));
	}

	const VertexProcessor::State VertexProcessor::update(DrawType drawType)
	{
		if(isFixedFunction())
		{
			updateTransform();

			if(updateLighting)
			{
				for(int i = 0; i < 8; i++)
				{
					if(context->vertexLightActive(i))
					{
						// Light position in camera coordinates
						setLightViewPosition(i, B * V * context->getLightPosition(i));
					}
				}

				updateLighting = false;
			}
		}

		State state;

		if(context->vertexShader)
		{
			state.shaderID = context->vertexShader->getSerialID();
		}
		else
		{
			state.shaderID = 0;
		}

		state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
		state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
		state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
		state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;

		state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
		state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
		state.vertexNormalActive = context->vertexNormalActive();
		state.normalizeNormals = context->normalizeNormalsActive();
		state.vertexLightingActive = context->vertexLightingActive();
		state.diffuseActive = context->diffuseActive();
		state.specularActive = context->specularActive();
		state.vertexSpecularActive = context->vertexSpecularActive();

		state.vertexLightActive = context->vertexLightActive(0) << 0 |
		                          context->vertexLightActive(1) << 1 |
		                          context->vertexLightActive(2) << 2 |
		                          context->vertexLightActive(3) << 3 |
		                          context->vertexLightActive(4) << 4 |
		                          context->vertexLightActive(5) << 5 |
		                          context->vertexLightActive(6) << 6 |
		                          context->vertexLightActive(7) << 7;

		state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
		state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
		state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
		state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
		state.fogActive = context->fogActive();
		state.vertexFogMode = context->vertexFogModeActive();
		state.rangeFogActive = context->rangeFogActive();
		state.localViewerActive = context->localViewerActive();
		state.pointSizeActive = context->pointSizeActive();
		state.pointScaleActive = context->pointScaleActive();

		state.preTransformed = context->preTransformed;
		state.superSampling = context->getSuperSampleCount() > 1;

		state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
		state.transformFeedbackEnabled = context->transformFeedbackEnabled;

		// Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
		//       which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
		DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
		state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);

		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
		{
			state.input[i].type = context->input[i].type;
			state.input[i].count = context->input[i].count;
			state.input[i].normalized = context->input[i].normalized;
			state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
		}

		if(!context->vertexShader)
		{
			for(int i = 0; i < 8; i++)
			{
			//	state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
				state.textureState[i].texGenActive = context->texGenActive(i);
				state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
				state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
			}
		}
		else
		{
			for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
			{
				if(context->vertexShader->usesSampler(i))
				{
					state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
				}
			}
		}

		if(context->vertexShader)   // FIXME: Also when pre-transformed?
		{
			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
			{
				state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
				state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
				state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
				state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
			}
		}
		else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
		{
			state.output[Pos].write = 0xF;

			if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
			{
				state.output[C0].write = 0xF;
			}

			if(context->specularActive())
			{
				state.output[C1].write = 0xF;
			}

			for(int stage = 0; stage < 8; stage++)
			{
				if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
				if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
				if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
				if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
			}

			if(context->fogActive())
			{
				state.output[Fog].xWrite = true;
			}

			if(context->pointSizeActive())
			{
				state.output[Pts].yWrite = true;
			}
		}
		else
		{
			state.output[Pos].write = 0xF;

			for(int i = 0; i < 2; i++)
			{
				if(context->input[Color0 + i])
				{
					state.output[C0 + i].write = 0xF;
				}
			}

			for(int i = 0; i < 8; i++)
			{
				if(context->input[TexCoord0 + i])
				{
					state.output[T0 + i].write = 0xF;
				}
			}

			if(context->input[PointSize])
			{
				state.output[Pts].yWrite = true;
			}
		}

		if(context->vertexShaderModel() < 0x0300)
		{
			state.output[C0].clamp = 0xF;
			state.output[C1].clamp = 0xF;
			state.output[Fog].xClamp = true;
		}

		state.hash = state.computeHash();

		return state;
	}

	std::shared_ptr<Routine> VertexProcessor::routine(const State &state)
	{
		auto routine = routineCache->query(state);

		if(!routine)   // Create one
		{
			VertexRoutine *generator = nullptr;

			if(state.fixedFunction)
			{
				generator = new VertexPipeline(state);
			}
			else
			{
				generator = new VertexProgram(state, context->vertexShader);
			}

			generator->generate();
			routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
			delete generator;

			routineCache->add(state, routine);
		}

		return routine;
	}
}
