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 namespace ssbo
35 {
36 
37 enum BufferVarFlags
38 {
39 	LAYOUT_STD140		= (1<<0),
40 	LAYOUT_STD430		= (1<<1),
41 	LAYOUT_ROW_MAJOR	= (1<<2),
42 	LAYOUT_COLUMN_MAJOR	= (1<<3),	//!< \note Lack of both flags means column-major matrix.
43 	LAYOUT_MASK			= LAYOUT_STD430|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR,
44 
45 	// \todo [2013-10-14 pyry] Investigate adding these.
46 /*	QUALIFIER_COHERENT	= (1<<4),
47 	QUALIFIER_VOLATILE	= (1<<5),
48 	QUALIFIER_RESTRICT	= (1<<6),
49 	QUALIFIER_READONLY	= (1<<7),
50 	QUALIFIER_WRITEONLY	= (1<<8),*/
51 
52 	ACCESS_READ			= (1<<9),	//!< Buffer variable is read in the shader.
53 	ACCESS_WRITE		= (1<<10),	//!< Buffer variable is written in the shader.
54 };
55 
56 class BufferVar
57 {
58 public:
59 						BufferVar		(const char* name, const glu::VarType& type, deUint32 flags);
60 
getName(void) const61 	const char*			getName			(void) const { return m_name.c_str();	}
getType(void) const62 	const glu::VarType&	getType			(void) const { return m_type;			}
getFlags(void) const63 	deUint32			getFlags		(void) const { return m_flags;			}
64 
65 private:
66 	std::string			m_name;
67 	glu::VarType		m_type;
68 	deUint32			m_flags;
69 };
70 
71 class BufferBlock
72 {
73 public:
74 	typedef std::vector<BufferVar>::iterator		iterator;
75 	typedef std::vector<BufferVar>::const_iterator	const_iterator;
76 
77 							BufferBlock				(const char* blockName);
78 
getBlockName(void) const79 	const char*				getBlockName			(void) const { return m_blockName.c_str();		}
getInstanceName(void) const80 	const char*				getInstanceName			(void) const { return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();	}
isArray(void) const81 	bool					isArray					(void) const { return m_arraySize > 0;			}
getArraySize(void) const82 	int						getArraySize			(void) const { return m_arraySize;				}
getFlags(void) const83 	deUint32				getFlags				(void) const { return m_flags;					}
84 
setInstanceName(const char * name)85 	void					setInstanceName			(const char* name)			{ m_instanceName = name;			}
setFlags(deUint32 flags)86 	void					setFlags				(deUint32 flags)			{ m_flags = flags;					}
addMember(const BufferVar & var)87 	void					addMember				(const BufferVar& var)		{ m_variables.push_back(var);		}
88 	void					setArraySize			(int arraySize);
89 
getLastUnsizedArraySize(int instanceNdx) const90 	int						getLastUnsizedArraySize	(int instanceNdx) const		{ return m_lastUnsizedArraySizes[instanceNdx];	}
setLastUnsizedArraySize(int instanceNdx,int size)91 	void					setLastUnsizedArraySize	(int instanceNdx, int size)	{ m_lastUnsizedArraySizes[instanceNdx] = size;	}
92 
begin(void)93 	inline iterator			begin					(void)			{ return m_variables.begin();	}
begin(void) const94 	inline const_iterator	begin					(void) const	{ return m_variables.begin();	}
end(void)95 	inline iterator			end						(void)			{ return m_variables.end();		}
end(void) const96 	inline const_iterator	end						(void) const	{ return m_variables.end();		}
97 
98 private:
99 	std::string				m_blockName;
100 	std::string				m_instanceName;
101 	std::vector<BufferVar>	m_variables;
102 	int						m_arraySize;				//!< Array size or 0 if not interface block array.
103 	std::vector<int>		m_lastUnsizedArraySizes;	//!< Sizes of last unsized array element, can be different per instance.
104 	deUint32				m_flags;
105 };
106 
107 class ShaderInterface
108 {
109 public:
110 									ShaderInterface			(void);
111 									~ShaderInterface		(void);
112 
113 	glu::StructType&				allocStruct				(const char* name);
114 	const glu::StructType*			findStruct				(const char* name) const;
115 	void							getNamedStructs			(std::vector<const glu::StructType*>& structs) const;
116 
117 	BufferBlock&					allocBlock				(const char* name);
118 
getNumBlocks(void) const119 	int								getNumBlocks			(void) const	{ return (int)m_bufferBlocks.size();	}
getBlock(int ndx) const120 	const BufferBlock&				getBlock				(int ndx) const	{ return *m_bufferBlocks[ndx];			}
121 
122 private:
123 									ShaderInterface			(const ShaderInterface&);
124 	ShaderInterface&				operator=				(const ShaderInterface&);
125 
126 	std::vector<glu::StructType*>	m_structs;
127 	std::vector<BufferBlock*>		m_bufferBlocks;
128 };
129 
130 struct BufferVarLayoutEntry
131 {
BufferVarLayoutEntryvkt::ssbo::BufferVarLayoutEntry132 	BufferVarLayoutEntry (void)
133 		: type					(glu::TYPE_LAST)
134 		, blockNdx				(-1)
135 		, offset				(-1)
136 		, arraySize				(-1)
137 		, arrayStride			(-1)
138 		, matrixStride			(-1)
139 		, topLevelArraySize		(-1)
140 		, topLevelArrayStride	(-1)
141 		, isRowMajor			(false)
142 	{
143 	}
144 
145 	std::string			name;
146 	glu::DataType		type;
147 	int					blockNdx;
148 	int					offset;
149 	int					arraySize;
150 	int					arrayStride;
151 	int					matrixStride;
152 	int					topLevelArraySize;
153 	int					topLevelArrayStride;
154 	bool				isRowMajor;
155 };
156 
157 struct BlockLayoutEntry
158 {
BlockLayoutEntryvkt::ssbo::BlockLayoutEntry159 	BlockLayoutEntry (void)
160 		: size(0)
161 	{
162 	}
163 
164 	std::string			name;
165 	int					size;
166 	std::vector<int>	activeVarIndices;
167 };
168 
169 class BufferLayout
170 {
171 public:
172 	std::vector<BlockLayoutEntry>		blocks;
173 	std::vector<BufferVarLayoutEntry>	bufferVars;
174 
175 	int									getVariableIndex		(const std::string& name) const;
176 	int									getBlockIndex			(const std::string& name) const;
177 };
178 
179 // BlockDataPtr
180 
181 struct BlockDataPtr
182 {
183 	void*		ptr;
184 	int			size;						//!< Redundant, for debugging purposes.
185 	int			lastUnsizedArraySize;
186 
BlockDataPtrvkt::ssbo::BlockDataPtr187 	BlockDataPtr (void* ptr_, int size_, int lastUnsizedArraySize_)
188 		: ptr					(ptr_)
189 		, size					(size_)
190 		, lastUnsizedArraySize	(lastUnsizedArraySize_)
191 	{
192 	}
193 
BlockDataPtrvkt::ssbo::BlockDataPtr194 	BlockDataPtr (void)
195 		: ptr					(DE_NULL)
196 		, size					(0)
197 		, lastUnsizedArraySize	(0)
198 	{
199 	}
200 };
201 
202 struct RefDataStorage
203 {
204 	std::vector<deUint8>			data;
205 	std::vector<BlockDataPtr>	pointers;
206 };
207 
208 class SSBOLayoutCase : public vkt::TestCase
209 {
210 public:
211 	enum BufferMode
212 	{
213 		BUFFERMODE_SINGLE = 0,	//!< Single buffer shared between uniform blocks.
214 		BUFFERMODE_PER_BLOCK,	//!< Per-block buffers
215 
216 		BUFFERMODE_LAST
217 	};
218 
219 								SSBOLayoutCase				(tcu::TestContext& testCtx, const char* name, const char* description, BufferMode bufferMode);
220 	virtual						~SSBOLayoutCase				(void);
221 
222 	virtual void				initPrograms				(vk::SourceCollections& programCollection) const;
223 	virtual TestInstance*		createInstance				(Context& context) const;
224 
225 protected:
226     void                        init                        (void);
227 
228 	BufferMode					m_bufferMode;
229 	ShaderInterface				m_interface;
230 
231 private:
232 								SSBOLayoutCase				(const SSBOLayoutCase&);
233 	SSBOLayoutCase&				operator=					(const SSBOLayoutCase&);
234 
235 	BufferLayout				m_refLayout;
236 	RefDataStorage				m_initialData;	// Initial data stored in buffer.
237 	RefDataStorage				m_writeData;		// Data written by compute shader.
238 	std::string					m_computeShaderSrc;
239 };
240 
241 } // ssbo
242 } // vkt
243 
244 #endif // _VKTSSBOLAYOUTCASE_HPP
245