// 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->vPosDeclared && 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->vFaceDeclared;

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

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

		if(context->vertexShader)
		{
			state.positionRegister = context->vertexShader->positionRegister;
			state.pointSizeRegister = context->vertexShader->pointSizeRegister;
		}
		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->semantic[interpolant][component - project];

					if(semantic.active())
					{
						int input = interpolant;
						for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
						{
							if(semantic == context->vertexShader->output[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->semantic[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);
	}
}
