vktUniformBlockCase.hpp revision d1f78adb5104f9f6cf274522f835ac10630c91d2
1#ifndef _VKTUNIFORMBLOCKCASE_HPP
2#define _VKTUNIFORMBLOCKCASE_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 Uniform block tests.
25 *//*--------------------------------------------------------------------*/
26
27#include "deSharedPtr.hpp"
28#include "vktTestCase.hpp"
29#include "tcuDefs.hpp"
30#include "gluShaderUtil.hpp"
31
32#include <map>
33
34namespace vkt
35{
36namespace ubo
37{
38
39// Uniform block details.
40
41enum UniformFlags
42{
43	PRECISION_LOW		= (1<<0),
44	PRECISION_MEDIUM	= (1<<1),
45	PRECISION_HIGH		= (1<<2),
46	PRECISION_MASK		= PRECISION_LOW|PRECISION_MEDIUM|PRECISION_HIGH,
47
48	LAYOUT_SHARED		= (1<<3),
49	LAYOUT_PACKED		= (1<<4),
50	LAYOUT_STD140		= (1<<5),
51	LAYOUT_ROW_MAJOR	= (1<<6),
52	LAYOUT_COLUMN_MAJOR	= (1<<7),	//!< \note Lack of both flags means column-major matrix.
53	LAYOUT_MASK			= LAYOUT_SHARED|LAYOUT_PACKED|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR,
54
55	DECLARE_VERTEX		= (1<<8),
56	DECLARE_FRAGMENT	= (1<<9),
57	DECLARE_BOTH		= DECLARE_VERTEX|DECLARE_FRAGMENT,
58
59	UNUSED_VERTEX		= (1<<10),	//!< Uniform or struct member is not read in vertex shader.
60	UNUSED_FRAGMENT		= (1<<11),	//!< Uniform or struct member is not read in fragment shader.
61	UNUSED_BOTH			= UNUSED_VERTEX|UNUSED_FRAGMENT
62};
63
64class StructType;
65
66class VarType
67{
68public:
69						VarType			(void);
70						VarType			(const VarType& other);
71						VarType			(glu::DataType basicType, deUint32 flags);
72						VarType			(const VarType& elementType, int arraySize);
73	explicit			VarType			(const StructType* structPtr);
74						~VarType		(void);
75
76	bool				isBasicType		(void) const	{ return m_type == TYPE_BASIC;	}
77	bool				isArrayType		(void) const	{ return m_type == TYPE_ARRAY;	}
78	bool				isStructType	(void) const	{ return m_type == TYPE_STRUCT;	}
79
80	deUint32			getFlags		(void) const	{ return m_flags;					}
81	glu::DataType		getBasicType	(void) const	{ return m_data.basicType;			}
82
83	const VarType&		getElementType	(void) const	{ return *m_data.array.elementType;	}
84	int					getArraySize	(void) const	{ return m_data.array.size;			}
85
86	const StructType&	getStruct		(void) const	{ return *m_data.structPtr;			}
87
88	VarType&			operator=		(const VarType& other);
89
90private:
91	enum Type
92	{
93		TYPE_BASIC,
94		TYPE_ARRAY,
95		TYPE_STRUCT,
96
97		TYPE_LAST
98	};
99
100	Type				m_type;
101	deUint32			m_flags;
102	union Data
103	{
104		glu::DataType		basicType;
105		struct
106		{
107			VarType*		elementType;
108			int				size;
109		} array;
110		const StructType*	structPtr;
111
112		Data (void)
113		{
114			array.elementType	= DE_NULL;
115			array.size			= 0;
116		};
117	} m_data;
118};
119
120class StructMember
121{
122public:
123						StructMember	(const std::string& name, const VarType& type, deUint32 flags)
124							: m_name(name), m_type(type), m_flags(flags)
125						{}
126						StructMember	(void)
127							: m_flags(0)
128						{}
129
130	const std::string&	getName			(void) const { return m_name;	}
131	const VarType&		getType			(void) const { return m_type;	}
132	deUint32			getFlags		(void) const { return m_flags;	}
133
134private:
135	std::string			m_name;
136	VarType				m_type;
137	deUint32			m_flags;
138};
139
140class StructType
141{
142public:
143	typedef std::vector<StructMember>::iterator			Iterator;
144	typedef std::vector<StructMember>::const_iterator	ConstIterator;
145
146								StructType		(const std::string& typeName) : m_typeName(typeName) {}
147								~StructType		(void) {}
148
149	const std::string&			getTypeName		(void) const	{ return m_typeName;			}
150	bool						hasTypeName		(void) const	{ return !m_typeName.empty();	}
151
152	inline Iterator				begin			(void)			{ return m_members.begin();		}
153	inline ConstIterator		begin			(void) const	{ return m_members.begin();		}
154	inline Iterator				end				(void)			{ return m_members.end();		}
155	inline ConstIterator		end				(void) const	{ return m_members.end();		}
156
157	void						addMember		(const std::string& name, const VarType& type, deUint32 flags = 0);
158
159private:
160	std::string					m_typeName;
161	std::vector<StructMember>	m_members;
162};
163
164class Uniform
165{
166public:
167						Uniform			(const std::string& name, const VarType& type, deUint32 flags = 0);
168
169	const std::string&	getName			(void) const { return m_name;	}
170	const VarType&		getType			(void) const { return m_type;	}
171	deUint32			getFlags		(void) const { return m_flags;	}
172
173private:
174	std::string			m_name;
175	VarType				m_type;
176	deUint32			m_flags;
177};
178
179class UniformBlock
180{
181public:
182	typedef std::vector<Uniform>::iterator			Iterator;
183	typedef std::vector<Uniform>::const_iterator	ConstIterator;
184
185							UniformBlock		(const std::string& blockName);
186
187	const std::string&		getBlockName		(void) const { return m_blockName;		}
188	const std::string&		getInstanceName		(void) const { return m_instanceName;	}
189	bool					hasInstanceName		(void) const { return !m_instanceName.empty();	}
190	bool					isArray				(void) const { return m_arraySize > 0;			}
191	int						getArraySize		(void) const { return m_arraySize;				}
192	deUint32				getFlags			(void) const { return m_flags;					}
193
194	void					setInstanceName		(const std::string& name)	{ m_instanceName = name;			}
195	void					setFlags			(deUint32 flags)			{ m_flags = flags;					}
196	void					setArraySize		(int arraySize)				{ m_arraySize = arraySize;			}
197	void					addUniform			(const Uniform& uniform)	{ m_uniforms.push_back(uniform);	}
198
199	inline Iterator			begin				(void)			{ return m_uniforms.begin();	}
200	inline ConstIterator	begin				(void) const	{ return m_uniforms.begin();	}
201	inline Iterator			end					(void)			{ return m_uniforms.end();		}
202	inline ConstIterator	end					(void) const	{ return m_uniforms.end();		}
203
204private:
205	std::string				m_blockName;
206	std::string				m_instanceName;
207	std::vector<Uniform>	m_uniforms;
208	int						m_arraySize;	//!< Array size or 0 if not interface block array.
209	deUint32				m_flags;
210};
211
212typedef de::SharedPtr<StructType>	StructTypeSP;
213typedef de::SharedPtr<UniformBlock>	UniformBlockSP;
214
215class ShaderInterface
216{
217public:
218								ShaderInterface			(void);
219								~ShaderInterface		(void);
220
221	StructType&					allocStruct				(const std::string& name);
222	void						getNamedStructs			(std::vector<const StructType*>& structs) const;
223
224	UniformBlock&				allocBlock				(const std::string& name);
225
226	int							getNumUniformBlocks		(void) const	{ return (int)m_uniformBlocks.size();	}
227	const UniformBlock&			getUniformBlock			(int ndx) const	{ return *m_uniformBlocks[ndx];			}
228
229private:
230	std::vector<StructTypeSP>		m_structs;
231	std::vector<UniformBlockSP>		m_uniformBlocks;
232};
233
234struct BlockLayoutEntry
235{
236	BlockLayoutEntry (void)
237		: size(0)
238	{
239	}
240
241	std::string			name;
242	int					size;
243	std::vector<int>	activeUniformIndices;
244	int					bindingNdx;
245	int					instanceNdx;
246};
247
248struct UniformLayoutEntry
249{
250	UniformLayoutEntry (void)
251		: type			(glu::TYPE_LAST)
252		, size			(0)
253		, blockNdx		(-1)
254		, offset		(-1)
255		, arrayStride	(-1)
256		, matrixStride	(-1)
257		, isRowMajor	(false)
258		, instanceNdx	(0)
259	{
260	}
261
262	std::string			name;
263	glu::DataType		type;
264	int					size;
265	int					blockNdx;
266	int					offset;
267	int					arrayStride;
268	int					matrixStride;
269	bool				isRowMajor;
270	int					instanceNdx;
271};
272
273class UniformLayout
274{
275public:
276	std::vector<BlockLayoutEntry>		blocks;
277	std::vector<UniformLayoutEntry>		uniforms;
278
279	int									getUniformIndex			(const std::string& name) const;
280	int									getBlockIndex			(const std::string& name) const;
281};
282
283class UniformBlockCase : public vkt::TestCase
284{
285public:
286	enum BufferMode
287	{
288		BUFFERMODE_SINGLE = 0,	//!< Single buffer shared between uniform blocks.
289		BUFFERMODE_PER_BLOCK,	//!< Per-block buffers
290
291		BUFFERMODE_LAST
292	};
293
294								UniformBlockCase			(tcu::TestContext&	testCtx,
295															 const std::string&	name,
296															 const std::string&	description,
297															 BufferMode			bufferMode,
298															 MatrixLoadFlags	matrixLoadFlag);
299								~UniformBlockCase			(void);
300
301	virtual	void				initPrograms				(vk::SourceCollections& programCollection) const;
302	virtual TestInstance*		createInstance				(Context& context) const;
303
304protected:
305	void						init						(void);
306
307	BufferMode					m_bufferMode;
308	ShaderInterface				m_interface;
309	MatrixLoadFlags				m_matrixLoadFlag;
310
311private:
312	std::string					m_vertShaderSource;
313	std::string					m_fragShaderSource;
314
315	std::vector<deUint8>		m_data;				//!< Data.
316	std::map<int, void*>		m_blockPointers;	//!< Reference block pointers.
317	UniformLayout				m_uniformLayout;	//!< std140 layout.
318};
319
320} // ubo
321} // vkt
322
323#endif // _VKTUNIFORMBLOCKCASE_HPP
324