// 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 "Color.hpp"
#include "Context.hpp"
#include "Memset.hpp"
#include "RoutineCache.hpp"

namespace sw
{
	class PixelShader;
	class Rasterizer;
	struct Texture;
	struct DrawData;
	struct Primitive;

	using RasterizerFunction = FunctionT<void(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;

			VkCompareOp depthCompareMode;
			bool depthWriteEnable;

			bool stencilActive;
			StencilOpState frontStencil;
			StencilOpState backStencil;

			bool depthTestActive;
			bool occlusionEnabled;
			bool perspective;
			bool depthClamp;

			BlendState blendState[RENDERTARGETS];

			unsigned int colorWriteMask;
			VkFormat targetFormat[RENDERTARGETS];
			unsigned int multiSample;
			unsigned int multiSampleMask;
			bool alphaToCoverage;
			bool centroid;
			VkFrontFace frontFace;
			VkFormat depthFormat;
		};

		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
		{
			word4 alphaReference4;

			word4 blendConstant4W[4];
			float4 blendConstant4F[4];
			word4 invBlendConstant4W[4];
			float4 invBlendConstant4F[4];
		};

	public:
		using RoutineType = RasterizerFunction::RoutineType;

		PixelProcessor();

		virtual ~PixelProcessor();

		void setBlendConstant(const Color<float> &blendConstant);

	protected:
		const State update(const Context* context) const;
		RoutineType routine(const State &state, vk::PipelineLayout const *pipelineLayout,
		                                 SpirvShader const *pixelShader, const vk::DescriptorSet::Bindings &descriptorSets);
		void setRoutineCacheSize(int routineCacheSize);

		// Other semi-constants
		Factor factor;

	private:
		using RoutineCacheType = RoutineCacheT<State, RasterizerFunction::CFunctionType>;
		RoutineCacheType *routineCache;
	};
}

#endif   // sw_PixelProcessor_hpp
