1#ifndef _GLUVARTYPE_HPP
2#define _GLUVARTYPE_HPP
3/*-------------------------------------------------------------------------
4 * drawElements Quality Program OpenGL ES Utilities
5 * ------------------------------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Shader variable type.
24 *//*--------------------------------------------------------------------*/
25
26#include "tcuDefs.hpp"
27#include "gluShaderUtil.hpp"
28
29#include <vector>
30#include <string>
31#include <ostream>
32
33namespace glu
34{
35
36class StructType;
37
38/*--------------------------------------------------------------------*//*!
39 * \brief Shader variable type.
40 *
41 * Variable type represents data type. No storage qualifiers are supported
42 * since they are associated to a declaration, not to the variable type.
43 *
44 * \note Structs are handled using struct pointers since it is often desirable
45 *		 to maintain unique list of struct declarations.
46 *//*--------------------------------------------------------------------*/
47class VarType
48{
49public:
50						VarType			(void);
51						VarType			(const VarType& other);
52
53						VarType			(DataType basicType, Precision precision);		//!< Basic type constructor.
54						VarType			(const VarType& elementType, int arraySize);	//!< Array type constructor.
55	explicit			VarType			(const StructType* structPtr);					//!< Struct type constructor.
56						~VarType		(void);
57
58	bool				isBasicType		(void) const	{ return m_type == TYPE_BASIC;	}
59	bool				isArrayType		(void) const	{ return m_type == TYPE_ARRAY;	}
60	bool				isStructType	(void) const	{ return m_type == TYPE_STRUCT;	}
61
62	DataType			getBasicType	(void) const	{ DE_ASSERT(isBasicType()); return m_data.basic.type;			}
63	Precision			getPrecision	(void) const	{ DE_ASSERT(isBasicType()); return m_data.basic.precision;		}
64
65	const VarType&		getElementType	(void) const	{ DE_ASSERT(isArrayType()); return *m_data.array.elementType;	}
66	int					getArraySize	(void) const	{ DE_ASSERT(isArrayType()); return m_data.array.size;			}
67
68	const StructType*	getStructPtr	(void) const	{ DE_ASSERT(isStructType()); return m_data.structPtr;			}
69
70	int					getScalarSize	(void) const;
71
72	VarType&			operator=		(const VarType& other);
73
74	bool				operator==		(const VarType& other) const;
75	bool				operator!=		(const VarType& other) const;
76
77	enum
78	{
79		UNSIZED_ARRAY = -1 //!< Array length for unsized arrays.
80	};
81
82private:
83	enum Type
84	{
85		TYPE_BASIC,
86		TYPE_ARRAY,
87		TYPE_STRUCT,
88
89		TYPE_LAST
90	};
91
92	Type				m_type;
93	union Data
94	{
95		// TYPE_BASIC
96		struct
97		{
98			DataType		type;
99			Precision		precision;
100		} basic;
101
102		// TYPE_ARRAY
103		struct
104		{
105			VarType*		elementType;
106			int				size;
107		} array;
108
109		// TYPE_STRUCT
110		const StructType*	structPtr;
111
112		Data (void)
113		{
114			array.elementType	= DE_NULL;
115			array.size			= 0;
116		};
117	} m_data;
118} DE_WARN_UNUSED_TYPE;
119
120template <typename T>
121inline VarType varTypeOf (Precision prec = PRECISION_LAST) { return VarType(dataTypeOf<T>(), prec); }
122
123class StructMember
124{
125public:
126						StructMember	(const char* name, const VarType& type) : m_name(name), m_type(type) {}
127						StructMember	(void) {}
128
129	const char*			getName			(void) const { return m_name.c_str();	}
130	const VarType&		getType			(void) const { return m_type;			}
131
132	bool				operator==		(const StructMember& other) const;
133	bool				operator!=		(const StructMember& other) const;
134
135private:
136	std::string			m_name;
137	VarType				m_type;
138} DE_WARN_UNUSED_TYPE;
139
140class StructType
141{
142public:
143	typedef std::vector<StructMember>::iterator			Iterator;
144	typedef std::vector<StructMember>::const_iterator	ConstIterator;
145
146								StructType		(const char* typeName) : m_typeName(typeName) {}
147								~StructType		(void) {}
148
149	bool						hasTypeName		(void) const	{ return !m_typeName.empty();	}
150	const char*					getTypeName		(void) const	{ return hasTypeName() ? m_typeName.c_str() : DE_NULL; }
151
152	void						addMember		(const char* name, const VarType& type);
153
154	int							getNumMembers	(void) const	{ return (int)m_members.size();	}
155	const StructMember&			getMember		(int ndx) const	{ return m_members[ndx];		}
156
157	inline Iterator				begin			(void)			{ return m_members.begin();		}
158	inline ConstIterator		begin			(void) const	{ return m_members.begin();		}
159	inline Iterator				end				(void)			{ return m_members.end();		}
160	inline ConstIterator		end				(void) const	{ return m_members.end();		}
161
162	bool						operator==		(const StructType& other) const;
163	bool						operator!=		(const StructType& other) const;
164
165private:
166	std::string					m_typeName;
167	std::vector<StructMember>	m_members;
168} DE_WARN_UNUSED_TYPE;
169
170enum Storage
171{
172	STORAGE_IN = 0,
173	STORAGE_OUT,
174	STORAGE_CONST,
175	STORAGE_UNIFORM,
176	STORAGE_BUFFER,
177	STORAGE_PATCH_IN,
178	STORAGE_PATCH_OUT,
179	STORAGE_LAST
180};
181
182const char* getStorageName (Storage storage);
183
184enum Interpolation
185{
186	INTERPOLATION_SMOOTH = 0,
187	INTERPOLATION_FLAT,
188	INTERPOLATION_CENTROID,
189	INTERPOLATION_LAST
190};
191
192const char* getInterpolationName (Interpolation interpolation);
193
194enum FormatLayout
195{
196	FORMATLAYOUT_RGBA32F = 0,
197	FORMATLAYOUT_RGBA16F,
198	FORMATLAYOUT_R32F,
199	FORMATLAYOUT_RGBA8,
200	FORMATLAYOUT_RGBA8_SNORM,
201
202	FORMATLAYOUT_RGBA32I,
203	FORMATLAYOUT_RGBA16I,
204	FORMATLAYOUT_RGBA8I,
205	FORMATLAYOUT_R32I,
206
207	FORMATLAYOUT_RGBA32UI,
208	FORMATLAYOUT_RGBA16UI,
209	FORMATLAYOUT_RGBA8UI,
210	FORMATLAYOUT_R32UI,
211
212	FORMATLAYOUT_LAST
213};
214
215const char* getFormatLayoutName (FormatLayout layout);
216
217enum MemoryAccessQualifier
218{
219	MEMORYACCESSQUALIFIER_COHERENT_BIT	= 0x01,
220	MEMORYACCESSQUALIFIER_VOLATILE_BIT	= 0x02,
221	MEMORYACCESSQUALIFIER_RESTRICT_BIT	= 0x04,
222	MEMORYACCESSQUALIFIER_READONLY_BIT	= 0x08,
223	MEMORYACCESSQUALIFIER_WRITEONLY_BIT	= 0x10,
224
225	MEMORYACCESSQUALIFIER_MASK = (MEMORYACCESSQUALIFIER_WRITEONLY_BIT << 1) - 1
226};
227
228const char* getMemoryAccessQualifierName (MemoryAccessQualifier qualifier);
229
230enum MatrixOrder
231{
232	MATRIXORDER_COLUMN_MAJOR = 0,
233	MATRIXORDER_ROW_MAJOR,
234
235	MATRIXORDER_LAST
236};
237
238const char* getMatrixOrderName (MatrixOrder qualifier);
239
240// Declaration utilities.
241
242struct Layout
243{
244					Layout			(int location_ = -1, int binding_ = -1, int offset_ = -1, FormatLayout format_ = FORMATLAYOUT_LAST, MatrixOrder matrixOrder_ = MATRIXORDER_LAST);
245
246	bool			operator==		(const Layout& other) const;
247	bool			operator!=		(const Layout& other) const;
248
249	int				location;
250	int				binding;
251	int				offset;
252	FormatLayout	format;
253	MatrixOrder		matrixOrder;
254} DE_WARN_UNUSED_TYPE;
255
256struct VariableDeclaration
257{
258						VariableDeclaration	(const VarType& varType_, const std::string& name_, Storage storage_ = STORAGE_LAST, Interpolation interpolation_ = INTERPOLATION_LAST, const Layout& layout_ = Layout(), deUint32 memoryAccessQualifierBits_ = 0);
259
260	bool				operator==			(const VariableDeclaration& other) const;
261	bool				operator!=			(const VariableDeclaration& other) const;
262
263	Layout				layout;
264	Interpolation		interpolation;
265	Storage				storage;
266	VarType				varType;
267	deUint32			memoryAccessQualifierBits;
268	std::string			name;
269} DE_WARN_UNUSED_TYPE;
270
271struct InterfaceBlock
272{
273											InterfaceBlock	(void);
274
275	glu::Layout								layout;
276	Storage									storage;
277	int										memoryAccessQualifierFlags;
278	std::string								interfaceName;
279	std::string								instanceName;
280	std::vector<glu::VariableDeclaration>	variables;
281	std::vector<int>						dimensions;
282} DE_WARN_UNUSED_TYPE;
283
284//! Internals for declare() utilities.
285namespace decl
286{
287
288struct Indent
289{
290	int level;
291	Indent (int level_) : level(level_) {}
292};
293
294struct DeclareStructTypePtr
295{
296	DeclareStructTypePtr (const StructType* structPtr_, int indentLevel_) : structPtr(structPtr_), indentLevel(indentLevel_) {}
297
298	const StructType*	structPtr;
299	int					indentLevel;
300};
301
302struct DeclareStructType
303{
304	DeclareStructType (const StructType& structType_, int indentLevel_) : structType(structType_), indentLevel(indentLevel_) {}
305
306	StructType			structType;
307	int					indentLevel;
308};
309
310struct DeclareVariable
311{
312	DeclareVariable (const VarType& varType_, const std::string& name_, int indentLevel_) : varType(varType_), name(name_), indentLevel(indentLevel_) {}
313
314	VarType				varType;
315	std::string			name;
316	int					indentLevel;
317};
318
319std::ostream&		operator<<		(std::ostream& str, const Indent&				indent);
320std::ostream&		operator<<		(std::ostream& str, const DeclareStructTypePtr&	decl);
321std::ostream&		operator<<		(std::ostream& str, const DeclareStructType&	decl);
322std::ostream&		operator<<		(std::ostream& str, const DeclareVariable&		decl);
323
324} // decl
325
326inline decl::Indent					indent			(int indentLevel)														{ return decl::Indent(indentLevel);									}
327inline decl::DeclareStructTypePtr	declare			(const StructType*	structPtr,	int indentLevel = 0)					{ return decl::DeclareStructTypePtr	(structPtr,		indentLevel);	}
328inline decl::DeclareStructType		declare			(const StructType&	structType,	int indentLevel = 0)					{ return decl::DeclareStructType	(structType,	indentLevel);	}
329inline decl::DeclareVariable		declare			(const VarType& varType, const std::string& name, int indentLevel = 0)	{ return decl::DeclareVariable		(varType, name, indentLevel);	}
330
331std::ostream&						operator<<		(std::ostream& str, const Layout& decl);
332std::ostream&						operator<<		(std::ostream& str, const VariableDeclaration& decl);
333
334} // glu
335
336#endif // _GLUVARTYPE_HPP
337