#ifndef _VKTSSBOLAYOUTCASE_HPP
#define _VKTSSBOLAYOUTCASE_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 SSBO layout tests.
 *//*--------------------------------------------------------------------*/

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

namespace vkt
{

namespace ssbo
{

enum BufferVarFlags
{
	LAYOUT_STD140		= (1<<0),
	LAYOUT_STD430		= (1<<1),
	LAYOUT_ROW_MAJOR	= (1<<2),
	LAYOUT_COLUMN_MAJOR	= (1<<3),	//!< \note Lack of both flags means column-major matrix.
	LAYOUT_SCALAR		= (1<<4),
	LAYOUT_MASK			= LAYOUT_STD430|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR|LAYOUT_SCALAR,

	// \todo [2013-10-14 pyry] Investigate adding these.
/*	QUALIFIER_COHERENT			= (1<<4),
	QUALIFIER_VOLATILE			= (1<<5),
	QUALIFIER_RESTRICT			= (1<<6),
	QUALIFIER_READONLY			= (1<<7),
	QUALIFIER_WRITEONLY			= (1<<8),*/
	ACCESS_READ					= (1<<9),	//!< Buffer variable is read in the shader.
	ACCESS_WRITE				= (1<<10),	//!< Buffer variable is written in the shader.
	LAYOUT_RELAXED				= (1<<11),	//!< Support VK_KHR_relaxed_block_layout extension
	LAYOUT_16BIT_STORAGE		= (1<<12),  //!< Support VK_KHR_16bit_storage extension
	LAYOUT_8BIT_STORAGE			= (1 << 13),  //!< Support VK_KHR_8bit_storage extension
	LAYOUT_DESCRIPTOR_INDEXING	= (1 << 14),  //!< Support VK_KHR_descriptor_indexing extension
};

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

class BufferVar
{
public:
						BufferVar		(const char* name, const glu::VarType& type, deUint32 flags);

	const char*			getName			(void) const		{ return m_name.c_str();	}
	const glu::VarType&	getType			(void) const		{ return m_type;			}
	deUint32			getFlags		(void) const		{ return m_flags;			}
	deUint32			getOffset		(void) const		{ return m_offset;			}

	void				setOffset		(deUint32 offset)	{ m_offset = offset;		}

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

class BufferBlock
{
public:
	typedef std::vector<BufferVar>::iterator		iterator;
	typedef std::vector<BufferVar>::const_iterator	const_iterator;

							BufferBlock				(const char* blockName);

	const char*				getBlockName			(void) const				{ return m_blockName.c_str();										}
	const char*				getInstanceName			(void) const				{ return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();	}
	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 char* name)			{ m_instanceName = name;											}
	void					setFlags				(deUint32 flags)			{ m_flags = flags;													}
	void					addMember				(const BufferVar& var)		{ m_variables.push_back(var);										}
	void					setArraySize			(int arraySize);

	int						getLastUnsizedArraySize	(int instanceNdx) const		{ return m_lastUnsizedArraySizes[instanceNdx];						}
	void					setLastUnsizedArraySize	(int instanceNdx, int size)	{ m_lastUnsizedArraySizes[instanceNdx] = size;						}

	inline iterator			begin					(void)						{ return m_variables.begin();										}
	inline const_iterator	begin					(void) const				{ return m_variables.begin();										}
	inline iterator			end						(void)						{ return m_variables.end();											}
	inline const_iterator	end						(void) const				{ return m_variables.end();											}

private:
	std::string				m_blockName;
	std::string				m_instanceName;
	std::vector<BufferVar>	m_variables;
	int						m_arraySize;				//!< Array size or 0 if not interface block array.
	std::vector<int>		m_lastUnsizedArraySizes;	//!< Sizes of last unsized array element, can be different per instance.
	deUint32				m_flags;
};

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

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

	BufferBlock&					allocBlock				(const char* name);

	int								getNumBlocks			(void) const	{ return (int)m_bufferBlocks.size();	}
	const BufferBlock&				getBlock				(int ndx) const	{ return *m_bufferBlocks[ndx];			}
	BufferBlock&					getBlock				(int ndx)		{ return *m_bufferBlocks[ndx];			}

private:
									ShaderInterface			(const ShaderInterface&);
	ShaderInterface&				operator=				(const ShaderInterface&);

	std::vector<glu::StructType*>	m_structs;
	std::vector<BufferBlock*>		m_bufferBlocks;
};

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

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

struct BlockLayoutEntry
{
	BlockLayoutEntry (void)
		: size(0)
	{
	}

	std::string			name;
	int					size;
	std::vector<int>	activeVarIndices;
};

class BufferLayout
{
public:
	std::vector<BlockLayoutEntry>		blocks;
	std::vector<BufferVarLayoutEntry>	bufferVars;

	int									getVariableIndex		(const std::string& name) const;
	int									getBlockIndex			(const std::string& name) const;
};

// BlockDataPtr

struct BlockDataPtr
{
	void*		ptr;
	int			size;						//!< Redundant, for debugging purposes.
	int			lastUnsizedArraySize;

	BlockDataPtr (void* ptr_, int size_, int lastUnsizedArraySize_)
		: ptr					(ptr_)
		, size					(size_)
		, lastUnsizedArraySize	(lastUnsizedArraySize_)
	{
	}

	BlockDataPtr (void)
		: ptr					(DE_NULL)
		, size					(0)
		, lastUnsizedArraySize	(0)
	{
	}
};

struct RefDataStorage
{
	std::vector<deUint8>			data;
	std::vector<BlockDataPtr>	pointers;
};

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

		BUFFERMODE_LAST
	};

								SSBOLayoutCase				(tcu::TestContext& testCtx, const char* name, const char* description, BufferMode bufferMode, MatrixLoadFlags matrixLoadFlag, bool usePhysStorageBuffer);
	virtual						~SSBOLayoutCase				(void);

	virtual void				delayedInit					(void);
	virtual void				initPrograms				(vk::SourceCollections& programCollection) const;
	virtual TestInstance*		createInstance				(Context& context) const;

protected:
	BufferMode					m_bufferMode;
	ShaderInterface				m_interface;
	MatrixLoadFlags				m_matrixLoadFlag;
	std::string					m_computeShaderSrc;
	bool						m_usePhysStorageBuffer;

private:
								SSBOLayoutCase				(const SSBOLayoutCase&);
	SSBOLayoutCase&				operator=					(const SSBOLayoutCase&);

	BufferLayout				m_refLayout;
	RefDataStorage				m_initialData;	// Initial data stored in buffer.
	RefDataStorage				m_writeData;		// Data written by compute shader.
};

} // ssbo
} // vkt

#endif // _VKTSSBOLAYOUTCASE_HPP
