// Copyright 2020 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 vk_Context_hpp
#define vk_Context_hpp

#include "Config.hpp"
#include "Memset.hpp"
#include "Stream.hpp"
#include "System/Types.hpp"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkFormat.hpp"

#include <vector>

namespace vk {

class Buffer;
class Device;
class ImageView;
class PipelineLayout;
class RenderPass;

struct VertexInputBinding
{
	Buffer *buffer = nullptr;
	VkDeviceSize offset = 0;
	VkDeviceSize size = 0;
	VkDeviceSize stride = 0;
};

struct IndexBuffer
{
	inline VkIndexType getIndexType() const { return indexType; }
	void setIndexBufferBinding(const VertexInputBinding &indexBufferBinding, VkIndexType type);
	void getIndexBuffers(VkPrimitiveTopology topology, uint32_t count, uint32_t first, bool indexed, bool hasPrimitiveRestartEnable, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const;

private:
	int bytesPerIndex() const;

	VertexInputBinding binding;
	VkIndexType indexType;
};

struct Attachments
{
	ImageView *colorBuffer[sw::MAX_COLOR_BUFFERS] = {};
	ImageView *depthBuffer = nullptr;
	ImageView *stencilBuffer = nullptr;

	VkFormat colorFormat(int index) const;
	VkFormat depthFormat() const;
};

struct Inputs
{
	Inputs(const VkPipelineVertexInputStateCreateInfo *vertexInputState);

	void updateDescriptorSets(const DescriptorSet::Array &dso,
	                          const DescriptorSet::Bindings &ds,
	                          const DescriptorSet::DynamicOffsets &ddo);
	inline const DescriptorSet::Array &getDescriptorSetObjects() const { return descriptorSetObjects; }
	inline const DescriptorSet::Bindings &getDescriptorSets() const { return descriptorSets; }
	inline const DescriptorSet::DynamicOffsets &getDescriptorDynamicOffsets() const { return descriptorDynamicOffsets; }
	inline const sw::Stream &getStream(uint32_t i) const { return stream[i]; }

	void bindVertexInputs(int firstInstance, bool dynamicInstanceStride);
	void setVertexInputBinding(const VertexInputBinding vertexInputBindings[]);
	void advanceInstanceAttributes(bool dynamicInstanceStride);
	VkDeviceSize getVertexStride(uint32_t i, bool dynamicVertexStride) const;
	VkDeviceSize getInstanceStride(uint32_t i, bool dynamicVertexStride) const;

private:
	VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
	DescriptorSet::Array descriptorSetObjects = {};
	DescriptorSet::Bindings descriptorSets = {};
	DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
	sw::Stream stream[sw::MAX_INTERFACE_COMPONENTS / 4];
};

struct MultisampleState
{
	bool sampleShadingEnable = false;
	bool alphaToCoverage = false;

	int sampleCount = 0;
	unsigned int multiSampleMask = 0;
	float minSampleShading = 0.0f;

	void set(const VkPipelineMultisampleStateCreateInfo *multisampleState);
};

struct BlendState : sw::Memset<BlendState>
{
	BlendState()
	    : Memset(this, 0)
	{}

	BlendState(bool alphaBlendEnable,
	           VkBlendFactor sourceBlendFactor,
	           VkBlendFactor destBlendFactor,
	           VkBlendOp blendOperation,
	           VkBlendFactor sourceBlendFactorAlpha,
	           VkBlendFactor destBlendFactorAlpha,
	           VkBlendOp blendOperationAlpha)
	    : Memset(this, 0)
	    , alphaBlendEnable(alphaBlendEnable)
	    , sourceBlendFactor(sourceBlendFactor)
	    , destBlendFactor(destBlendFactor)
	    , blendOperation(blendOperation)
	    , sourceBlendFactorAlpha(sourceBlendFactorAlpha)
	    , destBlendFactorAlpha(destBlendFactorAlpha)
	    , blendOperationAlpha(blendOperationAlpha)
	{}

