• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _VKTSSBOLAYOUTCASE_HPP
2 #define _VKTSSBOLAYOUTCASE_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2015 The Khronos Group Inc.
8  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief SSBO layout tests.
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktTestCase.hpp"
28 #include "tcuDefs.hpp"
29 #include "gluShaderUtil.hpp"
30 #include "gluVarType.hpp"
31 
32 namespace vkt
33 {
34 
35 namespace ssbo
36 {
37 
38 enum BufferVarFlags
39 {
40 	LAYOUT_STD140		= (1<<0),
41 	LAYOUT_STD430		= (1<<1),
42 	LAYOUT_ROW_MAJOR	= (1<<2),
43 	LAYOUT_COLUMN_MAJOR	= (1<<3),	//!< \note Lack of both flags means column-major matrix.
44 	LAYOUT_SCALAR		= (1<<4),
45 	LAYOUT_MASK			= LAYOUT_STD430|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR|LAYOUT_SCALAR,
46 
47 	// \todo [2013-10-14 pyry] Investigate adding these.
48 /*	QUALIFIER_COHERENT			= (1<<4),
49 	QUALIFIER_VOLATILE			= (1<<5),
50 	QUALIFIER_RESTRICT			= (1<<6),
51 	QUALIFIER_READONLY			= (1<<7),
52 	QUALIFIER_WRITEONLY			= (1<<8),*/
53 	ACCESS_READ					= (1<<9),	//!< Buffer variable is read in the shader.
54 	ACCESS_WRITE				= (1<<10),	//!< Buffer variable is written in the shader.
55 	LAYOUT_RELAXED				= (1<<11),	//!< Support VK_KHR_relaxed_block_layout extension
56 	LAYOUT_16BIT_STORAGE		= (1<<12),  //!< Support VK_KHR_16bit_storage extension
57 	LAYOUT_8BIT_STORAGE			= (1 << 13),  //!< Support VK_KHR_8bit_storage extension
58 	LAYOUT_DESCRIPTOR_INDEXING	= (1 << 14),  //!< Support VK_KHR_descriptor_indexing extension
59 };
60 
61 enum MatrixLoadFlags
62 {
63 	LOAD_FULL_MATRIX		= 0,
64 	LOAD_MATRIX_COMPONENTS	= 1,
65 };
66 
67 enum MatrixStoreFlags
68 {
69 	STORE_FULL_MATRIX		= 0,
70 	STORE_MATRIX_COLUMNS	= 1,
71 };
72 
73 class BufferVar
74 {
75 public:
76 						BufferVar		(const char* name, const glu::VarType& type, deUint32 flags);
77 
getName(void) const78 	const char*			getName			(void) const		{ return m_name.c_str();	}
getType(void) const79 	const glu::VarType&	getType			(void) const		{ return m_type;			}
getFlags(void) const80 	deUint32			getFlags		(void) const		{ return m_flags;			}
getOffset(void) const81 	deUint32			getOffset		(void) const		{ return m_offset;			}
82 
setOffset(deUint32 offset)83 	void				setOffset		(deUint32 offset)	{ m_offset = offset;		}
84 
85 private:
86 	std::string			m_name;
87 	glu::VarType		m_type;
88 	deUint32			m_flags;
89 	deUint32			m_offset;
90 };
91 
92 class BufferBlock
93 {
94 public:
95 	typedef std::vector<BufferVar>::iterator		iterator;
96 	typedef std::vector<BufferVar>::const_iterator	const_iterator;
97 
98 							BufferBlock				(const char* blockName);
99 
getBlockName(void) const100 	const char*				getBlockName			(void) const				{ return m_blockName.c_str();										}
getInstanceName(void) const101 	const char*				getInstanceName			(void) const				{ return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();	}
isArray(void) const102 	bool					isArray					(void) const				{ return m_arraySize > 0;											}
getArraySize(void) const103 	int						getArraySize			(void) const				{ return m_arraySize;												}
getFlags(void) const104 	deUint32				getFlags				(void) const				{ return m_flags;													}
105 
setInstanceName(const char * name)106 	void					setInstanceName			(const char* name)			{ m_instanceName = name;											}
setFlags(deUint32 flags)107 	void					setFlags				(deUint32 flags)			{ m_flags = flags;													}
addMember(const BufferVar & var)108 	void					addMember				(const BufferVar& var)		{ m_variables.push_back(var);										}
109 	void					setArraySize			(int arraySize);
110 
getLastUnsizedArraySize(int instanceNdx) const111 	int						getLastUnsizedArraySize	(int instanceNdx) const		{ return m_lastUnsizedArraySizes[instanceNdx];						}
setLastUnsizedArraySize(int instanceNdx,int size)112 	void					setLastUnsizedArraySize	(int instanceNdx, int size)	{ m_lastUnsizedArraySizes[instanceNdx] = size;						}
113 
begin(void)114 	inline iterator			begin					(void)						{ return m_variables.begin();										}
begin(void) const115 	inline const_iterator	begin					(void) const				{ return m_variables.begin();										}
end(void)116 	inline iterator			end						(void)						{ return m_variables.end();											}
end(void) const117 	inline const_iterator	end						(void) const				{ return m_variables.end();											}
118 
119 private:
120 	std::string				m_blockName;
121 	std::string				m_instanceName;
122 	std::vector<BufferVar>	m_variables;
123 	int						m_arraySize;				//!< Array size or 0 if not interface block array.
124 	std::vector<int>		m_lastUnsizedArraySizes;	//!< Sizes of last unsized array element, can be different per instance.
125 	deUint32				m_flags;
126 };
127 
128 class ShaderInterface
129 {
130 public:
131 									ShaderInterface			(void);
132 									~ShaderInterface		(void);
133 
134 	glu::StructType&				allocStruct				(const char* name);
135 	const glu::StructType*			findStruct				(const char* name) const;
136 	void							getNamedStructs			(std::vector<const glu::StructType*>& structs) const;
137 
138 	BufferBlock&					allocBlock				(const char* name);
139 
getNumBlocks(void) const140 	int								getNumBlocks			(void) const	{ return (int)m_bufferBlocks.size();	}
getBlock(int ndx) const141 	const BufferBlock&				getBlock				(int ndx) const	{ return *m_bufferBlocks[ndx];			}
getBlock(int ndx)142 	BufferBlock&					getBlock				(int ndx)		{ return *m_bufferBlocks[ndx];			}
143 
144 private:
145 									ShaderInterface			(const ShaderInterface&);
146 	ShaderInterface&				operator=				(const ShaderInterface&);
147 
148 	std::vector<glu::StructType*>	m_structs;
149 	std::vector<BufferBlock*>		m_bufferBlocks;
150 };
151 
152 struct BufferVarLayoutEntry
153 {
BufferVarLayoutEntryvkt::ssbo::BufferVarLayoutEntry154 	BufferVarLayoutEntry (void)
155 		: type					(glu::TYPE_LAST)
156 		, blockNdx				(-1)
157 		, offset				(-1)
158 		, arraySize				(-1)
159 		, arrayStride			(-1)
160 		, matrixStride			(-1)
161 		, topLevelArraySize		(-1)
162 		, topLevelArrayStride	(-1)
163 		, isRowMajor			(false)
164 	{
165 	}
166 
167 	std::string			name;
168 	glu::DataType		type;
169 	int					blockNdx;
170 	int					offset;
171 	int					arraySize;
172 	int					arrayStride;
173 	int					matrixStride;
174 	int					topLevelArraySize;
175 	int					topLevelArrayStride;
176 	bool				isRowMajor;
177 };
178 
179 struct BlockLayoutEntry
180 {
BlockLayoutEntryvkt::ssbo::BlockLayoutEntry181 	BlockLayoutEntry (void)
182 		: size(0)
183 	{
184 	}
185 
186 	std::string			name;
187 	int					size;
188 	std::vector<int>	activeVarIndices;
189 };
190 
191 class BufferLayout
192 {
193 public:
194 	std::vector<BlockLayoutEntry>		blocks;
195 	std::vector<BufferVarLayoutEntry>	bufferVars;
196 
197 	int									getVariableIndex		(const std::string& name) const;
198 	int									getBlockIndex			(const std::string& name) const;
199 };
200 
201 // BlockDataPtr
202 
203 struct BlockDataPtr
204 {
205 	void*		ptr;
206 	int			size;						//!< Redundant, for debugging purposes.
207 	int			lastUnsizedArraySize;
208 
BlockDataPtrvkt::ssbo::BlockDataPtr209 	BlockDataPtr (void* ptr_, int size_, int lastUnsizedArraySize_)
210 		: ptr					(ptr_)
211 		, size					(size_)
212 		, lastUnsizedArraySize	(lastUnsizedArraySize_)
213 	{
214 	}
215 
BlockDataPtrvkt::ssbo::BlockDataPtr216 	BlockDataPtr (void)
217 		: ptr					(DE_NULL)
218 		, size					(0)
219 		, lastUnsizedArraySize	(0)
220 	{
221 	}
222 };
223 
224 struct RefDataStorage
225 {
226 	std::vector<deUint8>			data;
227 	std::vector<BlockDataPtr>	pointers;
228 };
229 
230 class SSBOLayoutCase : public vkt::TestCase
231 {
232 public:
233 	enum BufferMode
234 	{
235 		BUFFERMODE_SINGLE = 0,	//!< Single buffer shared between uniform blocks.
236 		BUFFERMODE_PER_BLOCK,	//!< Per-block buffers
237 
238 		BUFFERMODE_LAST
239 	};
240 
241 								SSBOLayoutCase				(tcu::TestContext& testCtx, const char* name, const char* description, BufferMode bufferMode, MatrixLoadFlags matrixLoadFlag, MatrixStoreFlags matrixStoreFlag, bool usePhysStorageBuffer);
242 	virtual						~SSBOLayoutCase				(void);
243 
244 	virtual void				delayedInit					(void);
245 	virtual void				initPrograms				(vk::SourceCollections& programCollection) const;
246 	virtual TestInstance*		createInstance				(Context& context) const;
247 	virtual void				checkSupport				(Context &context) const;
248 
249 protected:
250 	BufferMode					m_bufferMode;
251 	ShaderInterface				m_interface;
252 	MatrixLoadFlags				m_matrixLoadFlag;
253 	MatrixStoreFlags			m_matrixStoreFlag;
254 	std::string					m_computeShaderSrc;
255 	bool						m_usePhysStorageBuffer;
256 
257 private:
258 								SSBOLayoutCase				(const SSBOLayoutCase&);
259 	SSBOLayoutCase&				operator=					(const SSBOLayoutCase&);
260 
261 	BufferLayout				m_refLayout;
262 	RefDataStorage				m_initialData;	// Initial data stored in buffer.
263 	RefDataStorage				m_writeData;		// Data written by compute shader.
264 };
265 
266 } // ssbo
267 } // vkt
268 
269 #endif // _VKTSSBOLAYOUTCASE_HPP
270