// 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 "Pipeline/SpirvShader.hpp"
#include "System/Memory.hpp"
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkImageView.hpp"

#include <string.h>

namespace sw {

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

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

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

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

void Context::init()
{
	for(int i = 0; i < RENDERTARGETS; ++i)
	{
		renderTarget[i] = nullptr;
	}

	depthBuffer = nullptr;
	stencilBuffer = nullptr;

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

	robustBufferAccess = false;

	rasterizerDiscard = false;

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

	cullMode = VK_CULL_MODE_FRONT_BIT;
	frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
	provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
	lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;

	depthBias = 0.0f;
	slopeDepthBias = 0.0f;

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

	pipelineLayout = nullptr;

	pixelShader = nullptr;
	vertexShader = nullptr;

	occlusionEnabled = false;

	lineWidth = 1.0f;

	sampleMask = 0xFFFFFFFF;
	alphaToCoverage = false;
}

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

	return depthWriteEnable;
}

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

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

void Context::setBlendState(int index, BlendState state)
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	blendState[index] = state;
}

BlendState Context::getBlendState(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	BlendState activeBlendState;
	activeBlendState.alphaBlendEnable = alphaBlendActive(index);
	activeBlendState.sourceBlendFactor = sourceBlendFactor(index);
	activeBlendState.destBlendFactor = destBlendFactor(index);
	activeBlendState.blendOperation = blendOperation(index);
	activeBlendState.sourceBlendFactorAlpha = sourceBlendFactorAlpha(index);
	activeBlendState.destBlendFactorAlpha = destBlendFactorAlpha(index);
	activeBlendState.blendOperationAlpha = blendOperationAlpha(index);
	return activeBlendState;
}

bool Context::alphaBlendActive(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	if(!blendState[index].alphaBlendEnable)
	{
		return false;
	}

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

	bool colorBlend = !(blendOperation(index) == VK_BLEND_OP_SRC_EXT && sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE);
	bool alphaBlend = !(blendOperationAlpha(index) == VK_BLEND_OP_SRC_EXT && sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE);

	return colorBlend || alphaBlend;
}

VkBlendFactor Context::sourceBlendFactor(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	if(!blendState[index].alphaBlendEnable) return VK_BLEND_FACTOR_ONE;

	switch(blendState[index].blendOperation)
	{
		case VK_BLEND_OP_ADD:
		case VK_BLEND_OP_SUBTRACT:
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			return blendState[index].sourceBlendFactor;
		case VK_BLEND_OP_MIN:
			return VK_BLEND_FACTOR_ONE;
		case VK_BLEND_OP_MAX:
			return VK_BLEND_FACTOR_ONE;
		default:
			ASSERT(false);
	}

	return blendState[index].sourceBlendFactor;
}

VkBlendFactor Context::destBlendFactor(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	if(!blendState[index].alphaBlendEnable) return VK_BLEND_FACTOR_ONE;

	switch(blendState[index].blendOperation)
	{
		case VK_BLEND_OP_ADD:
		case VK_BLEND_OP_SUBTRACT:
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			return blendState[index].destBlendFactor;
		case VK_BLEND_OP_MIN:
			return VK_BLEND_FACTOR_ONE;
		case VK_BLEND_OP_MAX:
			return VK_BLEND_FACTOR_ONE;
		default:
			ASSERT(false);
	}

	return blendState[index].destBlendFactor;
}

bool Context::allTargetsColorClamp() const
{
	// TODO: remove all of this and support VkPhysicalDeviceFeatures::independentBlend instead
	for(int i = 0; i < RENDERTARGETS; i++)
	{
		if(renderTarget[i] && renderTarget[i]->getFormat().isFloatFormat())
		{
			return false;
		}
	}

	return true;
}

VkBlendOp Context::blendOperation(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	if(!blendState[index].alphaBlendEnable) return VK_BLEND_OP_SRC_EXT;

	switch(blendState[index].blendOperation)
	{
		case VK_BLEND_OP_ADD:
			if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;
				}
				else
				{
					return VK_BLEND_OP_DST_EXT;
				}
			}
			else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_ADD;
				}
			}
			else
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_ADD;
				}
			}
		case VK_BLEND_OP_SUBTRACT:
			if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
			{
				return VK_BLEND_OP_ZERO_EXT;  // Negative, clamped to zero
			}
			else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_SUBTRACT;
				}
			}
			else
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_SUBTRACT;
				}
			}
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;
				}
				else
				{
					return VK_BLEND_OP_DST_EXT;
				}
			}
			else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
				{
					return VK_BLEND_OP_ZERO_EXT;  // Negative, clamped to zero
				}
				else
				{
					return VK_BLEND_OP_REVERSE_SUBTRACT;
				}
			}
			else
			{
				if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
				{
					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 blendState[index].blendOperation;
}

VkBlendFactor Context::sourceBlendFactorAlpha(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	switch(blendState[index].blendOperationAlpha)
	{
		case VK_BLEND_OP_ADD:
		case VK_BLEND_OP_SUBTRACT:
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			return blendState[index].sourceBlendFactorAlpha;
		case VK_BLEND_OP_MIN:
			return VK_BLEND_FACTOR_ONE;
		case VK_BLEND_OP_MAX:
			return VK_BLEND_FACTOR_ONE;
		default:
			ASSERT(false);
	}

	return blendState[index].sourceBlendFactorAlpha;
}

VkBlendFactor Context::destBlendFactorAlpha(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	switch(blendState[index].blendOperationAlpha)
	{
		case VK_BLEND_OP_ADD:
		case VK_BLEND_OP_SUBTRACT:
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			return blendState[index].destBlendFactorAlpha;
		case VK_BLEND_OP_MIN:
			return VK_BLEND_FACTOR_ONE;
		case VK_BLEND_OP_MAX:
			return VK_BLEND_FACTOR_ONE;
		default:
			ASSERT(false);
	}

	return blendState[index].destBlendFactorAlpha;
}

VkBlendOp Context::blendOperationAlpha(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	switch(blendState[index].blendOperationAlpha)
	{
		case VK_BLEND_OP_ADD:
			if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;
				}
				else
				{
					return VK_BLEND_OP_DST_EXT;
				}
			}
			else if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_ADD;
				}
			}
			else
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_ADD;
				}
			}
		case VK_BLEND_OP_SUBTRACT:
			if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
			{
				return VK_BLEND_OP_ZERO_EXT;  // Negative, clamped to zero
			}
			else if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_SUBTRACT;
				}
			}
			else
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_SRC_EXT;
				}
				else
				{
					return VK_BLEND_OP_SUBTRACT;
				}
			}
		case VK_BLEND_OP_REVERSE_SUBTRACT:
			if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
				{
					return VK_BLEND_OP_ZERO_EXT;
				}
				else
				{
					return VK_BLEND_OP_DST_EXT;
				}
			}
			else if(sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE)
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
				{
					return VK_BLEND_OP_ZERO_EXT;  // Negative, clamped to zero
				}
				else
				{
					return VK_BLEND_OP_REVERSE_SUBTRACT;
				}
			}
			else
			{
				if(destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
				{
					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 blendState[index].blendOperationAlpha;
}

VkFormat Context::renderTargetInternalFormat(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

	if(renderTarget[index])
	{
		return renderTarget[index]->getFormat();
	}
	else
	{
		return VK_FORMAT_UNDEFINED;
	}
}

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

	return false;
}

int Context::colorWriteActive(int index) const
{
	ASSERT((index >= 0) && (index < RENDERTARGETS));

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

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

	return colorWriteMask[index];
}

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

}  // namespace sw