	bool alphaBlendEnable;
	VkBlendFactor sourceBlendFactor;
	VkBlendFactor destBlendFactor;
	VkBlendOp blendOperation;
	VkBlendFactor sourceBlendFactorAlpha;
	VkBlendFactor destBlendFactorAlpha;
	VkBlendOp blendOperationAlpha;
};

struct DynamicState
{
	VkViewport viewport = {};
	VkRect2D scissor = {};
	sw::float4 blendConstants = {};
	float depthBiasConstantFactor = 0.0f;
	float depthBiasClamp = 0.0f;
	float depthBiasSlopeFactor = 0.0f;
	float minDepthBounds = 0.0f;
	float maxDepthBounds = 0.0f;
	float lineWidth = 0.0f;

	VkCullModeFlags cullMode = VK_CULL_MODE_NONE;
	VkBool32 depthBoundsTestEnable = VK_FALSE;
	VkCompareOp depthCompareOp = VK_COMPARE_OP_NEVER;
	VkBool32 depthTestEnable = VK_FALSE;
	VkBool32 depthWriteEnable = VK_FALSE;
	VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
	VkPrimitiveTopology primitiveTopology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
	uint32_t scissorCount = 0;
	VkRect2D scissors[vk::MAX_VIEWPORTS] = {};
	VkStencilFaceFlags faceMask = (VkStencilFaceFlags)0;
	VkStencilOpState frontStencil = {};
	VkStencilOpState backStencil = {};
	VkBool32 stencilTestEnable = VK_FALSE;
	uint32_t viewportCount = 0;
	VkRect2D viewports[vk::MAX_VIEWPORTS] = {};
	VkBool32 rasterizerDiscardEnable = VK_FALSE;
	VkBool32 depthBiasEnable = VK_FALSE;
	VkBool32 primitiveRestartEnable = VK_FALSE;
};

struct VertexInputInterfaceDynamicStateFlags
{
	bool dynamicPrimitiveRestartEnable : 1;
	bool dynamicPrimitiveTopology : 1;
	bool dynamicVertexInputBindingStride : 1;
};

struct PreRasterizationDynamicStateFlags
{
	bool dynamicLineWidth : 1;
	bool dynamicDepthBias : 1;
	bool dynamicDepthBiasEnable : 1;
	bool dynamicCullMode : 1;
	bool dynamicFrontFace : 1;
	bool dynamicViewport : 1;
	bool dynamicScissor : 1;
	bool dynamicViewportWithCount : 1;
	bool dynamicScissorWithCount : 1;
	bool dynamicRasterizerDiscardEnable : 1;
};

struct FragmentDynamicStateFlags
{
	bool dynamicDepthTestEnable : 1;
	bool dynamicDepthWriteEnable : 1;
	bool dynamicDepthBoundsTestEnable : 1;
	bool dynamicDepthBounds : 1;
	bool dynamicDepthCompareOp : 1;
	bool dynamicStencilTestEnable : 1;
	bool dynamicStencilOp : 1;
	bool dynamicStencilCompareMask : 1;
	bool dynamicStencilWriteMask : 1;
	bool dynamicStencilReference : 1;
};

struct FragmentOutputInterfaceDynamicStateFlags
{
	bool dynamicBlendConstants : 1;
};

struct DynamicStateFlags
{
	VertexInputInterfaceDynamicStateFlags vertexInputInterface;
	PreRasterizationDynamicStateFlags preRasterization;
	FragmentDynamicStateFlags fragment;
	FragmentOutputInterfaceDynamicStateFlags fragmentOutputInterface;
};

struct VertexInputInterfaceState
{
	void initialize(const VkPipelineVertexInputStateCreateInfo *vertexInputState,
	           const VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState,
	           const DynamicStateFlags &allDynamicStateFlags);

	void applyState(const DynamicState &dynamicState);

	inline VkPrimitiveTopology getTopology() const { return topology; }
	inline bool hasPrimitiveRestartEnable() const { return primitiveRestartEnable; }

	inline bool hasDynamicVertexStride() const { return dynamicStateFlags.dynamicVertexInputBindingStride; }
	inline bool hasDynamicTopology() const { return dynamicStateFlags.dynamicPrimitiveTopology; }
	inline bool hasDynamicPrimitiveRestartEnable() const { return dynamicStateFlags.dynamicPrimitiveRestartEnable; }

