#ifndef _VKTUNIFORMBLOCKCASE_HPP
#define _VKTUNIFORMBLOCKCASE_HPP
/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Uniform block tests.
 *//*--------------------------------------------------------------------*/

#include "deSharedPtr.hpp"
#include "vktTestCase.hpp"
#include "tcuDefs.hpp"
#include "gluShaderUtil.hpp"

#include <map>

namespace vkt
{
namespace ubo
{

// Uniform block details.

enum UniformFlags
{
	PRECISION_LOW		= (1<<0),
	PRECISION_MEDIUM	= (1<<1),
	PRECISION_HIGH		= (1<<2),
	PRECISION_MASK		= PRECISION_LOW|PRECISION_MEDIUM|PRECISION_HIGH,

	LAYOUT_SHARED		= (1<<3),
	LAYOUT_PACKED		= (1<<4),
	LAYOUT_STD140		= (1<<5),
	LAYOUT_ROW_MAJOR	= (1<<6),
	LAYOUT_COLUMN_MAJOR	= (1<<7),	//!< \note Lack of both flags means column-major matrix.
	LAYOUT_OFFSET		= (1<<8),
	LAYOUT_STD430		= (1<<9),
	LAYOUT_SCALAR		= (1<<10),
	LAYOUT_MASK			= LAYOUT_SHARED|LAYOUT_PACKED|LAYOUT_STD140|LAYOUT_STD430|LAYOUT_SCALAR|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR|LAYOUT_OFFSET,

	DECLARE_VERTEX		= (1<<11),
	DECLARE_FRAGMENT	= (1<<12),
	DECLARE_BOTH		= DECLARE_VERTEX|DECLARE_FRAGMENT,

	UNUSED_VERTEX		= (1<<13),	//!< Uniform or struct member is not read in vertex shader.
	UNUSED_FRAGMENT		= (1<<14),	//!< Uniform or struct member is not read in fragment shader.
	UNUSED_BOTH			= UNUSED_VERTEX|UNUSED_FRAGMENT,

	LAYOUT_16BIT_STORAGE= (1<<15),  //!< Support VK_KHR_16bit_storage extension
	LAYOUT_8BIT_STORAGE	= (1<<16),  //!< Support VK_KHR_8bit_storage extension

	LAYOUT_DESCRIPTOR_INDEXING = (1 << 17),  //!< Support VK_KHR_descriptor_indexing extension
};

enum MatrixLoadFlags
{
	LOAD_FULL_MATRIX		= 0,
	LOAD_MATRIX_COMPONENTS	= 1,
};

class StructType;

class VarType
{
public:
						VarType			(void);
						VarType			(const VarType& other);
						VarType			(glu::DataType basicType, deUint32 flags);
						VarType			(const VarType& elementType, int arraySize);
	explicit			VarType			(const StructType* structPtr, deUint32 flags = 0u);
						~VarType		(void);

	bool				isBasicType		(void) const	{ return m_type == TYPE_BASIC;	}
	bool				isArrayType		(void) const	{ return m_type == TYPE_ARRAY;	}
	bool				isStructType	(void) const	{ return m_type == TYPE_STRUCT;	}

	deUint32			getFlags		(void) const	{ return m_flags;					}
	glu::DataType		getBasicType	(void) const	{ return m_data.basicType;			}

	const VarType&		getElementType	(void) const	{ return *m_data.array.elementType;	}
	int					getArraySize	(void) const	{ return m_data.array.size;			}

	const StructType&	getStruct		(void) const	{ return *m_data.structPtr;			}
	const StructType*	getStructPtr	(void) const	{ DE_ASSERT(isStructType()); return m_data.structPtr;			}

	VarType&			operator=		(const VarType& other);

private:
	enum Type
	{
		TYPE_BASIC,
		TYPE_ARRAY,
		TYPE_STRUCT,

		TYPE_LAST
	};

	Type				m_type;
	deUint32			m_flags;
	union Data
	{
		glu::DataType		basicType;
		struct
		{
			VarType*		elementType;
			int				size;
		} array;
		const StructType*	structPtr;

		Data (void)
		{
			array.elementType	= DE_NULL;
			array.size			= 0;
		}
	} m_data;
};

class StructMember
{
public:
						StructMember	(const std::string& name, const VarType& type, deUint32 flags)
							: m_name(name), m_type(type), m_flags(flags)
						{}
						StructMember	(void)
							: m_flags(0)
						{}

	const std::string&	getName			(void) const { return m_name;	}
	const VarType&		getType			(void) const { return m_type;	}
	deUint32			getFlags		(void) const { return m_flags;	}

private:
	std::string			m_name;
	VarType				m_type;
	deUint32			m_flags;
};

class StructType
{
public:
	typedef std::vector<StructMember>::iterator			Iterator;
	typedef std::vector<StructMember>::const_iterator	ConstIterator;

								StructType		(const std::string& typeName) : m_typeName(typeName) {}
								~StructType		(void) {}

	const std::string&			getTypeName		(void) const	{ return m_typeName;			}
	bool						hasTypeName		(void) const	{ return !m_typeName.empty();	}

	inline Iterator				begin			(void)			{ return m_members.begin();		}
	inline ConstIterator		begin			(void) const	{ return m_members.begin();		}
	inline Iterator				end				(void)			{ return m_members.end();		}
	inline ConstIterator		end				(void) const	{ return m_members.end();		}

	void						addMember		(const std::string& name, const VarType& type, deUint32 flags = 0);

private:
	std::string					m_typeName;
	std::vector<StructMember>	m_members;
};

class Uniform
{
public:
						Uniform			(const std::string& name, const VarType& type, deUint32 flags = 0);

