• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _VKTTRANSFORMFEEDBACKFUZZLAYOUTCASE_HPP
2 #define _VKTTRANSFORMFEEDBACKFUZZLAYOUTCASE_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  * Copyright (c) 2018 The Khronos Group Inc.
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  *//*!
24  * \file
25  * \brief Vulkan Transform Feedback Fuzz Layout Tests
26  *//*--------------------------------------------------------------------*/
27 
28 #include "deSharedPtr.hpp"
29 #include "vktTestCase.hpp"
30 #include "tcuDefs.hpp"
31 #include "gluShaderUtil.hpp"
32 
33 #include <map>
34 
35 namespace vkt
36 {
37 namespace TransformFeedback
38 {
39 
40 // Interface block details.
41 
42 enum InterfaceFlags
43 {
44 	PRECISION_LOW			= (1<<0),
45 	PRECISION_MEDIUM		= (1<<1),
46 	PRECISION_HIGH			= (1<<2),
47 	PRECISION_MASK			= PRECISION_LOW|PRECISION_MEDIUM|PRECISION_HIGH,
48 
49 	LAYOUT_XFBBUFFER		= (1<<3),
50 	LAYOUT_XFBOFFSET		= (1<<4),
51 	LAYOUT_XFBSTRIDE		= (1<<5),
52 	LAYOUT_MASK				= LAYOUT_XFBBUFFER|LAYOUT_XFBOFFSET|LAYOUT_XFBSTRIDE,
53 
54 	FIELD_UNASSIGNED		= (1<<6),	//!< Interface or struct member is not used in shader.
55 	FIELD_MISSING			= (1<<7),	//!< Interface or struct member will be commented out in shader.
56 	FIELD_OPTIONS			= FIELD_UNASSIGNED|FIELD_MISSING,
57 };
58 
59 enum MatrixLoadFlags
60 {
61 	LOAD_FULL_MATRIX		= 0,
62 	LOAD_MATRIX_COMPONENTS	= 1,
63 };
64 
65 enum TestStageFlags
66 {
67 	TEST_STAGE_VERTEX	= 0,
68 	TEST_STAGE_GEOMETRY	= 1,
69 };
70 
71 class StructType;
72 
73 class VarType
74 {
75 public:
76 						VarType			(void);
77 						VarType			(const VarType& other);
78 						VarType			(glu::DataType basicType, deUint32 flags);
79 						VarType			(const VarType& elementType, int arraySize);
80 	explicit			VarType			(const StructType* structPtr, deUint32 flags = 0u);
81 						~VarType		(void);
82 
isBasicType(void) const83 	bool				isBasicType		(void) const	{ return m_type == TYPE_BASIC;	}
isArrayType(void) const84 	bool				isArrayType		(void) const	{ return m_type == TYPE_ARRAY;	}
isStructType(void) const85 	bool				isStructType	(void) const	{ return m_type == TYPE_STRUCT;	}
86 
getFlags(void) const87 	deUint32			getFlags		(void) const	{ return m_flags;					}
getBasicType(void) const88 	glu::DataType		getBasicType	(void) const	{ return m_data.basicType;			}
89 
getElementType(void) const90 	const VarType&		getElementType	(void) const	{ return *m_data.array.elementType;	}
getArraySize(void) const91 	int					getArraySize	(void) const	{ return m_data.array.size;			}
92 
getStruct(void) const93 	const StructType&	getStruct		(void) const	{ return *m_data.structPtr;			}
94 
95 	VarType&			operator=		(const VarType& other);
96 
97 private:
98 	enum Type
99 	{
100 		TYPE_BASIC,
101 		TYPE_ARRAY,
102 		TYPE_STRUCT,
103 
104 		TYPE_LAST
105 	};
106 
107 	Type				m_type;
108 	deUint32			m_flags;
109 	union Data
110 	{
111 		glu::DataType		basicType;
112 		struct
113 		{
114 			VarType*		elementType;
115 			int				size;
116 		} array;
117 		const StructType*	structPtr;
118 
Data(void)119 		Data (void)
120 		{
121 			array.elementType	= DE_NULL;
122 			array.size			= 0;
123 		}
124 	} m_data;
125 };
126 
127 class StructMember
128 {
129 public:
StructMember(const std::string & name,const VarType & type,deUint32 flags)130 						StructMember	(const std::string& name, const VarType& type, deUint32 flags)
131 							: m_name(name)
132 							, m_type(type)
133 							, m_flags(flags)
134 						{}
135 
StructMember(void)136 						StructMember	(void)
137 							: m_flags(0)
138 						{}
139 
getName(void) const140 	const std::string&	getName			(void) const { return m_name;	}
getType(void) const141 	const VarType&		getType			(void) const { return m_type;	}
getFlags(void) const142 	deUint32			getFlags		(void) const { return m_flags;	}
143 
144 private:
145 	std::string			m_name;
146 	VarType				m_type;
147 	deUint32			m_flags;
148 };
149 
150 class StructType
151 {
152 public:
153 	typedef std::vector<StructMember>::iterator			Iterator;
154 	typedef std::vector<StructMember>::const_iterator	ConstIterator;
155 
StructType(const std::string & typeName)156 								StructType		(const std::string& typeName) : m_typeName(typeName) {}
~StructType(void)157 								~StructType		(void) {}
158 
getTypeName(void) const159 	const std::string&			getTypeName		(void) const	{ return m_typeName;			}
hasTypeName(void) const160 	bool						hasTypeName		(void) const	{ return !m_typeName.empty();	}
161 
begin(void)162 	inline Iterator				begin			(void)			{ return m_members.begin();		}
begin(void) const163 	inline ConstIterator		begin			(void) const	{ return m_members.begin();		}
end(void)164 	inline Iterator				end				(void)			{ return m_members.end();		}
end(void) const165 	inline ConstIterator		end				(void) const	{ return m_members.end();		}
166 
167 	void						addMember		(const std::string& name, const VarType& type, deUint32 flags = 0);
168 
169 private:
170 	std::string					m_typeName;
171 	std::vector<StructMember>	m_members;
172 };
173 
174 class InterfaceBlockMember
175 {
176 public:
177 						InterfaceBlockMember	(const std::string& name, const VarType& type, deUint32 flags = 0);
178 
getName(void) const179 	const std::string&	getName					(void) const { return m_name;	}
getType(void) const180 	const VarType&		getType					(void) const { return m_type;	}
getFlags(void) const181 	deUint32			getFlags				(void) const { return m_flags;	}
182 
183 private:
184 	std::string			m_name;
185 	VarType				m_type;
186 	deUint32			m_flags;
187 };
188 
189 class InterfaceBlock
190 {
191 public:
192 	typedef std::vector<InterfaceBlockMember>::iterator			Iterator;
193 	typedef std::vector<InterfaceBlockMember>::const_iterator	ConstIterator;
194 
195 										InterfaceBlock		(const std::string& blockName);
196 
getBlockName(void) const197 	const std::string&					getBlockName		(void) const { return m_blockName;				}
hasInstanceName(void) const198 	bool								hasInstanceName		(void) const { return !m_instanceName.empty();	}
getInstanceName(void) const199 	const std::string&					getInstanceName		(void) const { return m_instanceName;			}
isArray(void) const200 	bool								isArray				(void) const { return m_arraySize > 0;			}
getArraySize(void) const201 	int									getArraySize		(void) const { return m_arraySize;				}
getXfbBuffer(void) const202 	int									getXfbBuffer		(void) const { return m_xfbBuffer;				}
getFlags(void) const203 	deUint32							getFlags			(void) const { return m_flags;					}
204 
setInstanceName(const std::string & name)205 	void								setInstanceName		(const std::string& name)							{ m_instanceName = name;						}
setFlags(deUint32 flags)206 	void								setFlags			(deUint32 flags)									{ m_flags = flags;								}
setFlag(deUint32 flag)207 	void								setFlag				(deUint32 flag)										{ m_flags |= flag;								}
setArraySize(int arraySize)208 	void								setArraySize		(int arraySize)										{ m_arraySize = arraySize;						}
setXfbBuffer(int xfbBuffer)209 	void								setXfbBuffer		(int xfbBuffer)										{ m_xfbBuffer = xfbBuffer;						}
addInterfaceMember(const InterfaceBlockMember & interfaceBlockMember)210 	void								addInterfaceMember	(const InterfaceBlockMember& interfaceBlockMember)	{ m_members.push_back(interfaceBlockMember);	}
211 
begin(void)212 	inline Iterator						begin				(void)			{ return m_members.begin();		}
begin(void) const213 	inline ConstIterator				begin				(void) const	{ return m_members.begin();		}
end(void)214 	inline Iterator						end					(void)			{ return m_members.end();		}
end(void) const215 	inline ConstIterator				end					(void) const	{ return m_members.end();		}
216 
217 private:
218 	std::string							m_blockName;
219 	std::string							m_instanceName;
220 	std::vector<InterfaceBlockMember>	m_members;
221 	int									m_xfbBuffer;
222 	int									m_arraySize;	//!< Array size or 0 if not interface block array.
223 	deUint32							m_flags;
224 };
225 
226 typedef de::SharedPtr<StructType>		StructTypeSP;
227 typedef de::SharedPtr<InterfaceBlock>	InterfaceBlockSP;
228 
229 class ShaderInterface
230 {
231 public:
232 									ShaderInterface				(void);
233 									~ShaderInterface			(void);
234 
235 	StructType&						allocStruct					(const std::string& name);
236 	void							getNamedStructs				(std::vector<const StructType*>& structs) const;
237 
238 	InterfaceBlock&					allocBlock					(const std::string& name);
239 
getNumInterfaceBlocks(void) const240 	int								getNumInterfaceBlocks		(void) const	{ return (int)m_interfaceBlocks.size();	}
getInterfaceBlock(int ndx) const241 	const InterfaceBlock&			getInterfaceBlock			(int ndx) const	{ return *m_interfaceBlocks[ndx];		}
getInterfaceBlockForModify(int ndx)242 	InterfaceBlock&					getInterfaceBlockForModify	(int ndx)		{ return *m_interfaceBlocks[ndx];		}
243 
244 private:
245 	std::vector<StructTypeSP>		m_structs;
246 	std::vector<InterfaceBlockSP>	m_interfaceBlocks;
247 };
248 
249 struct BlockLayoutEntry
250 {
BlockLayoutEntryvkt::TransformFeedback::BlockLayoutEntry251 	BlockLayoutEntry (void)
252 		: xfbBuffer				(-1)
253 		, xfbOffset				(-1)
254 		, xfbSize				(0)
255 		, xfbStride				(0)
256 		, blockDeclarationNdx	(-1)
257 		, instanceNdx			(-1)
258 		, locationNdx			(-1)
259 		, locationSize			(-1)
260 	{
261 	}
262 
263 	std::string			name;
264 	int					xfbBuffer;
265 	int					xfbOffset;
266 	int					xfbSize;
267 	int					xfbStride;
268 	std::vector<int>	activeInterfaceIndices;
269 	int					blockDeclarationNdx;
270 	int					instanceNdx;
271 	// Location are not used for transform feedback, but they must be not overlap to pass GLSL compiler
272 	int					locationNdx;
273 	int					locationSize;
274 };
275 
276 struct InterfaceLayoutEntry
277 {
InterfaceLayoutEntryvkt::TransformFeedback::InterfaceLayoutEntry278 	InterfaceLayoutEntry (void)
279 		: type			(glu::TYPE_LAST)
280 		, arraySize		(0)
281 		, blockLayoutNdx(-1)
282 		, offset		(-1)
283 		, arrayStride	(-1)
284 		, matrixStride	(-1)
285 		, instanceNdx	(0)
286 		, locationNdx	(-1)
287 		, validate		(true)
288 	{
289 	}
290 
291 	std::string			name;
292 	glu::DataType		type;
293 	int					arraySize;
294 	int					blockLayoutNdx;
295 	int					offset;
296 	int					arrayStride;
297 	int					matrixStride;
298 	int					instanceNdx;
299 	// Location are not used for transform feedback, but they must be not overlap to pass GLSL compiler
300 	int					locationNdx;
301 	bool				validate;
302 };
303 
304 class InterfaceLayout
305 {
306 public:
307 	std::vector<BlockLayoutEntry>		blocks;
308 	std::vector<InterfaceLayoutEntry>	interfaces;
309 
310 	int									getInterfaceLayoutIndex	(int blockDeclarationNdx, const std::string& name) const;
311 	int									getBlockLayoutIndex		(int blockDeclarationNdx, int instanceNdx) const;
312 };
313 
314 typedef std::vector<vk::VkDeviceSize> DeviceSizeVector;
315 
316 class InterfaceBlockCase : public vkt::TestCase
317 {
318 public:
319 							InterfaceBlockCase			(tcu::TestContext&		testCtx,
320 														 const std::string&		name,
321 														 const std::string&		description,
322 														 MatrixLoadFlags		matrixLoadFlag,
323 														 TestStageFlags			testStageFlag,
324 														 bool					shuffleInterfaceMembers = false);
325 							~InterfaceBlockCase			(void);
326 
327 	virtual void			delayedInit					(void);
328 	virtual	void			initPrograms				(vk::SourceCollections&	programCollection) const;
329 	virtual TestInstance*	createInstance				(Context&				context) const;
330 
331 protected:
332 	ShaderInterface			m_interface;
333 	MatrixLoadFlags			m_matrixLoadFlag;
334 	TestStageFlags			m_testStageFlags;
335 	bool					m_shuffleInterfaceMembers;	//!< Used with explicit offsets to test out of order member offsets
336 	deUint32				m_locationsRequired;
337 
338 private:
339 	std::string				m_vertShaderSource;
340 	std::string				m_geomShaderSource;
341 
342 	std::vector<deUint8>	m_data;						//!< Data.
343 	DeviceSizeVector		m_tfBufBindingSizes;
344 	DeviceSizeVector		m_tfBufBindingOffsets;
345 	std::map<int, void*>	m_blockPointers;			//!< Reference block pointers.
346 	InterfaceLayout			m_interfaceLayout;			//!< interface layout.
347 };
348 
349 } // TransformFeedback
350 } // vkt
351 
352 #endif // _VKTTRANSFORMFEEDBACKFUZZLAYOUTCASE_HPP
353