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
59 {
60 return m_type == VARTYPE_BASIC;
61 }
isArrayType(void) const62 bool isArrayType(void) const
63 {
64 return m_type == VARTYPE_ARRAY;
65 }
isStructType(void) const66 bool isStructType(void) const
67 {
68 return m_type == VARTYPE_STRUCT;
69 }
70
getBasicType(void) const71 DataType getBasicType(void) const
72 {
73 DE_ASSERT(isBasicType());
74 return m_data.basic.type;
75 }
getPrecision(void) const76 Precision getPrecision(void) const
77 {
78 DE_ASSERT(isBasicType());
79 return m_data.basic.precision;
80 }
81
getElementType(void) const82 const VarType &getElementType(void) const
83 {
84 DE_ASSERT(isArrayType());
85 return *m_data.array.elementType;
86 }
getArraySize(void) const87 int getArraySize(void) const
88 {
89 DE_ASSERT(isArrayType());
90 return m_data.array.size;
91 }
92
getStructPtr(void) const93 const StructType *getStructPtr(void) const
94 {
95 DE_ASSERT(isStructType());
96 return m_data.structPtr;
97 }
98
99 int getScalarSize(void) const;
100
101 VarType &operator=(const VarType &other);
102
103 bool operator==(const VarType &other) const;
104 bool operator!=(const VarType &other) const;
105
106 enum
107 {
108 UNSIZED_ARRAY = -1 //!< Array length for unsized arrays.
109 };
110
111 private:
112 enum Type
113 {
114 VARTYPE_BASIC,
115 VARTYPE_ARRAY,
116 VARTYPE_STRUCT,
117
118 VARTYPE_LAST
119 };
120
121 Type m_type;
122 union Data
123 {
124 // TYPE_BASIC
125 struct
126 {
127 DataType type;
128 Precision precision;
129 } basic;
130
131 // TYPE_ARRAY
132 struct
133 {
134 VarType *elementType;
135 int size;
136 } array;
137
138 // TYPE_STRUCT
139 const StructType *structPtr;
140
Data(void)141 Data(void)
142 {
143 array.elementType = DE_NULL;
144 array.size = 0;
145 }
146 } m_data;
147 } DE_WARN_UNUSED_TYPE;
148
149 template <typename T>
varTypeOf(Precision prec=PRECISION_LAST)150 inline VarType varTypeOf(Precision prec = PRECISION_LAST)
151 {
152 return VarType(dataTypeOf<T>(), prec);
153 }
154
155 class StructMember
156 {
157 public:
StructMember(const char * name,const VarType & type)158 StructMember(const char *name, const VarType &type) : m_name(name), m_type(type)
159 {
160 }
StructMember(void)161 StructMember(void)
162 {
163 }
164
getName(void) const165 const char *getName(void) const
166 {
167 return m_name.c_str();
168 }
getType(void) const169 const VarType &getType(void) const
170 {
171 return m_type;
172 }
173
174 bool operator==(const StructMember &other) const;
175 bool operator!=(const StructMember &other) const;
176
177 private:
178 std::string m_name;
179 VarType m_type;
180 } DE_WARN_UNUSED_TYPE;
181
182 class StructType
183 {
184 public:
185 typedef std::vector<StructMember>::iterator Iterator;
186 typedef std::vector<StructMember>::const_iterator ConstIterator;
187
StructType(const char * typeName)188 StructType(const char *typeName) : m_typeName(typeName)
189 {
190 }
~StructType(void)191 ~StructType(void)
192 {
193 }
194
hasTypeName(void) const195 bool hasTypeName(void) const
196 {
197 return !m_typeName.empty();
198 }
getTypeName(void) const199 const char *getTypeName(void) const
200 {
201 return hasTypeName() ? m_typeName.c_str() : DE_NULL;
202 }
203
204 void addMember(const char *name, const VarType &type);
205
getNumMembers(void) const206 int getNumMembers(void) const
207 {
208 return (int)m_members.size();
209 }
getMember(int ndx) const210 const StructMember &getMember(int ndx) const
211 {
212 return m_members[ndx];
213 }
214
begin(void)215 inline Iterator begin(void)
216 {
217 return m_members.begin();
218 }
begin(void) const219 inline ConstIterator begin(void) const
220 {
221 return m_members.begin();
222 }
end(void)223 inline Iterator end(void)
224 {
225 return m_members.end();
226 }
end(void) const227 inline ConstIterator end(void) const
228 {
229 return m_members.end();
230 }
231
232 bool operator==(const StructType &other) const;
233 bool operator!=(const StructType &other) const;
234
235 private:
236 std::string m_typeName;
237 std::vector<StructMember> m_members;
238 } DE_WARN_UNUSED_TYPE;
239
240 enum Storage
241 {
242 STORAGE_IN = 0,
243 STORAGE_OUT,
244 STORAGE_CONST,
245 STORAGE_UNIFORM,
246 STORAGE_BUFFER,
247 STORAGE_PATCH_IN,
248 STORAGE_PATCH_OUT,
249 STORAGE_LAST
250 };
251
252 const char *getStorageName(Storage storage);
253
254 enum Interpolation
255 {
256 INTERPOLATION_SMOOTH = 0,
257 INTERPOLATION_FLAT,
258 INTERPOLATION_CENTROID,
259 INTERPOLATION_LAST
260 };
261
262 const char *getInterpolationName(Interpolation interpolation);
263
264 enum FormatLayout
265 {
266 FORMATLAYOUT_RGBA32F = 0,
267 FORMATLAYOUT_RGBA16F,
268 FORMATLAYOUT_R32F,
269 FORMATLAYOUT_RGBA8,
270 FORMATLAYOUT_RGBA8_SNORM,
271
272 FORMATLAYOUT_RGBA32I,
273 FORMATLAYOUT_RGBA16I,
274 FORMATLAYOUT_RGBA8I,
275 FORMATLAYOUT_R32I,
276
277 FORMATLAYOUT_RGBA32UI,
278 FORMATLAYOUT_RGBA16UI,
279 FORMATLAYOUT_RGBA8UI,
280 FORMATLAYOUT_R32UI,
281
282 FORMATLAYOUT_LAST
283 };
284
285 const char *getFormatLayoutName(FormatLayout layout);
286
287 enum MemoryAccessQualifier
288 {
289 MEMORYACCESSQUALIFIER_COHERENT_BIT = 0x01,
290 MEMORYACCESSQUALIFIER_VOLATILE_BIT = 0x02,
291 MEMORYACCESSQUALIFIER_RESTRICT_BIT = 0x04,
292 MEMORYACCESSQUALIFIER_READONLY_BIT = 0x08,
293 MEMORYACCESSQUALIFIER_WRITEONLY_BIT = 0x10,
294
295 MEMORYACCESSQUALIFIER_MASK = (MEMORYACCESSQUALIFIER_WRITEONLY_BIT << 1) - 1
296 };
297
298 const char *getMemoryAccessQualifierName(MemoryAccessQualifier qualifier);
299
300 enum MatrixOrder
301 {
302 MATRIXORDER_COLUMN_MAJOR = 0,
303 MATRIXORDER_ROW_MAJOR,
304
305 MATRIXORDER_LAST
306 };
307
308 const char *getMatrixOrderName(MatrixOrder qualifier);
309
310 // Declaration utilities.
311
312 struct Layout
313 {
314 Layout(int location_ = -1, int binding_ = -1, int offset_ = -1, FormatLayout format_ = FORMATLAYOUT_LAST,
315 MatrixOrder matrixOrder_ = MATRIXORDER_LAST);
316
317 bool operator==(const Layout &other) const;
318 bool operator!=(const Layout &other) const;
319
320 int location;
321 int binding;
322 int offset;
323 FormatLayout format;
324 MatrixOrder matrixOrder;
325 } DE_WARN_UNUSED_TYPE;
326
327 struct VariableDeclaration
328 {
329 VariableDeclaration(const VarType &varType_, const std::string &name_, Storage storage_ = STORAGE_LAST,
330 Interpolation interpolation_ = INTERPOLATION_LAST, const Layout &layout_ = Layout(),
331 uint32_t memoryAccessQualifierBits_ = 0);
332
333 bool operator==(const VariableDeclaration &other) const;
334 bool operator!=(const VariableDeclaration &other) const;
335
336 Layout layout;
337 Interpolation interpolation;
338 Storage storage;
339 VarType varType;
340 uint32_t memoryAccessQualifierBits;
341 std::string name;
342 } DE_WARN_UNUSED_TYPE;
343
344 struct InterfaceBlock
345 {
346 InterfaceBlock(void);
347
348 glu::Layout layout;
349 Storage storage;
350 int memoryAccessQualifierFlags;
351 std::string interfaceName;
352 std::string instanceName;
353 std::vector<glu::VariableDeclaration> variables;
354 std::vector<int> dimensions;
355 } DE_WARN_UNUSED_TYPE;
356
357 //! Internals for declare() utilities.
358 namespace decl
359 {
360
361 struct Indent
362 {
363 int level;
Indentglu::decl::Indent364 Indent(int level_) : level(level_)
365 {
366 }
367 };
368
369 struct DeclareStructTypePtr
370 {
DeclareStructTypePtrglu::decl::DeclareStructTypePtr371 DeclareStructTypePtr(const StructType *structPtr_, int indentLevel_)
372 : structPtr(structPtr_)
373 , indentLevel(indentLevel_)
374 {
375 }
376
377 const StructType *structPtr;
378 int indentLevel;
379 };
380
381 struct DeclareStructType
382 {
DeclareStructTypeglu::decl::DeclareStructType383 DeclareStructType(const StructType &structType_, int indentLevel_)
384 : structType(structType_)
385 , indentLevel(indentLevel_)
386 {
387 }
388
389 StructType structType;
390 int indentLevel;
391 };
392
393 struct DeclareVariable
394 {
DeclareVariableglu::decl::DeclareVariable395 DeclareVariable(const VarType &varType_, const std::string &name_, int indentLevel_)
396 : varType(varType_)
397 , name(name_)
398 , indentLevel(indentLevel_)
399 {
400 }
401
402 VarType varType;
403 std::string name;
404 int indentLevel;
405 };
406
407 std::ostream &operator<<(std::ostream &str, const Indent &indent);
408 std::ostream &operator<<(std::ostream &str, const DeclareStructTypePtr &decl);
409 std::ostream &operator<<(std::ostream &str, const DeclareStructType &decl);
410 std::ostream &operator<<(std::ostream &str, const DeclareVariable &decl);
411
412 } // namespace decl
413
indent(int indentLevel)414 inline decl::Indent indent(int indentLevel)
415 {
416 return decl::Indent(indentLevel);
417 }
declare(const StructType * structPtr,int indentLevel=0)418 inline decl::DeclareStructTypePtr declare(const StructType *structPtr, int indentLevel = 0)
419 {
420 return decl::DeclareStructTypePtr(structPtr, indentLevel);
421 }
declare(const StructType & structType,int indentLevel=0)422 inline decl::DeclareStructType declare(const StructType &structType, int indentLevel = 0)
423 {
424 return decl::DeclareStructType(structType, indentLevel);
425 }
declare(const VarType & varType,const std::string & name,int indentLevel=0)426 inline decl::DeclareVariable declare(const VarType &varType, const std::string &name, int indentLevel = 0)
427 {
428 return decl::DeclareVariable(varType, name, indentLevel);
429 }
430
431 std::ostream &operator<<(std::ostream &str, const Layout &decl);
432 std::ostream &operator<<(std::ostream &str, const VariableDeclaration &decl);
433
434 } // namespace glu
435
436 #endif // _GLUVARTYPE_HPP
437