am 5ff2f2fe: am c6ed4922: Add NOTICE and MODULE_LICENSE files
[platform/upstream/VK-GL-CTS.git] / framework / opengl / gluVarType.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES Utilities
3  * ------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Shader variable type.
22  *//*--------------------------------------------------------------------*/
23
24 #include "gluVarType.hpp"
25 #include "deStringUtil.hpp"
26
27 namespace glu
28 {
29
30 VarType::VarType (void)
31         : m_type(TYPE_LAST)
32 {
33 }
34
35 VarType::VarType (const VarType& other)
36         : m_type(TYPE_LAST)
37 {
38         *this = other;
39 }
40
41 VarType::VarType (DataType basicType, Precision precision)
42         : m_type(TYPE_BASIC)
43 {
44         m_data.basic.type               = basicType;
45         m_data.basic.precision  = precision;
46 }
47
48 VarType::VarType (const VarType& elementType, int arraySize)
49         : m_type(TYPE_ARRAY)
50 {
51         DE_ASSERT(arraySize >= 0 || arraySize == UNSIZED_ARRAY);
52         m_data.array.size                       = arraySize;
53         m_data.array.elementType        = new VarType(elementType);
54 }
55
56 VarType::VarType (const StructType* structPtr)
57         : m_type(TYPE_STRUCT)
58 {
59         m_data.structPtr = structPtr;
60 }
61
62 VarType::~VarType (void)
63 {
64         if (m_type == TYPE_ARRAY)
65                 delete m_data.array.elementType;
66 }
67
68 VarType& VarType::operator= (const VarType& other)
69 {
70         if (this == &other)
71                 return *this; // Self-assignment.
72
73         if (m_type == TYPE_ARRAY)
74                 delete m_data.array.elementType;
75
76         m_type  = other.m_type;
77         m_data  = Data();
78
79         if (m_type == TYPE_ARRAY)
80         {
81                 m_data.array.elementType        = new VarType(*other.m_data.array.elementType);
82                 m_data.array.size                       = other.m_data.array.size;
83         }
84         else
85                 m_data = other.m_data;
86
87         return *this;
88 }
89
90 int VarType::getScalarSize (void) const
91 {
92         switch (m_type)
93         {
94                 case TYPE_BASIC:        return glu::getDataTypeScalarSize(m_data.basic.type);
95                 case TYPE_ARRAY:        return m_data.array.elementType->getScalarSize()*m_data.array.size;
96
97                 case TYPE_STRUCT:
98                 {
99                         int size = 0;
100                         for (StructType::ConstIterator iter = m_data.structPtr->begin(); iter != m_data.structPtr->end(); iter++)
101                                 size += iter->getType().getScalarSize();
102                         return size;
103                 }
104
105                 default:
106                         DE_ASSERT(false);
107                         return 0;
108         }
109 }
110
111 bool VarType::operator== (const VarType& other) const
112 {
113         if (m_type != other.m_type)
114                 return false;
115
116         switch (m_type)
117         {
118                 case TYPE_BASIC:
119                         return  m_data.basic.type == other.m_data.basic.type &&
120                                         m_data.basic.precision == other.m_data.basic.precision;
121
122                 case TYPE_ARRAY:
123                         return  *m_data.array.elementType == *other.m_data.array.elementType &&
124                                         m_data.array.size == other.m_data.array.size;
125
126                 case TYPE_STRUCT:
127                         return m_data.structPtr == other.m_data.structPtr;
128
129                 default:
130                         DE_ASSERT(false);
131                         return 0;
132         }
133 }
134
135 bool VarType::operator!= (const VarType& other) const
136 {
137         return !(*this == other);
138 }
139
140 // StructMember implementation
141
142 bool StructMember::operator== (const StructMember& other) const
143 {
144         return (m_name == other.m_name) && (m_type == other.m_type);
145 }
146
147 bool StructMember::operator!= (const StructMember& other) const
148 {
149         return !(*this == other);
150 }
151
152 // StructType implementation.
153
154 void StructType::addMember (const char* name, const VarType& type)
155 {
156         m_members.push_back(StructMember(name, type));
157 }
158
159 bool StructType::operator== (const StructType& other) const
160 {
161         return (m_typeName == other.m_typeName) && (m_members == other.m_members);
162 }
163
164 bool StructType::operator!= (const StructType& other) const
165 {
166         return !(*this == other);
167 }
168
169 const char* getStorageName (Storage storage)
170 {
171         static const char* const s_names[] = { "in", "out", "const", "uniform", "buffer", "patch in", "patch out" };
172
173         return de::getSizedArrayElement<STORAGE_LAST>(s_names, storage);
174 }
175
176 const char* getInterpolationName (Interpolation interpolation)
177 {
178         static const char* const s_names[] = { "smooth", "flat", "centroid" };
179
180         return de::getSizedArrayElement<INTERPOLATION_LAST>(s_names, interpolation);
181 }
182
183 const char* getFormatLayoutName (FormatLayout layout)
184 {
185         static const char* s_names[] =
186         {
187                 "rgba32f",                      // FORMATLAYOUT_RGBA32F
188                 "rgba16f",                      // FORMATLAYOUT_RGBA16F
189                 "r32f",                         // FORMATLAYOUT_R32F
190                 "rgba8",                        // FORMATLAYOUT_RGBA8
191                 "rgba8_snorm",          // FORMATLAYOUT_RGBA8_SNORM
192                 "rgba32i",                      // FORMATLAYOUT_RGBA32I
193                 "rgba16i",                      // FORMATLAYOUT_RGBA16I
194                 "rgba8i",                       // FORMATLAYOUT_RGBA8I
195                 "r32i",                         // FORMATLAYOUT_R32I
196                 "rgba32ui",                     // FORMATLAYOUT_RGBA32UI
197                 "rgba16ui",                     // FORMATLAYOUT_RGBA16UI
198                 "rgba8ui",                      // FORMATLAYOUT_RGBA8UI
199                 "r32ui",                        // FORMATLAYOUT_R32UI
200         };
201
202         return de::getSizedArrayElement<FORMATLAYOUT_LAST>(s_names, layout);
203 }
204
205 const char* getMemoryAccessQualifierName (MemoryAccessQualifier qualifier)
206 {
207         switch (qualifier)
208         {
209                 case MEMORYACCESSQUALIFIER_COHERENT_BIT:        return "coherent";
210                 case MEMORYACCESSQUALIFIER_VOLATILE_BIT:        return "volatile";
211                 case MEMORYACCESSQUALIFIER_RESTRICT_BIT:        return "restrict";
212                 case MEMORYACCESSQUALIFIER_READONLY_BIT:        return "readonly";
213                 case MEMORYACCESSQUALIFIER_WRITEONLY_BIT:       return "writeonly";
214                 default:
215                         DE_ASSERT(false);
216                         return DE_NULL;
217         }
218 }
219
220 const char* getMatrixOrderName (MatrixOrder qualifier)
221 {
222         static const char* s_names[] =
223         {
224                 "column_major", // MATRIXORDER_COLUMN_MAJOR
225                 "row_major",    // MATRIXORDER_ROW_MAJOR
226         };
227
228         return de::getSizedArrayElement<MATRIXORDER_LAST>(s_names, qualifier);
229 }
230
231 // Layout Implementation
232
233 Layout::Layout (int location_, int binding_, int offset_, FormatLayout format_, MatrixOrder matrixOrder_)
234         : location                      (location_)
235         , binding                       (binding_)
236         , offset                        (offset_)
237         , format                        (format_)
238         , matrixOrder           (matrixOrder_)
239 {
240 }
241
242 bool Layout::operator== (const Layout& other) const
243 {
244         return  location == other.location &&
245                         binding == other.binding &&
246                         offset == other.offset &&
247                         format == other.format &&
248                         matrixOrder == other.matrixOrder;
249 }
250
251 bool Layout::operator!= (const Layout& other) const
252 {
253         return !(*this == other);
254 }
255
256 // VariableDeclaration Implementation
257
258 VariableDeclaration::VariableDeclaration (const VarType& varType_, const std::string& name_, Storage storage_, Interpolation interpolation_, const Layout& layout_, deUint32 memoryAccessQualifierBits_)
259         : layout                                                (layout_)
260         , interpolation                                 (interpolation_)
261         , storage                                               (storage_)
262         , varType                                               (varType_)
263         , memoryAccessQualifierBits             (memoryAccessQualifierBits_)
264         , name                                                  (name_)
265 {
266 }
267
268 bool VariableDeclaration::operator== (const VariableDeclaration& other) const
269 {
270         return  layout == other.layout &&
271                         interpolation == other.interpolation &&
272                         storage == other.storage &&
273                         varType == other.varType &&
274                         memoryAccessQualifierBits == other.memoryAccessQualifierBits &&
275                         name == other.name;
276 }
277
278 bool VariableDeclaration::operator!= (const VariableDeclaration& other) const
279 {
280         return !(*this == other);
281 }
282
283 // InterfaceBlock Implementation
284
285 InterfaceBlock::InterfaceBlock (void)
286         : layout                                                (Layout())
287         , storage                                               (glu::STORAGE_LAST)
288         , memoryAccessQualifierFlags    (0)
289 {
290 }
291
292 // Declaration utilties.
293
294 std::ostream& operator<< (std::ostream& str, const Layout& layout)
295 {
296         std::vector<std::string> layoutDeclarationList;
297
298         if (layout.location != -1)
299                 layoutDeclarationList.push_back("location=" + de::toString(layout.location));
300
301         if (layout.binding != -1)
302                 layoutDeclarationList.push_back("binding=" + de::toString(layout.binding));
303
304         if (layout.offset != -1)
305                 layoutDeclarationList.push_back("offset=" + de::toString(layout.offset));
306
307         if (layout.format != FORMATLAYOUT_LAST)
308                 layoutDeclarationList.push_back(getFormatLayoutName(layout.format));
309
310         if (layout.matrixOrder != MATRIXORDER_LAST)
311                 layoutDeclarationList.push_back(getMatrixOrderName(layout.matrixOrder));
312
313         if (!layoutDeclarationList.empty())
314         {
315                 str << "layout(" << layoutDeclarationList[0];
316
317                 for (int layoutNdx = 1; layoutNdx < (int)layoutDeclarationList.size(); ++layoutNdx)
318                         str << ", " << layoutDeclarationList[layoutNdx];
319
320                 str << ")";
321         }
322
323         return str;
324 }
325
326 std::ostream& operator<< (std::ostream& str, const VariableDeclaration& decl)
327 {
328         if (decl.layout != Layout())
329                 str << decl.layout << " ";
330
331         for (int bitNdx = 0; (1 << bitNdx) & MEMORYACCESSQUALIFIER_MASK; ++bitNdx)
332                 if (decl.memoryAccessQualifierBits & (1 << bitNdx))
333                         str << getMemoryAccessQualifierName((glu::MemoryAccessQualifier)(1 << bitNdx)) << " ";
334
335         if (decl.interpolation != INTERPOLATION_LAST)
336                 str << getInterpolationName(decl.interpolation) << " ";
337
338         if (decl.storage != STORAGE_LAST)
339                 str << getStorageName(decl.storage) << " ";
340
341         str << declare(decl.varType, decl.name);
342
343         return str;
344 }
345
346 namespace decl
347 {
348
349 std::ostream& operator<< (std::ostream& str, const Indent& indent)
350 {
351         for (int i = 0; i < indent.level; i++)
352                 str << "\t";
353         return str;
354 }
355
356 std::ostream& operator<< (std::ostream& str, const DeclareVariable& decl)
357 {
358         const VarType&          type    = decl.varType;
359         const VarType*          curType = &type;
360         std::vector<int>        arraySizes;
361
362         // Handle arrays.
363         while (curType->isArrayType())
364         {
365                 arraySizes.push_back(curType->getArraySize());
366                 curType = &curType->getElementType();
367         }
368
369         if (curType->isBasicType())
370         {
371                 if (curType->getPrecision() != PRECISION_LAST)
372                         str << glu::getPrecisionName(curType->getPrecision()) << " ";
373                 str << glu::getDataTypeName(curType->getBasicType());
374         }
375         else if (curType->isStructType())
376         {
377                 const StructType* structPtr = curType->getStructPtr();
378
379                 if (structPtr->hasTypeName())
380                         str << structPtr->getTypeName();
381                 else
382                         str << declare(structPtr, decl.indentLevel); // Generate inline declaration.
383         }
384         else
385                 DE_ASSERT(false);
386
387         str << " " << decl.name;
388
389         // Print array sizes.
390         for (std::vector<int>::const_iterator sizeIter = arraySizes.begin(); sizeIter != arraySizes.end(); sizeIter++)
391         {
392                 const int arrSize = *sizeIter;
393                 if (arrSize == VarType::UNSIZED_ARRAY)
394                         str << "[]";
395                 else
396                         str << "[" << arrSize << "]";
397         }
398
399         return str;
400 }
401
402 std::ostream& operator<< (std::ostream& str, const DeclareStructTypePtr& decl)
403 {
404         str << "struct";
405
406         // Type name is optional.
407         if (decl.structPtr->hasTypeName())
408                 str << " " << decl.structPtr->getTypeName();
409
410         str << "\n" << indent(decl.indentLevel) << "{\n";
411
412         for (StructType::ConstIterator memberIter = decl.structPtr->begin(); memberIter != decl.structPtr->end(); memberIter++)
413         {
414                 str << indent(decl.indentLevel+1);
415                 str << declare(memberIter->getType(), memberIter->getName(), decl.indentLevel+1) << ";\n";
416         }
417
418         str << indent(decl.indentLevel) << "}";
419
420         return str;
421 }
422
423 std::ostream& operator<< (std::ostream& str, const DeclareStructType& decl)
424 {
425         return str << declare(&decl.structType, decl.indentLevel);
426 }
427
428 } // decl
429 } // glu