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

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

#include <atomic>

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
{
	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;
	bool depthClipEnable;

	unsigned int *colorBuffer[MAX_COLOR_BUFFERS];
	int colorPitchB[MAX_COLOR_BUFFERS];
	int colorSliceB[MAX_COLOR_BUFFERS];
	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;

	vk::Pipeline::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 (*)(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);

	DrawCall();
	~DrawCall();

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

	int id;

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

	VkPrimitiveTopology topology;
	VkProvokingVertexModeEXT provokingVertexMode;
	VkIndexType indexType;
	VkLineRasterizationModeEXT lineRasterizationMode;

	bool depthClipEnable;

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

	SetupFunction setupPrimitives;
	SetupProcessor::State setupState;

	vk::ImageView *colorBuffer[MAX_COLOR_BUFFERS];
	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(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
	static int setupWireframeTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
	static int setupPointTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
	static int setupLines(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
	static int setupPoints(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);

	static bool setupLine(vk::Device *device, Primitive &primitive, Triangle &triangle, const DrawCall &draw);
	static bool setupPoint(vk::Device *device, 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 vk::GraphicsPipeline *pipeline, const vk::DynamicState &dynamicState, unsigned int count, int baseVertex,
	          CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D &framebufferExtent,
	          vk::Pipeline::PushConstantStorage const &pushConstants, bool update = true);

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

	void synchronize();

private:
	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
