// 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 "Blitter.hpp"
#include "PixelProcessor.hpp"
#include "Primitive.hpp"
#include "SetupProcessor.hpp"
#include "VertexProcessor.hpp"
#include "Device/Config.hpp"
#include "Vulkan/VkDescriptorSet.hpp"

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

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

namespace vk {

class DescriptorSet;
class Device;
class Query;
class PipelineLayout;

}  // namespace vk

namespace sw {

class CountedEvent;
struct DrawCall;
class PixelShader;
class VertexShader;
struct Task;
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 WxF;
	float4 HxF;
	float4 X0xF;
	float4 Y0xF;
	float4 halfPixelX;
	float4 halfPixelY;
	float viewportHeight;
	float depthRange;
	float depthNear;
	float minimumResolvableDepthDifference;
	float constantDepthBias;
	float slopeDepthBias;
	float depthBiasClamp;

	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;
	VkProvokingVertexModeEXT provokingVertexMode;
	VkIndexType indexType;
	VkLineRasterizationModeEXT lineRasterizationMode;

	VertexProcessor::RoutineType vertexRoutine;
	SetupProcessor::RoutineType setupRoutine;
	PixelProcessor::RoutineType pixelRoutine;
	bool containsImageWrite;

	SetupFunction setupPrimitives;
	SetupProcessor::State setupState;

	vk::Device *device;
	vk::ImageView *renderTarget[RENDERTARGETS];
	vk::ImageView *depthBuffer;
	vk::ImageView *stencilBuffer;
	vk::DescriptorSet::Array descriptorSetObjects;
	const vk::PipelineLayout *pipelineLayout;
	sw::CountedEvent *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,
	    VkProvokingVertexModeEXT provokingVertexMode);

	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:
	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,
	          CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D &framebufferExtent,
	          PushConstantStorage const &pushConstants, bool update = true);

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

	void setBlendConstant(const float4 &blendConstant);

	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 vertexProcessor;
	PixelProcessor pixelProcessor;
	SetupProcessor setupProcessor;

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

	VertexProcessor::RoutineType vertexRoutine;
	SetupProcessor::RoutineType setupRoutine;
	PixelProcessor::RoutineType pixelRoutine;

	vk::Device *device;
};

}  // namespace sw

#endif  // sw_Renderer_hpp