	bool isDrawPoint(bool polygonModeAware, VkPolygonMode polygonMode) const;
	bool isDrawLine(bool polygonModeAware, VkPolygonMode polygonMode) const;
	bool isDrawTriangle(bool polygonModeAware, VkPolygonMode polygonMode) const;

private:
	VertexInputInterfaceDynamicStateFlags dynamicStateFlags = {};

	bool primitiveRestartEnable = false;

	VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
};

struct PreRasterizationState
{
	void initialize(const vk::Device *device,
	           const VkPipelineViewportStateCreateInfo *viewportState,
	           const VkPipelineRasterizationStateCreateInfo *rasterizationState,
	           const vk::RenderPass *renderPass, uint32_t subpassIndex,
	           const VkPipelineRenderingCreateInfo *rendering,
	           const DynamicStateFlags &allDynamicStateFlags);

	void applyState(const DynamicState &dynamicState);

	inline VkCullModeFlags getCullMode() const { return cullMode; }
	inline VkFrontFace getFrontFace() const { return frontFace; }
	inline VkPolygonMode getPolygonMode() const { return polygonMode; }
	inline VkProvokingVertexModeEXT getProvokingVertexMode() const { return provokingVertexMode; }
	inline VkLineRasterizationModeEXT getLineRasterizationMode() const { return lineRasterizationMode; }

	inline bool hasRasterizerDiscard() const { return rasterizerDiscard; }

	inline float getConstantDepthBias() const { return depthBiasEnable ? constantDepthBias : 0; }
	inline float getSlopeDepthBias() const { return depthBiasEnable ? slopeDepthBias : 0; }
	inline float getDepthBiasClamp() const { return depthBiasEnable ? depthBiasClamp : 0; }

	inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; }
	inline bool getDepthClampEnable() const { return depthClampEnable; }
	inline bool getDepthClipEnable() const { return depthClipEnable; }
	inline bool getDepthClipNegativeOneToOne() const { return depthClipNegativeOneToOne; }

	inline float getLineWidth() const { return lineWidth; }

	inline const VkRect2D &getScissor() const { return scissor; }
	inline const VkViewport &getViewport() const { return viewport; }

private:
	PreRasterizationDynamicStateFlags dynamicStateFlags = {};

	bool rasterizerDiscard = false;
	bool depthClampEnable = false;
	bool depthClipEnable = false;
	bool depthClipNegativeOneToOne = false;
	bool depthBiasEnable = false;
	bool depthRangeUnrestricted = false;

	VkCullModeFlags cullMode = 0;
	VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
	VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
	VkProvokingVertexModeEXT provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
	VkLineRasterizationModeEXT lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;

	float depthBiasClamp = 0.0f;
	float constantDepthBias = 0.0f;
	float slopeDepthBias = 0.0f;

	float lineWidth = 0.0f;

	VkRect2D scissor = {};
	VkViewport viewport = {};
};

struct FragmentState
{
	void initialize(const VkPipelineDepthStencilStateCreateInfo *depthStencilState,
	           const vk::RenderPass *renderPass, uint32_t subpassIndex,
	           const VkPipelineRenderingCreateInfo *rendering,
	           const DynamicStateFlags &allDynamicStateFlags);

	void applyState(const DynamicState &dynamicState);

	inline VkStencilOpState getFrontStencil() const { return frontStencil; }
	inline VkStencilOpState getBackStencil() const { return backStencil; }

	inline float getMinDepthBounds() const { return minDepthBounds; }
	inline float getMaxDepthBounds() const { return maxDepthBounds; }

	inline VkCompareOp getDepthCompareMode() const { return depthCompareMode; }

	bool depthWriteActive(const Attachments &attachments) const;
	bool depthTestActive(const Attachments &attachments) const;
	bool stencilActive(const Attachments &attachments) const;
	bool depthBoundsTestActive(const Attachments &attachments) const;

private:
	void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo *depthStencilState);

	FragmentDynamicStateFlags dynamicStateFlags = {};

