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

#include "Primitive.hpp"
#include "System/Memory.hpp"
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkImageView.hpp"
#include "Pipeline/SpirvShader.hpp"

#include <string.h>

namespace sw
{
	extern bool perspectiveCorrection;

	bool booleanFaceRegister = false;
	bool fullPixelPositionRegister = false;
	bool colorsDefaultToZero = false;

	bool forceWindowed = false;
	bool quadLayoutEnabled = false;
	bool postBlendSRGB = false;
	bool exactColorRounding = false;
	TransparencyAntialiasing transparencyAntialiasing = TRANSPARENCY_NONE;
	bool forceClearRegisters = false;

	Context::Context()
	{
		init();
	}

	Context::~Context()
	{
	}

	void *Context::operator new(size_t bytes)
	{
		return allocate((unsigned int)bytes);
	}

	void Context::operator delete(void *pointer, size_t bytes)
	{
		deallocate(pointer);
	}

	bool Context::isDrawPoint() const
	{
		switch(topology)
		{
		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
			return true;
		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
			break;
		default:
			UNIMPLEMENTED("topology %d", int(topology));
		}
		return false;
	}

	bool Context::isDrawLine() const
	{
		switch(topology)
		{
		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
			return true;
		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
			break;
		default:
			UNIMPLEMENTED("topology %d", int(topology));
		}
		return false;
	}

	bool Context::isDrawTriangle() const
	{
		switch(topology)
		{
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
			return true;
		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
			break;
		default:
			UNIMPLEMENTED("topology %d", int(topology));
		}
		return false;
	}

	void Context::init()
	{
		// Set vertex streams to null stream
		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
		{
			input[i].defaults();
		}

		for(int i = 0; i < RENDERTARGETS; ++i)
		{
			renderTarget[i] = nullptr;
		}
		depthBuffer = nullptr;
		stencilBuffer = nullptr;

		stencilEnable = false;
		twoSidedStencil = false;
		frontStencil = {};
		backStencil = {};

		rasterizerDiscard = false;

		depthCompareMode = VK_COMPARE_OP_LESS;
		depthBoundsTestEnable = false;
		depthBufferEnable = false;
		depthWriteEnable = false;

		alphaBlendEnable = false;
		sourceBlendFactorState = VK_BLEND_FACTOR_ONE;
		destBlendFactorState = VK_BLEND_FACTOR_ZERO;
		blendOperationState = VK_BLEND_OP_ADD;

		separateAlphaBlendEnable = false;
		sourceBlendFactorStateAlpha = VK_BLEND_FACTOR_ONE;
		destBlendFactorStateAlpha = VK_BLEND_FACTOR_ZERO;
		blendOperationStateAlpha = VK_BLEND_OP_ADD;

		cullMode = CULL_CLOCKWISE;
		frontFacingCCW = true;

		depthBias = 0.0f;
		slopeDepthBias = 0.0f;

		for(int i = 0; i < RENDERTARGETS; i++)
		{
			colorWriteMask[i] = 0x0000000F;
		}

		pipelineLayout = nullptr;

		pixelShader = nullptr;
		vertexShader = nullptr;

		instanceID = 0;

		occlusionEnabled = false;

		lineWidth = 1.0f;

		sampleMask = 0xFFFFFFFF;
		alphaToCoverage = false;
	}

	bool Context::setDepthBufferEnable(bool depthBufferEnable)
	{
		bool modified = (Context::depthBufferEnable != depthBufferEnable);
		Context::depthBufferEnable = depthBufferEnable;
		return modified;
	}

	bool Context::setAlphaBlendEnable(bool alphaBlendEnable)
	{
		bool modified = (Context::alphaBlendEnable != alphaBlendEnable);
		Context::alphaBlendEnable = alphaBlendEnable;
		return modified;
	}

	bool Context::setSourceBlendFactor(VkBlendFactor sourceBlendFactor)
	{
		bool modified = (Context::sourceBlendFactorState != sourceBlendFactor);
		Context::sourceBlendFactorState = sourceBlendFactor;
		return modified;
	}

	bool Context::setDestBlendFactor(VkBlendFactor destBlendFactor)
	{
		bool modified = (Context::destBlendFactorState != destBlendFactor);
		Context::destBlendFactorState = destBlendFactor;
		return modified;
	}

	bool Context::setBlendOperation(VkBlendOp blendOperation)
	{
		bool modified = (Context::blendOperationState != blendOperation);
		Context::blendOperationState = blendOperation;
		return modified;
	}

