Merge "Fix extension support checks in negative api tests" into nougat-cts-dev am...
[platform/upstream/VK-GL-CTS.git] / framework / randomshaders / rsgVariableType.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Random Shader Generator
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 Variable Type class.
22  *//*--------------------------------------------------------------------*/
23
24 #include "rsgVariableType.hpp"
25 #include "rsgToken.hpp"
26
27 using std::vector;
28
29 namespace rsg
30 {
31
32 VariableType& VariableType::operator= (const VariableType& other)
33 {
34         if (this == &other)
35                 return *this;
36
37         delete m_elementType;
38
39         m_elementType   = DE_NULL;
40         m_baseType              = other.m_baseType;
41         m_precision             = other.m_precision;
42         m_typeName              = other.m_typeName;
43         m_numElements   = other.m_numElements;
44         m_members               = other.m_members;
45         m_elementType   = DE_NULL;
46
47         if (other.m_elementType)
48                 m_elementType = new VariableType(*other.m_elementType);
49
50         return *this;
51 }
52
53 VariableType::VariableType (const VariableType& other)
54         : m_elementType(DE_NULL)
55 {
56         *this = other;
57 }
58
59 bool VariableType::operator!= (const VariableType& other) const
60 {
61         if (m_baseType != other.m_baseType)
62                 return true;
63         if (m_precision != other.m_precision)
64                 return true;
65         if (m_numElements != other.m_numElements)
66                 return true;
67         if (!!m_elementType != !!other.m_elementType)
68                 return true;
69         if (m_elementType && *m_elementType != *other.m_elementType)
70                 return true;
71         if (m_members != other.m_members)
72                 return true;
73         return false;
74 }
75
76 bool VariableType::operator== (const VariableType& other) const
77 {
78         return !(*this != other);
79 }
80
81 int VariableType::getScalarSize (void) const
82 {
83         switch (m_baseType)
84         {
85                 case TYPE_VOID:
86                 case TYPE_FLOAT:
87                 case TYPE_INT:
88                 case TYPE_BOOL:
89                 case TYPE_SAMPLER_2D:
90                 case TYPE_SAMPLER_CUBE:
91                         return m_numElements;
92
93                 case TYPE_STRUCT:
94                 {
95                         int sum = 0;
96                         for (vector<Member>::const_iterator i = m_members.begin(); i != m_members.end(); i++)
97                                 sum += i->getType().getScalarSize();
98                         return sum;
99                 }
100
101                 case TYPE_ARRAY:
102                 {
103                         DE_ASSERT(m_elementType);
104                         return m_elementType->getScalarSize() * m_numElements;
105                 }
106
107                 default:
108                         DE_ASSERT(false);
109                         return 0;
110         }
111 }
112
113 int VariableType::getMemberScalarOffset (int memberNdx) const
114 {
115         DE_ASSERT(isStruct());
116
117         int curOffset = 0;
118         for (vector<Member>::const_iterator i = m_members.begin(); i != m_members.begin() + memberNdx; i++)
119                 curOffset += i->getType().getScalarSize();
120
121         return curOffset;
122 }
123
124 int VariableType::getElementScalarOffset (int elementNdx) const
125 {
126         DE_ASSERT(isArray());
127         return elementNdx * getElementType().getScalarSize();
128 }
129
130 const VariableType& VariableType::getScalarType (Type baseType)
131 {
132         switch (baseType)
133         {
134                 case TYPE_FLOAT:
135                 {
136                         static const VariableType s_floatTypes[] =
137                         {
138                                 VariableType(TYPE_FLOAT, 1)
139                                 // \todo [pyry] Extend with different precision variants?
140                         };
141                         return s_floatTypes[0];
142                 }
143
144                 case TYPE_INT:
145                 {
146                         static const VariableType s_intTypes[] =
147                         {
148                                 VariableType(TYPE_INT, 1)
149                         };
150                         return s_intTypes[0];
151                 }
152
153                 case TYPE_BOOL:
154                 {
155                         static const VariableType s_boolTypes[] =
156                         {
157                                 VariableType(TYPE_BOOL, 1)
158                         };
159                         return s_boolTypes[0];
160                 }
161
162                 case TYPE_SAMPLER_2D:
163                 {
164                         static const VariableType sampler2DType = VariableType(TYPE_SAMPLER_2D, 1);
165                         return sampler2DType;
166                 }
167
168                 case TYPE_SAMPLER_CUBE:
169                 {
170                         static const VariableType samplerCubeType = VariableType(TYPE_SAMPLER_CUBE, 1);
171                         return samplerCubeType;
172                 }
173
174                 default:
175                         DE_ASSERT(DE_FALSE);
176                         throw Exception("VariableType::getScalarType(): unsupported type");
177         }
178 }
179
180 const VariableType& VariableType::getElementType (void) const
181 {
182         DE_ASSERT(m_precision == PRECISION_NONE); // \todo [pyry] Precision
183         switch (m_baseType)
184         {
185                 case TYPE_FLOAT:
186                 case TYPE_INT:
187                 case TYPE_BOOL:
188                 case TYPE_SAMPLER_2D:
189                 case TYPE_SAMPLER_CUBE:
190                         return getScalarType(m_baseType);
191
192                 case TYPE_ARRAY:
193                 {
194                         DE_ASSERT(m_elementType);
195                         return *m_elementType;
196                 }
197
198                 default:
199                         DE_ASSERT(DE_FALSE);
200                         throw Exception("VariableType::getElementType(): unsupported type");
201         }
202 }
203
204 void VariableType::tokenizeShortType (TokenStream& str) const
205 {
206         switch (m_precision)
207         {
208                 case PRECISION_LOW:             str << Token::LOW_PRECISION;    break;
209                 case PRECISION_MEDIUM:  str << Token::MEDIUM_PRECISION; break;
210                 case PRECISION_HIGH:    str << Token::HIGH_PRECISION;   break;
211                 default:                                /* nothing */                                   break;
212         }
213
214         switch (m_baseType)
215         {
216                 case TYPE_VOID:
217                         str << Token::VOID;
218                         break;
219
220                 case TYPE_FLOAT:
221                         switch (m_numElements)
222                         {
223                                 case 1:         str << Token::FLOAT;            break;
224                                 case 2:         str << Token::VEC2;                     break;
225                                 case 3:         str << Token::VEC3;                     break;
226                                 case 4:         str << Token::VEC4;                     break;
227                                 default:        DE_ASSERT(DE_FALSE);            break;
228                         }
229                         break;
230
231                 case TYPE_INT:
232                         switch (m_numElements)
233                         {
234                                 case 1:         str << Token::INT;                      break;
235                                 case 2:         str << Token::IVEC2;            break;
236                                 case 3:         str << Token::IVEC3;            break;
237                                 case 4:         str << Token::IVEC4;            break;
238                                 default:        DE_ASSERT(DE_FALSE);            break;
239                         }
240                         break;
241
242                 case TYPE_BOOL:
243                         switch (m_numElements)
244                         {
245                                 case 1:         str << Token::BOOL;                     break;
246                                 case 2:         str << Token::BVEC2;            break;
247                                 case 3:         str << Token::BVEC3;            break;
248                                 case 4:         str << Token::BVEC4;            break;
249                                 default:        DE_ASSERT(DE_FALSE);            break;
250                         }
251                         break;
252
253                 case TYPE_SAMPLER_2D:           str << Token::SAMPLER2D;        break;
254                 case TYPE_SAMPLER_CUBE:         str << Token::SAMPLERCUBE;      break;
255
256                 case TYPE_STRUCT:
257                         DE_ASSERT(m_typeName != "");
258                         str << Token(m_typeName.c_str());
259                         break;
260
261                 case TYPE_ARRAY:
262                         DE_ASSERT(m_elementType);
263                         m_elementType->tokenizeShortType(str);
264                         str << Token::LEFT_BRACKET << Token(m_numElements) << Token::RIGHT_BRACKET;
265                         break;
266
267                 default:
268                         DE_ASSERT(DE_FALSE);
269                         break;
270         }
271 }
272
273 } // rsg