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