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