	bool Context::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)
	{
		bool modified = (Context::separateAlphaBlendEnable != separateAlphaBlendEnable);
		Context::separateAlphaBlendEnable = separateAlphaBlendEnable;
		return modified;
	}

	bool Context::setSourceBlendFactorAlpha(VkBlendFactor sourceBlendFactorAlpha)
	{
		bool modified = (Context::sourceBlendFactorStateAlpha != sourceBlendFactorAlpha);
		Context::sourceBlendFactorStateAlpha = sourceBlendFactorAlpha;
		return modified;
	}

	bool Context::setDestBlendFactorAlpha(VkBlendFactor destBlendFactorAlpha)
	{
		bool modified = (Context::destBlendFactorStateAlpha != destBlendFactorAlpha);
		Context::destBlendFactorStateAlpha = destBlendFactorAlpha;
		return modified;
	}

	bool Context::setBlendOperationAlpha(VkBlendOp blendOperationAlpha)
	{
		bool modified = (Context::blendOperationStateAlpha != blendOperationAlpha);
		Context::blendOperationStateAlpha = blendOperationAlpha;
		return modified;
	}

	bool Context::setColorWriteMask(int index, int colorWriteMask)
	{
		bool modified = (Context::colorWriteMask[index] != colorWriteMask);
		Context::colorWriteMask[index] = colorWriteMask;
		return modified;
	}

	bool Context::depthWriteActive()
	{
		if(!depthBufferActive()) return false;

		return depthWriteEnable;
	}

	bool Context::alphaTestActive()
	{
		return transparencyAntialiasing != TRANSPARENCY_NONE;
	}

	bool Context::depthBufferActive()
	{
		return depthBuffer && depthBufferEnable;
	}

	bool Context::stencilActive()
	{
		return stencilBuffer && stencilEnable;
	}

	bool Context::alphaBlendActive()
	{
		if(!alphaBlendEnable)
		{
			return false;
		}

		if(!colorUsed())
		{
			return false;
		}

		bool colorBlend = !(blendOperation() == VK_BLEND_OP_SRC_EXT && sourceBlendFactor() == VK_BLEND_FACTOR_ONE);
		bool alphaBlend = separateAlphaBlendEnable ? !(blendOperationAlpha() == VK_BLEND_OP_SRC_EXT && sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE) : colorBlend;

		return colorBlend || alphaBlend;
	}

	VkBlendFactor Context::sourceBlendFactor()
	{
		if(!alphaBlendEnable) return VK_BLEND_FACTOR_ONE;

		switch(blendOperationState)
		{
		case VK_BLEND_OP_ADD:
		case VK_BLEND_OP_SUBTRACT:
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			return sourceBlendFactorState;
		case VK_BLEND_OP_MIN:
			return VK_BLEND_FACTOR_ONE;
		case VK_BLEND_OP_MAX:
			return VK_BLEND_FACTOR_ONE;
		default:
			ASSERT(false);
		}

		return sourceBlendFactorState;
	}

	VkBlendFactor Context::destBlendFactor()
	{
		if(!alphaBlendEnable) return VK_BLEND_FACTOR_ONE;

		switch(blendOperationState)
		{
		case VK_BLEND_OP_ADD:
		case VK_BLEND_OP_SUBTRACT:
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			return destBlendFactorState;
		case VK_BLEND_OP_MIN:
			return VK_BLEND_FACTOR_ONE;
		case VK_BLEND_OP_MAX:
			return VK_BLEND_FACTOR_ONE;
		default:
			ASSERT(false);
		}

		return destBlendFactorState;
	}

	VkBlendOp Context::blendOperation()
	{
		if(!alphaBlendEnable) return VK_BLEND_OP_SRC_EXT;

		switch(blendOperationState)
		{
		case VK_BLEND_OP_ADD:
			if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO)
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;
				}
				else
				{
					return VK_BLEND_OP_DST_EXT;
				}
			}
			else if(sourceBlendFactor() == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_ADD;
				}
			}
			else
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_ADD;
				}
			}
		case VK_BLEND_OP_SUBTRACT:
			if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO)
			{
				return VK_BLEND_OP_ZERO_EXT;   // Negative, clamped to zero
			}
			else if(sourceBlendFactor() == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_SUBTRACT;
				}
			}
			else
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_SUBTRACT;
				}
			}
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO)
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;
				}
				else
				{
					return VK_BLEND_OP_DST_EXT;
				}
			}
			else if(sourceBlendFactor() == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;   // Negative, clamped to zero
				}
				else
				{
					return VK_BLEND_OP_REVERSE_SUBTRACT;
				}
			}
			else
			{
				if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;   // Negative, clamped to zero
				}
				else
				{
					return VK_BLEND_OP_REVERSE_SUBTRACT;
				}
			}
		case VK_BLEND_OP_MIN:
			return VK_BLEND_OP_MIN;
		case VK_BLEND_OP_MAX:
			return VK_BLEND_OP_MAX;
		default:
			ASSERT(false);
		}

		return blendOperationState;
	}

	VkBlendFactor Context::sourceBlendFactorAlpha()
	{
		if(!separateAlphaBlendEnable)
		{
			return sourceBlendFactor();
		}
		else
		{
			switch(blendOperationStateAlpha)
			{
			case VK_BLEND_OP_ADD:
			case VK_BLEND_OP_SUBTRACT:
			case VK_BLEND_OP_REVERSE_SUBTRACT:
				return sourceBlendFactorStateAlpha;
			case VK_BLEND_OP_MIN:
				return VK_BLEND_FACTOR_ONE;
			case VK_BLEND_OP_MAX:
				return VK_BLEND_FACTOR_ONE;
			default:
				ASSERT(false);
			}

			return sourceBlendFactorStateAlpha;
		}
	}

	VkBlendFactor Context::destBlendFactorAlpha()
	{
		if(!separateAlphaBlendEnable)
		{
			return destBlendFactor();
		}
		else
		{
			switch(blendOperationStateAlpha)
			{
			case VK_BLEND_OP_ADD:
			case VK_BLEND_OP_SUBTRACT:
			case VK_BLEND_OP_REVERSE_SUBTRACT:
				return destBlendFactorStateAlpha;
			case VK_BLEND_OP_MIN:
				return VK_BLEND_FACTOR_ONE;
			case VK_BLEND_OP_MAX:
				return VK_BLEND_FACTOR_ONE;
			default:
				ASSERT(false);
			}

			return destBlendFactorStateAlpha;
		}
	}

	VkBlendOp Context::blendOperationAlpha()
	{
		if(!separateAlphaBlendEnable)
		{
			return blendOperation();
		}
		else
		{
			switch(blendOperationStateAlpha)
			{
			case VK_BLEND_OP_ADD:
				if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_ZERO_EXT;
					}
					else
					{
						return VK_BLEND_OP_DST_EXT;
					}
				}
				else if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_SRC_EXT;
					}
					else
					{
						return VK_BLEND_OP_ADD;
					}
				}
				else
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_SRC_EXT;
					}
					else
					{
						return VK_BLEND_OP_ADD;
					}
				}
			case VK_BLEND_OP_SUBTRACT:
				if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;   // Negative, clamped to zero
				}
				else if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_SRC_EXT;
					}
					else
					{
						return VK_BLEND_OP_SUBTRACT;
					}
				}
				else
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_SRC_EXT;
					}
					else
					{
						return VK_BLEND_OP_SUBTRACT;
					}
				}
			case VK_BLEND_OP_REVERSE_SUBTRACT:
				if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_ZERO_EXT;
					}
					else
					{
						return VK_BLEND_OP_DST_EXT;
					}
				}
				else if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_ZERO_EXT;   // Negative, clamped to zero
					}
					else
					{
						return VK_BLEND_OP_REVERSE_SUBTRACT;
					}
				}
				else
				{
					if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
					{
						return VK_BLEND_OP_ZERO_EXT;   // Negative, clamped to zero
					}
					else
					{
						return VK_BLEND_OP_ZERO_EXT;
					}
				}
			case VK_BLEND_OP_MIN:
				return VK_BLEND_OP_MIN;
			case VK_BLEND_OP_MAX:
				return VK_BLEND_OP_MAX;
			default:
				ASSERT(false);
			}

			return blendOperationStateAlpha;
		}
	}

	bool Context::perspectiveActive()
	{
		if(!colorUsed())
		{
			return false;
		}

		if(!perspectiveCorrection)
		{
			return false;
		}

		if(isDrawPoint())
		{
			return false;
		}

		return true;
	}

	VkFormat Context::renderTargetInternalFormat(int index)
	{
		if(renderTarget[index])
		{
			return renderTarget[index]->getFormat();
		}
		else
		{
			return VK_FORMAT_UNDEFINED;
		}
	}

	bool Context::colorWriteActive()
	{
		for (int i = 0; i < RENDERTARGETS; i++)
		{
			if (colorWriteActive(i))
			{
				return true;
			}
		}

		return false;
	}

	int Context::colorWriteActive(int index)
	{
		if(!renderTarget[index] || renderTarget[index]->getFormat() == VK_FORMAT_UNDEFINED)
		{
			return 0;
		}

		if(blendOperation() == VK_BLEND_OP_DST_EXT && destBlendFactor() == VK_BLEND_FACTOR_ONE &&
		   (!separateAlphaBlendEnable || (blendOperationAlpha() == VK_BLEND_OP_DST_EXT && destBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)))
		{
			return 0;
		}

		return colorWriteMask[index];
	}

	bool Context::colorUsed()
	{
		return colorWriteActive() || alphaTestActive() || (pixelShader && pixelShader->getModes().ContainsKill);
	}
}
