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