	const std::string&	getName			(void) const { return m_name;	}
	const VarType&		getType			(void) const { return m_type;	}
	deUint32			getFlags		(void) const { return m_flags;	}

private:
	std::string			m_name;
	VarType				m_type;
	deUint32			m_flags;
};

class UniformBlock
{
public:
	typedef std::vector<Uniform>::iterator			Iterator;
	typedef std::vector<Uniform>::const_iterator	ConstIterator;

							UniformBlock		(const std::string& blockName);

	const std::string&		getBlockName		(void) const { return m_blockName;		}
	const std::string&		getInstanceName		(void) const { return m_instanceName;	}
	bool					hasInstanceName		(void) const { return !m_instanceName.empty();	}
	bool					isArray				(void) const { return m_arraySize > 0;			}
	int						getArraySize		(void) const { return m_arraySize;				}
	deUint32				getFlags			(void) const { return m_flags;					}

	void					setInstanceName		(const std::string& name)	{ m_instanceName = name;			}
	void					setFlags			(deUint32 flags)			{ m_flags = flags;					}
	void					setArraySize		(int arraySize)				{ m_arraySize = arraySize;			}
	void					addUniform			(const Uniform& uniform)	{ m_uniforms.push_back(uniform);	}

	inline Iterator			begin				(void)			{ return m_uniforms.begin();	}
	inline ConstIterator	begin				(void) const	{ return m_uniforms.begin();	}
	inline Iterator			end					(void)			{ return m_uniforms.end();		}
	inline ConstIterator	end					(void) const	{ return m_uniforms.end();		}

private:
	std::string				m_blockName;
	std::string				m_instanceName;
	std::vector<Uniform>	m_uniforms;
	int						m_arraySize;	//!< Array size or 0 if not interface block array.
	deUint32				m_flags;
};

typedef de::SharedPtr<StructType>	StructTypeSP;
typedef de::SharedPtr<UniformBlock>	UniformBlockSP;

class ShaderInterface
{
public:
								ShaderInterface			(void);
								~ShaderInterface		(void);

	StructType&					allocStruct				(const std::string& name);
	void						getNamedStructs			(std::vector<const StructType*>& structs) const;

	UniformBlock&				allocBlock				(const std::string& name);

	int							getNumUniformBlocks		(void) const	{ return (int)m_uniformBlocks.size();	}
	const UniformBlock&			getUniformBlock			(int ndx) const	{ return *m_uniformBlocks[ndx];			}
	bool						usesBlockLayout			(UniformFlags layoutFlag) const;

private:
	std::vector<StructTypeSP>		m_structs;
	std::vector<UniformBlockSP>		m_uniformBlocks;
};

struct BlockLayoutEntry
{
	BlockLayoutEntry (void)
		: size					(0)
		, blockDeclarationNdx	(-1)
		, bindingNdx			(-1)
		, instanceNdx			(-1)
	{
	}

	std::string			name;
	int					size;
	std::vector<int>	activeUniformIndices;
	int					blockDeclarationNdx;
	int					bindingNdx;
	int					instanceNdx;
};

struct UniformLayoutEntry
{
	UniformLayoutEntry (void)
		: type			(glu::TYPE_LAST)
		, size			(0)
		, blockNdx		(-1)
		, offset		(-1)
		, arraySize		(-1)
		, arrayStride	(-1)
		, matrixStride	(-1)
		, topLevelArraySize		(-1)
		, topLevelArrayStride	(-1)
		, isRowMajor	(false)
		, instanceNdx	(0)
	{
	}

	std::string			name;
	glu::DataType		type;
	int					size;
	int					blockNdx;
	int					offset;
	int					arraySize;
	int					arrayStride;
	int					matrixStride;
	int					topLevelArraySize;
	int					topLevelArrayStride;
	bool				isRowMajor;
	int					instanceNdx;
};

class UniformLayout
{
public:
	std::vector<BlockLayoutEntry>		blocks;
	std::vector<UniformLayoutEntry>		uniforms;

	int									getUniformLayoutIndex	(int blockDeclarationNdx, const std::string& name) const;
	int									getBlockLayoutIndex		(int blockDeclarationNdx, int instanceNdx) const;
};

class UniformBlockCase : public vkt::TestCase
{
public:
	enum BufferMode
	{
		BUFFERMODE_SINGLE = 0,	//!< Single buffer shared between uniform blocks.
		BUFFERMODE_PER_BLOCK,	//!< Per-block buffers

		BUFFERMODE_LAST
	};

								UniformBlockCase			(tcu::TestContext&	testCtx,
															 const std::string&	name,
															 const std::string&	description,
															 BufferMode			bufferMode,
															 MatrixLoadFlags	matrixLoadFlag,
															 bool				shuffleUniformMembers = false);
								~UniformBlockCase			(void);

	virtual void				delayedInit					(void);
	virtual	void				initPrograms				(vk::SourceCollections& programCollection) const;
	virtual TestInstance*		createInstance				(Context& context) const;
	bool						usesBlockLayout				(UniformFlags layoutFlag) const { return m_interface.usesBlockLayout(layoutFlag); }

protected:
	BufferMode					m_bufferMode;
	ShaderInterface				m_interface;
	MatrixLoadFlags				m_matrixLoadFlag;
	const bool					m_shuffleUniformMembers;	//!< Used with explicit offsets to test out of order member offsets

private:
	std::string					m_vertShaderSource;
	std::string					m_fragShaderSource;

	std::vector<deUint8>		m_data;						//!< Data.
	std::map<int, void*>		m_blockPointers;			//!< Reference block pointers.
	UniformLayout				m_uniformLayout;			//!< std140 layout.
};

} // ubo
} // vkt

#endif // _VKTUNIFORMBLOCKCASE_HPP
