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

#include "SetupRoutine.hpp"
#include "Primitive.hpp"
#include "Polygon.hpp"
#include "Context.hpp"
#include "Renderer.hpp"
#include "Constants.hpp"
#include "Debug.hpp"

namespace sw
{
	extern bool complementaryDepthBuffer;
	extern bool fullPixelPositionRegister;

	bool precacheSetup = false;

	unsigned int SetupProcessor::States::computeHash()
	{
		unsigned int *state = (unsigned int*)this;
		unsigned int hash = 0;

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

		return hash;
	}

	SetupProcessor::State::State(int i)
	{
		memset(this, 0, sizeof(State));
	}

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

		return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
	}

	SetupProcessor::SetupProcessor(Context *context) : context(context)
	{
		routineCache = 0;
		setRoutineCacheSize(1024);
	}

	SetupProcessor::~SetupProcessor()
	{
		delete routineCache;
		routineCache = 0;
	}

	SetupProcessor::State SetupProcessor::update() const
	{
		State state;

		bool vPosZW = (context->pixelShader && context->pixelShader->isVPosDeclared() && fullPixelPositionRegister);

		state.isDrawPoint = context->isDrawPoint(true);
		state.isDrawLine = context->isDrawLine(true);
		state.isDrawTriangle = context->isDrawTriangle(false);
		state.isDrawSolidTriangle = context->isDrawTriangle(true);
		state.interpolateZ = context->depthBufferActive() || context->pixelFogActive() != FOG_NONE || vPosZW;
		state.interpolateW = context->perspectiveActive() || vPosZW;
		state.perspective = context->perspectiveActive();
		state.pointSprite = context->pointSpriteActive();
		state.cullMode = context->cullMode;
		state.twoSidedStencil = context->stencilActive() && context->twoSidedStencil;
		state.slopeDepthBias = slopeDepthBias != 0.0f;
		state.vFace = context->pixelShader && context->pixelShader->isVFaceDeclared();

		state.positionRegister = Pos;
		state.pointSizeRegister = Unused;

		state.multiSample = context->getMultiSampleCount();
		state.rasterizerDiscard = context->rasterizerDiscard;

		if(context->vertexShader)
		{
			state.positionRegister = context->vertexShader->getPositionRegister();
			state.pointSizeRegister = context->vertexShader->getPointSizeRegister();
		}
		else if(context->pointSizeActive())
		{
			state.pointSizeRegister = Pts;
		}

		for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
		{
			for(int component = 0; component < 4; component++)
			{
				state.gradient[interpolant][component].attribute = Unused;
				state.gradient[interpolant][component].flat = false;
				state.gradient[interpolant][component].wrap = false;
			}
		}

		state.fog.attribute = Unused;
		state.fog.flat = false;
		state.fog.wrap = false;

		const bool point = context->isDrawPoint(true);
		const bool sprite = context->pointSpriteActive();
		const bool flatShading = (context->shadingMode == SHADING_FLAT) || point;

		if(context->vertexShader && context->pixelShader)
		{
			for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
			{
				for(int component = 0; component < 4; component++)
				{
					int project = context->isProjectionComponent(interpolant - 2, component) ? 1 : 0;
					const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component - project);

					if(semantic.active())
					{
						int input = interpolant;
						for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
						{
							if(semantic == context->vertexShader->getOutput(i, component - project))
							{
								input = i;
								break;
							}
						}

						bool flat = point;

						switch(semantic.usage)
						{
						case Shader::USAGE_TEXCOORD: flat = point && !sprite;             break;
						case Shader::USAGE_COLOR:    flat = semantic.flat || flatShading; break;
						}

						state.gradient[interpolant][component].attribute = input;
						state.gradient[interpolant][component].flat = flat;
					}
				}
			}
		}
		else if(context->preTransformed && context->pixelShader)
		{
			for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
			{
				for(int component = 0; component < 4; component++)
				{
					const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component);

					switch(semantic.usage)
					{
					case 0xFF:
						break;
					case Shader::USAGE_TEXCOORD:
						state.gradient[interpolant][component].attribute = T0 + semantic.index;
						state.gradient[interpolant][component].flat = semantic.flat || (point && !sprite);
						break;
					case Shader::USAGE_COLOR:
						state.gradient[interpolant][component].attribute = C0 + semantic.index;
						state.gradient[interpolant][component].flat = semantic.flat || flatShading;
						break;
					default:
						ASSERT(false);
					}
				}
			}
		}
		else if(context->pixelShaderVersion() < 0x0300)
		{
			for(int coordinate = 0; coordinate < 8; coordinate++)
			{
				for(int component = 0; component < 4; component++)
				{
					if(context->textureActive(coordinate, component))
					{
						state.texture[coordinate][component].attribute = T0 + coordinate;
						state.texture[coordinate][component].flat = point && !sprite;
						state.texture[coordinate][component].wrap = (context->textureWrap[coordinate] & (1 << component)) != 0;
					}
				}
			}

			for(int color = 0; color < 2; color++)
			{
				for(int component = 0; component < 4; component++)
				{
					if(context->colorActive(color, component))
					{
						state.color[color][component].attribute = C0 + color;
						state.color[color][component].flat = flatShading;
					}
				}
			}
		}
		else ASSERT(false);

		if(context->fogActive())
		{
			state.fog.attribute = Fog;
			state.fog.flat = point;
		}

		state.hash = state.computeHash();

		return state;
	}

	Routine *SetupProcessor::routine(const State &state)
	{
		Routine *routine = routineCache->query(state);

		if(!routine)
		{
			SetupRoutine *generator = new SetupRoutine(state);
			generator->generate();
			routine = generator->getRoutine();
			delete generator;

			routineCache->add(state, routine);
		}

		return routine;
	}

	void SetupProcessor::setRoutineCacheSize(int cacheSize)
	{
		delete routineCache;
		routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheSetup ? "sw-setup" : 0);
	}
}
