// 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_Renderer_hpp
#define sw_Renderer_hpp

#include "VertexProcessor.hpp"
#include "PixelProcessor.hpp"
#include "SetupProcessor.hpp"
#include "Plane.hpp"
#include "Primitive.hpp"
#include "Blitter.hpp"
#include "Device/Config.hpp"
#include "Vulkan/VkDescriptorSet.hpp"

#include "marl/pool.h"
#include "marl/finally.h"
#include "marl/ticket.h"

#include <atomic>
#include <list>
#include <mutex>
#include <thread>

namespace vk
{
	class DescriptorSet;
	class Device;
	class Query;
}

namespace sw
{
	struct DrawCall;
	class PixelShader;
	class VertexShader;
	struct Task;
	class TaskEvents;
	class Resource;
	struct Constants;

	static constexpr int MaxBatchSize = 128;
	static constexpr int MaxBatchCount = 16;
	static constexpr int MaxClusterCount = 16;
	static constexpr int MaxDrawCount = 16;

	using TriangleBatch = std::array<Triangle, MaxBatchSize>;
	using PrimitiveBatch = std::array<Primitive, MaxBatchSize>;

	struct DrawData
	{
		const Constants *constants;

		vk::DescriptorSet::Bindings descriptorSets = {};
		vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};

		const void *input[MAX_INTERFACE_COMPONENTS / 4];
		unsigned int robustnessSize[MAX_INTERFACE_COMPONENTS / 4];
		unsigned int stride[MAX_INTERFACE_COMPONENTS / 4];
		const void *indices;

		int instanceID;
		int baseVertex;
		float lineWidth;
		int viewID;

		PixelProcessor::Stencil stencil[2];   // clockwise, counterclockwise
		PixelProcessor::Factor factor;
		unsigned int occlusion[MaxClusterCount];   // Number of pixels passing depth test

		float4 Wx16;
		float4 Hx16;
		float4 X0x16;
		float4 Y0x16;
		float4 halfPixelX;
		float4 halfPixelY;
		float viewportHeight;
		float slopeDepthBias;
		float depthRange;
		float depthNear;

		unsigned int *colorBuffer[RENDERTARGETS];
		int colorPitchB[RENDERTARGETS];
		int colorSliceB[RENDERTARGETS];
		float *depthBuffer;
		int depthPitchB;
		int depthSliceB;
		unsigned char *stencilBuffer;
		int stencilPitchB;
		int stencilSliceB;

		int scissorX0;
		int scissorX1;
		int scissorY0;
		int scissorY1;

		float4 a2c0;
		float4 a2c1;
		float4 a2c2;
		float4 a2c3;

		PushConstantStorage pushConstants;
	};

	struct DrawCall
	{
		struct BatchData
		{
			using Pool = marl::BoundedPool<BatchData, MaxBatchCount, marl::PoolPolicy::Preserve>;

			TriangleBatch triangles;
			PrimitiveBatch primitives;
			VertexTask vertexTask;
			unsigned int id;
			unsigned int firstPrimitive;
			unsigned int numPrimitives;
			int numVisible;
			marl::Ticket clusterTickets[MaxClusterCount];
		};

		using Pool = marl::BoundedPool<DrawCall, MaxDrawCount, marl::PoolPolicy::Preserve>;
		using SetupFunction = int(*)(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);

		DrawCall();
		~DrawCall();

		static void run(const marl::Loan<DrawCall>& draw, marl::Ticket::Queue* tickets, marl::Ticket::Queue clusterQueues[MaxClusterCount]);
		static void processVertices(DrawCall* draw, BatchData* batch);
		static void processPrimitives(DrawCall* draw, BatchData* batch);
		static void processPixels(const marl::Loan<DrawCall>& draw, const marl::Loan<BatchData>& batch, const std::shared_ptr<marl::Finally>& finally);
		void setup();
		void teardown();

		int id;

		BatchData::Pool *batchDataPool;
		unsigned int numPrimitives;
		unsigned int numPrimitivesPerBatch;
		unsigned int numBatches;

		VkPrimitiveTopology topology;
		VkIndexType indexType;

		std::shared_ptr<Routine> vertexRoutine;
		std::shared_ptr<Routine> setupRoutine;
		std::shared_ptr<Routine> pixelRoutine;

		VertexProcessor::RoutinePointer vertexPointer;
		SetupProcessor::RoutinePointer setupPointer;
		PixelProcessor::RoutinePointer pixelPointer;

		SetupFunction setupPrimitives;
		SetupProcessor::State setupState;

		vk::ImageView *renderTarget[RENDERTARGETS];
		vk::ImageView *depthBuffer;
		vk::ImageView *stencilBuffer;
		TaskEvents *events;

		vk::Query* occlusionQuery;

		DrawData *data;

		static void processPrimitiveVertices(
				unsigned int triangleIndicesOut[MaxBatchSize + 1][3],
				const void *primitiveIndices,
				VkIndexType indexType,
				unsigned int start,
				unsigned int triangleCount,
				VkPrimitiveTopology topology);

		static int setupSolidTriangles(Triangle* triangles, Primitive* primitives, const DrawCall* drawCall, int count);
		static int setupWireframeTriangles(Triangle* triangles, Primitive* primitives, const DrawCall* drawCall, int count);
		static int setupPointTriangles(Triangle* triangles, Primitive* primitives, const DrawCall* drawCall, int count);
		static int setupLines(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
		static int setupPoints(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);

		static bool setupLine(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
		static bool setupPoint(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
	};

	class alignas(16) Renderer : public VertexProcessor, public PixelProcessor, public SetupProcessor
	{
	public:
		Renderer(vk::Device* device);

		virtual ~Renderer();

		void* operator new(size_t size);
		void operator delete(void* mem);

		bool hasOcclusionQuery() const { return occlusionQuery != nullptr; }

		void draw(const sw::Context* context, VkIndexType indexType, unsigned int count, int baseVertex,
				TaskEvents *events, int instanceID, int viewID, void *indexBuffer,
				PushConstantStorage const & pushConstants, bool update = true);

		// Viewport & Clipper
		void setViewport(const VkViewport &viewport);
		void setScissor(const VkRect2D &scissor);

		void addQuery(vk::Query *query);
		void removeQuery(vk::Query *query);

		void advanceInstanceAttributes(Stream* inputs);

		void synchronize();

	private:
		VkViewport viewport;
		VkRect2D scissor;

		DrawCall::Pool drawCallPool;
		DrawCall::BatchData::Pool batchDataPool;

		std::atomic<int> nextDrawID = {0};

		vk::Query *occlusionQuery = nullptr;
		marl::Ticket::Queue drawTickets;
		marl::Ticket::Queue clusterQueues[MaxClusterCount];

		VertexProcessor::State vertexState;
		SetupProcessor::State setupState;
		PixelProcessor::State pixelState;

		std::shared_ptr<Routine> vertexRoutine;
		std::shared_ptr<Routine> setupRoutine;
		std::shared_ptr<Routine> pixelRoutine;

		vk::Device* device;
	};

}

#endif   // sw_Renderer_hpp
