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 
33 namespace glu
34 {
35 
36 class 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  *//*--------------------------------------------------------------------*/
47 class VarType
48 {
49 public:
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 
isBasicType(void) const58 	bool				isBasicType		(void) const	{ return m_type == VARTYPE_BASIC;	}
isArrayType(void) const59 	bool				isArrayType		(void) const	{ return m_type == VARTYPE_ARRAY;	}
isStructType(void) const60 	bool				isStructType	(void) const	{ return m_type == VARTYPE_STRUCT;	}
61 
getBasicType(void) const62 	DataType			getBasicType	(void) const	{ DE_ASSERT(isBasicType()); return m_data.basic.type;			}
getPrecision(void) const63 	Precision			getPrecision	(void) const	{ DE_ASSERT(isBasicType()); return m_data.basic.precision;		}
64 
getElementType(void) const65 	const VarType&		getElementType	(void) const	{ DE_ASSERT(isArrayType()); return *m_data.array.elementType;	}
getArraySize(void) const66 	int					getArraySize	(void) const	{ DE_ASSERT(isArrayType()); return m_data.array.size;			}
67 
getStructPtr(void) const68 	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 
82 private:
83 	enum Type
84 	{
85 		VARTYPE_BASIC,
86 		VARTYPE_ARRAY,
87 		VARTYPE_STRUCT,
88 
89 		VARTYPE_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 
Data(void)112 		Data (void)
113 		{
114 			array.elementType	= DE_NULL;
115 			array.size			= 0;
116 		};
117 	} m_data;
118 } DE_WARN_UNUSED_TYPE;
119 
120 template <typename T>
varTypeOf(Precision prec=PRECISION_LAST)121 inline VarType varTypeOf (Precision prec = PRECISION_LAST) { return VarType(dataTypeOf<T>(), prec); }
122 
123 class StructMember
124 {
125 public:
StructMember(const char * name,const VarType & type)126 						StructMember	(const char* name, const VarType& type) : m_name(name), m_type(type) {}
StructMember(void)127 						StructMember	(void) {}
128 
getName(void) const129 	const char*			getName			(void) const { return m_name.c_str();	}
getType(void) const130 	const VarType&		getType			(void) const { return m_type;			}
131 
132 	bool				operator==		(const StructMember& other) const;
133 	bool				operator!=		(const StructMember& other) const;
134 
135 private:
136 	std::string			m_name;
137 	VarType				m_type;
138 } DE_WARN_UNUSED_TYPE;
139 
140 class StructType
141 {
142 public:
143 	typedef std::vector<StructMember>::iterator			Iterator;
144 	typedef std::vector<StructMember>::const_iterator	ConstIterator;
145 
StructType(const char * typeName)146 								StructType		(const char* typeName) : m_typeName(typeName) {}
~StructType(void)147 								~StructType		(void) {}
148 
hasTypeName(void) const149 	bool						hasTypeName		(void) const	{ return !m_typeName.empty();	}
getTypeName(void) const150 	const char*					getTypeName		(void) const	{ return hasTypeName() ? m_typeName.c_str() : DE_NULL; }
151 
152 	void						addMember		(const char* name, const VarType& type);
153 
getNumMembers(void) const154 	int							getNumMembers	(void) const	{ return (int)m_members.size();	}
getMember(int ndx) const155 	const StructMember&			getMember		(int ndx) const	{ return m_members[ndx];		}
156 
begin(void)157 	inline Iterator				begin			(void)			{ return m_members.begin();		}
begin(void) const158 	inline ConstIterator		begin			(void) const	{ return m_members.begin();		}
end(void)159 	inline Iterator				end				(void)			{ return m_members.end();		}
end(void) const160 	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 
165 private:
166 	std::string					m_typeName;
167 	std::vector<StructMember>	m_members;
168 } DE_WARN_UNUSED_TYPE;
169 
170 enum 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 
182 const char* getStorageName (Storage storage);
183 
184 enum Interpolation
185 {
186 	INTERPOLATION_SMOOTH = 0,
187 	INTERPOLATION_FLAT,
188 	INTERPOLATION_CENTROID,
189 	INTERPOLATION_LAST
190 };
191 
192 const char* getInterpolationName (Interpolation interpolation);
193 
194 enum 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 
215 const char* getFormatLayoutName (FormatLayout layout);
216 
217 enum 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 
228 const char* getMemoryAccessQualifierName (MemoryAccessQualifier qualifier);
229 
230 enum MatrixOrder
231 {
232 	MATRIXORDER_COLUMN_MAJOR = 0,
233 	MATRIXORDER_ROW_MAJOR,
234 
235 	MATRIXORDER_LAST
236 };
237 
238 const char* getMatrixOrderName (MatrixOrder qualifier);
239 
240 // Declaration utilities.
241 
242 struct 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 
256 struct 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 
271 struct 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.
285 namespace decl
286 {
287 
288 struct Indent
289 {
290 	int level;
Indentglu::decl::Indent291 	Indent (int level_) : level(level_) {}
292 };
293 
294 struct DeclareStructTypePtr
295 {
DeclareStructTypePtrglu::decl::DeclareStructTypePtr296 	DeclareStructTypePtr (const StructType* structPtr_, int indentLevel_) : structPtr(structPtr_), indentLevel(indentLevel_) {}
297 
298 	const StructType*	structPtr;
299 	int					indentLevel;
300 };
301 
302 struct DeclareStructType
303 {
DeclareStructTypeglu::decl::DeclareStructType304 	DeclareStructType (const StructType& structType_, int indentLevel_) : structType(structType_), indentLevel(indentLevel_) {}
305 
306 	StructType			structType;
307 	int					indentLevel;
308 };
309 
310 struct DeclareVariable
311 {
DeclareVariableglu::decl::DeclareVariable312 	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 
319 std::ostream&		operator<<		(std::ostream& str, const Indent&				indent);
320 std::ostream&		operator<<		(std::ostream& str, const DeclareStructTypePtr&	decl);
321 std::ostream&		operator<<		(std::ostream& str, const DeclareStructType&	decl);
322 std::ostream&		operator<<		(std::ostream& str, const DeclareVariable&		decl);
323 
324 } // decl
325 
indent(int indentLevel)326 inline decl::Indent					indent			(int indentLevel)														{ return decl::Indent(indentLevel);									}
declare(const StructType * structPtr,int indentLevel=0)327 inline decl::DeclareStructTypePtr	declare			(const StructType*	structPtr,	int indentLevel = 0)					{ return decl::DeclareStructTypePtr	(structPtr,		indentLevel);	}
declare(const StructType & structType,int indentLevel=0)328 inline decl::DeclareStructType		declare			(const StructType&	structType,	int indentLevel = 0)					{ return decl::DeclareStructType	(structType,	indentLevel);	}
declare(const VarType & varType,const std::string & name,int indentLevel=0)329 inline decl::DeclareVariable		declare			(const VarType& varType, const std::string& name, int indentLevel = 0)	{ return decl::DeclareVariable		(varType, name, indentLevel);	}
330 
331 std::ostream&						operator<<		(std::ostream& str, const Layout& decl);
332 std::ostream&						operator<<		(std::ostream& str, const VariableDeclaration& decl);
333 
334 } // glu
335 
336 #endif // _GLUVARTYPE_HPP
337