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