// 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.

#ifndef sw_PixelProcessor_hpp
#define sw_PixelProcessor_hpp

#include "Context.hpp"
#include "Memset.hpp"
#include "RoutineCache.hpp"
#include "Vulkan/VkFormat.hpp"

#include <memory>

namespace sw {

struct DrawData;
struct Primitive;
class SpirvShader;

using RasterizerFunction = FunctionT<void(const vk::Device *device, const Primitive *primitive, int count, int cluster, int clusterCount, DrawData *draw)>;

class PixelProcessor
{
public:
	struct States : Memset<States>
	{
		// Same as VkStencilOpState, but with no reference, as it's not part of the state
		// (it doesn't require a different program to be generated)
		struct StencilOpState
		{
			VkStencilOp failOp;
			VkStencilOp passOp;
			VkStencilOp depthFailOp;
			VkCompareOp compareOp;
			uint32_t compareMask;
			uint32_t writeMask;

			void operator=(const VkStencilOpState &rhs)
			{
				failOp = rhs.failOp;
				passOp = rhs.passOp;
				depthFailOp = rhs.depthFailOp;
				compareOp = rhs.compareOp;
				compareMask = rhs.compareMask;
				writeMask = rhs.writeMask;
			}
		};

		States()
		    : Memset(this, 0)
		{}

		uint32_t computeHash();

		uint64_t shaderID;
		uint32_t pipelineLayoutIdentifier;

		unsigned int numClipDistances;
		unsigned int numCullDistances;

		VkCompareOp depthCompareMode;
		bool depthWriteEnable;

		bool stencilActive;
		StencilOpState frontStencil;
		StencilOpState backStencil;

		bool depthTestActive;
		bool depthBoundsTestActive;
		bool occlusionEnabled;
		bool perspective;

		vk::BlendState blendState[MAX_COLOR_BUFFERS];

		unsigned int colorWriteMask;
		vk::Format colorFormat[MAX_COLOR_BUFFERS];
		unsigned int multiSampleCount;
		unsigned int multiSampleMask;
		bool enableMultiSampling;
		bool alphaToCoverage;
		bool centroid;
		bool sampleShadingEnabled;
		float minSampleShading;
		float minDepthBounds;
		float maxDepthBounds;
		VkFrontFace frontFace;
		vk::Format depthFormat;
		bool depthBias;
		bool depthClamp;

		float minDepthClamp;
		float maxDepthClamp;
	};

	struct State : States
	{
		bool operator==(const State &state) const;

		int colorWriteActive(int index) const
		{
			return (colorWriteMask >> (index * 4)) & 0xF;
		}

		uint32_t hash;
	};

	struct Stencil
	{
		int64_t testMaskQ;
		int64_t referenceMaskedQ;
		int64_t referenceMaskedSignedQ;
		int64_t writeMaskQ;
		int64_t invWriteMaskQ;
		int64_t referenceQ;

		void set(int reference, int testMask, int writeMask)
		{
			referenceQ = replicate(reference);
			testMaskQ = replicate(testMask);
			writeMaskQ = replicate(writeMask);
			invWriteMaskQ = ~writeMaskQ;
			referenceMaskedQ = referenceQ & testMaskQ;
			referenceMaskedSignedQ = replicate(((reference & testMask) + 0x80) & 0xFF);
		}

		static int64_t replicate(int b)
		{
			int64_t w = b & 0xFF;

			return (w << 0) | (w << 8) | (w << 16) | (w << 24) | (w << 32) | (w << 40) | (w << 48) | (w << 56);
		}
	};

	struct Factor
	{
		float4 blendConstantF;     // Unclamped for floating-point attachment formats.
		float4 invBlendConstantF;  // Unclamped for floating-point attachment formats.
		float4 blendConstantU;     // Clamped to [0,1] for unsigned fixed-point attachment formats.
		float4 invBlendConstantU;  // Clamped to [0,1] for unsigned fixed-point attachment formats.
		float4 blendConstantS;     // Clamped to [-1,1] for signed fixed-point attachment formats.
		float4 invBlendConstantS;  // Clamped to [-1,1] for signed fixed-point attachment formats.
	};

public:
	using RoutineType = RasterizerFunction::RoutineType;

	PixelProcessor();

	void setBlendConstant(const float4 &blendConstant);

	const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments, bool occlusionEnabled) const;
	RoutineType routine(const State &state, const vk::PipelineLayout *pipelineLayout,
	                    const SpirvShader *pixelShader, const vk::DescriptorSet::Bindings &descriptorSets);
	void setRoutineCacheSize(int routineCacheSize);

	// Other semi-constants
	Factor factor;

private:
	using RoutineCacheType = RoutineCache<State, RasterizerFunction::CFunctionType>;
	std::unique_ptr<RoutineCacheType> routineCache;
};

}  // namespace sw

namespace std {

template<>
struct hash<sw::PixelProcessor::State>
{
	uint64_t operator()(const sw::PixelProcessor::State &state) const
	{
		return state.hash;
	}
};

}  // namespace std

#endif  // sw_PixelProcessor_hpp