	bool depthTestEnable = false;
	bool depthWriteEnable = false;
	bool depthBoundsTestEnable = false;
	bool stencilEnable = false;

	float minDepthBounds = 0.0f;
	float maxDepthBounds = 0.0f;

	VkCompareOp depthCompareMode = VK_COMPARE_OP_NEVER;

	VkStencilOpState frontStencil = {};
	VkStencilOpState backStencil = {};

	// Note: if a pipeline library is created with the fragment state only, and sample shading
	// is enabled or a render pass is provided, VkPipelineMultisampleStateCreateInfo must be
	// provided.  This must identically match with the one provided for the fragment output
	// interface library.
	//
	// Currently, SwiftShader can always use the copy provided and stored in
	// FragmentOutputInterfaceState.  If a future optimization requires access to this state in
	// a pipeline library without fragment output interface, a copy of MultisampleState can be
	// placed here and initialized under the above condition.
	//
	// Ref: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap10.html#pipeline-graphics-subsets
};

struct FragmentOutputInterfaceState
{
	void initialize(const VkPipelineColorBlendStateCreateInfo *colorBlendState,
	            const VkPipelineMultisampleStateCreateInfo *multisampleState,
	            const vk::RenderPass *renderPass, uint32_t subpassIndex,
	            const VkPipelineRenderingCreateInfo *rendering,
	            const DynamicStateFlags &allDynamicStateFlags);

	void applyState(const DynamicState &dynamicState);

	inline unsigned int getMultiSampleMask() const { return multisample.multiSampleMask; }
	inline int getSampleCount() const { return multisample.sampleCount; }
	inline bool hasSampleShadingEnabled() const { return multisample.sampleShadingEnable; }
	inline float getMinSampleShading() const { return multisample.minSampleShading; }
	inline bool hasAlphaToCoverage() const { return multisample.alphaToCoverage; }

	inline const sw::float4 &getBlendConstants() const { return blendConstants; }

	BlendState getBlendState(int index, const Attachments &attachments, bool fragmentContainsKill) const;

	int colorWriteActive(int index, const Attachments &attachments) const;

private:
	void setColorBlendState(const VkPipelineColorBlendStateCreateInfo *colorBlendState);

	VkBlendFactor blendFactor(VkBlendOp blendOperation, VkBlendFactor blendFactor) const;
	VkBlendOp blendOperation(VkBlendOp blendOperation, VkBlendFactor sourceBlendFactor, VkBlendFactor destBlendFactor, vk::Format format) const;

	bool alphaBlendActive(int index, const Attachments &attachments, bool fragmentContainsKill) const;
	bool colorWriteActive(const Attachments &attachments) const;

	int colorWriteMask[sw::MAX_COLOR_BUFFERS] = {};  // RGBA

	FragmentOutputInterfaceDynamicStateFlags dynamicStateFlags = {};

	sw::float4 blendConstants = {};
	BlendState blendState[sw::MAX_COLOR_BUFFERS] = {};

	MultisampleState multisample;
};

struct GraphicsState
{
	GraphicsState(const Device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo, const PipelineLayout *layout);

	GraphicsState combineStates(const DynamicState &dynamicState) const;

	inline const PipelineLayout *getPipelineLayout() const { return pipelineLayout; }

	const VertexInputInterfaceState &getVertexInputInterfaceState() const { return vertexInputInterfaceState; }
	const PreRasterizationState &getPreRasterizationState() const { return preRasterizationState; }
	const FragmentState &getFragmentState() const { return fragmentState; }
	const FragmentOutputInterfaceState &getFragmentOutputInterfaceState() const { return fragmentOutputInterfaceState; }

private:
	const PipelineLayout *pipelineLayout = nullptr;

	// The four subsets of a graphics pipeline as described in the spec.  With
	// VK_EXT_graphics_pipeline_library, a number of these may be valid.
	VertexInputInterfaceState vertexInputInterfaceState;
	PreRasterizationState preRasterizationState;
	FragmentState fragmentState;
	FragmentOutputInterfaceState fragmentOutputInterfaceState;
};

}  // namespace vk

#endif  // vk_Context_hpp
