1 #ifndef _GLUVARTYPEUTIL_HPP
2 #define _GLUVARTYPEUTIL_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program OpenGL ES Utilities
5 * ------------------------------------------------
7 * Copyright 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Shader variable type utilities.
24 *//*--------------------------------------------------------------------*/
26 #include "tcuDefs.hpp"
27 #include "gluVarType.hpp"
36 // Variable path tokenizer
53 VarTokenizer (const char* str);
54 ~VarTokenizer (void) {}
56 Token getToken (void) const { return m_token; }
57 std::string getIdentifier (void) const { return std::string(m_str+m_tokenStart, m_str+m_tokenStart+m_tokenLen); }
58 int getNumber (void) const;
59 int getCurrentTokenStartLocation (void) const { return m_tokenStart; }
60 int getCurrentTokenEndLocation (void) const { return m_tokenStart + m_tokenLen; }
71 // VarType subtype path utilities.
73 struct VarTypeComponent
85 VarTypeComponent (Type type_, int index_) : type(type_), index(index_) {}
86 VarTypeComponent (void) : type(TYPE_LAST), index(0) {}
88 bool operator== (const VarTypeComponent& other) const { return type == other.type && index == other.index; }
89 bool operator!= (const VarTypeComponent& other) const { return type != other.type || index != other.index; }
95 typedef std::vector<VarTypeComponent> TypeComponentVector;
97 // TypeComponentVector utilties.
99 template <typename Iterator>
100 bool isValidTypePath (const VarType& type, Iterator begin, Iterator end);
102 template <typename Iterator>
103 VarType getVarType (const VarType& type, Iterator begin, Iterator end);
105 inline bool isValidTypePath (const VarType& type, const TypeComponentVector& path) { return isValidTypePath(type, path.begin(), path.end()); }
106 inline VarType getVarType (const VarType& type, const TypeComponentVector& path) { return getVarType(type, path.begin(), path.end()); }
108 std::string parseVariableName (const char* nameWithPath);
109 void parseTypePath (const char* nameWithPath, const VarType& type, TypeComponentVector& path);
111 // Type path formatter.
113 struct TypeAccessFormat
115 TypeAccessFormat (const VarType& type_, const TypeComponentVector& path_) : type(type_), path(path_) {}
118 const TypeComponentVector& path;
121 std::ostream& operator<< (std::ostream& str, const TypeAccessFormat& format);
123 // Subtype path builder.
128 SubTypeAccess (const VarType& type);
130 SubTypeAccess& member (int ndx) { m_path.push_back(VarTypeComponent(VarTypeComponent::STRUCT_MEMBER, ndx)); DE_ASSERT(isValid()); return *this; } //!< Access struct element.
131 SubTypeAccess& element (int ndx) { m_path.push_back(VarTypeComponent(VarTypeComponent::ARRAY_ELEMENT, ndx)); DE_ASSERT(isValid()); return *this; } //!< Access array element.
132 SubTypeAccess& column (int ndx) { m_path.push_back(VarTypeComponent(VarTypeComponent::MATRIX_COLUMN, ndx)); DE_ASSERT(isValid()); return *this; } //!< Access column.
133 SubTypeAccess& component (int ndx) { m_path.push_back(VarTypeComponent(VarTypeComponent::VECTOR_COMPONENT, ndx)); DE_ASSERT(isValid()); return *this; } //!< Access component.
134 SubTypeAccess& parent (void) { DE_ASSERT(!m_path.empty()); m_path.pop_back(); return *this; }
136 SubTypeAccess member (int ndx) const { return SubTypeAccess(*this).member(ndx); }
137 SubTypeAccess element (int ndx) const { return SubTypeAccess(*this).element(ndx); }
138 SubTypeAccess column (int ndx) const { return SubTypeAccess(*this).column(ndx); }
139 SubTypeAccess component (int ndx) const { return SubTypeAccess(*this).component(ndx); }
140 SubTypeAccess parent (void) const { return SubTypeAccess(*this).parent(); }
142 bool isValid (void) const { return isValidTypePath(m_type, m_path); }
143 VarType getType (void) const { return getVarType(m_type, m_path); }
144 const TypeComponentVector& getPath (void) const { return m_path; }
146 bool empty (void) const { return m_path.empty(); }
148 bool operator== (const SubTypeAccess& other) const { return m_path == other.m_path && m_type == other.m_type; }
149 bool operator!= (const SubTypeAccess& other) const { return m_path != other.m_path || m_type != other.m_type; }
153 TypeComponentVector m_path;
158 // \note VarType must be live during iterator usage.
159 template <class IsExpanded>
160 class SubTypeIterator : public std::iterator<std::forward_iterator_tag, VarType>
163 static SubTypeIterator<IsExpanded> begin (const VarType* type) { return SubTypeIterator(type); }
164 static SubTypeIterator<IsExpanded> end (const VarType* type) { DE_UNREF(type); return SubTypeIterator(DE_NULL); }
166 bool operator== (const SubTypeIterator<IsExpanded>& other) const { return m_type == other.m_type && m_path == other.m_path; }
167 bool operator!= (const SubTypeIterator<IsExpanded>& other) const { return m_type != other.m_type || m_path != other.m_path; }
169 SubTypeIterator<IsExpanded>& operator++ (void);
170 SubTypeIterator<IsExpanded> operator++ (int) { SubTypeIterator<IsExpanded> copy(*this); ++(*this); return copy; }
172 void toStream (std::ostream& str) const { str << TypeAccessFormat(*m_type, m_path); }
173 VarType getType (void) const { return getVarType(*m_type, m_path.begin(), m_path.end()); }
174 const TypeComponentVector& getPath (void) const { return m_path; }
176 VarType operator* (void) const { return getType(); }
179 SubTypeIterator (const VarType* type);
181 void removeTraversed (void);
182 void findNext (void);
184 const VarType* m_type;
185 TypeComponentVector m_path;
188 struct IsBasicType { bool operator() (const VarType& type) const { return type.isBasicType(); } };
189 struct IsScalarType { bool operator() (const VarType& type) const { return type.isBasicType() && isDataTypeScalar(type.getBasicType()); } };
190 struct IsVectorOrScalarType { bool operator() (const VarType& type) const { return type.isBasicType() && isDataTypeScalarOrVector(type.getBasicType()); } };
192 typedef SubTypeIterator<IsBasicType> BasicTypeIterator;
193 typedef SubTypeIterator<IsVectorOrScalarType> VectorTypeIterator;
194 typedef SubTypeIterator<IsScalarType> ScalarTypeIterator;
196 template <class IsExpanded>
197 std::ostream& operator<< (std::ostream& str, const SubTypeIterator<IsExpanded>& iter)
203 template <class IsExpanded>
204 SubTypeIterator<IsExpanded>::SubTypeIterator (const VarType* type)
211 template <class IsExpanded>
212 SubTypeIterator<IsExpanded>& SubTypeIterator<IsExpanded>::operator++ (void)
216 // Remove traversed nodes.
222 m_type = DE_NULL; // Unset type to signal end.
226 // First type was already expanded.
227 DE_ASSERT(IsExpanded()(getVarType(*m_type, m_path)));
234 template <class IsExpanded>
235 void SubTypeIterator<IsExpanded>::removeTraversed (void)
237 DE_ASSERT(m_type && !m_path.empty());
239 // Pop traversed nodes.
240 while (!m_path.empty())
242 VarTypeComponent& curComp = m_path.back();
243 VarType parentType = getVarType(*m_type, m_path.begin(), m_path.end()-1);
245 if (curComp.type == VarTypeComponent::MATRIX_COLUMN)
247 DE_ASSERT(isDataTypeMatrix(parentType.getBasicType()));
248 if (curComp.index+1 < getDataTypeMatrixNumColumns(parentType.getBasicType()))
251 else if (curComp.type == VarTypeComponent::VECTOR_COMPONENT)
253 DE_ASSERT(isDataTypeVector(parentType.getBasicType()));
254 if (curComp.index+1 < getDataTypeScalarSize(parentType.getBasicType()))
257 else if (curComp.type == VarTypeComponent::ARRAY_ELEMENT)
259 DE_ASSERT(parentType.isArrayType());
260 if (curComp.index+1 < parentType.getArraySize())
263 else if (curComp.type == VarTypeComponent::STRUCT_MEMBER)
265 DE_ASSERT(parentType.isStructType());
266 if (curComp.index+1 < parentType.getStructPtr()->getNumMembers())
274 template <class IsExpanded>
275 void SubTypeIterator<IsExpanded>::findNext (void)
279 // Increment child counter in current level.
280 VarTypeComponent& curComp = m_path.back();
286 VarType curType = getVarType(*m_type, m_path);
288 if (IsExpanded()(curType))
291 // Recurse into child type.
292 if (curType.isBasicType())
294 DataType basicType = curType.getBasicType();
296 if (isDataTypeMatrix(basicType))
297 m_path.push_back(VarTypeComponent(VarTypeComponent::MATRIX_COLUMN, 0));
298 else if (isDataTypeVector(basicType))
299 m_path.push_back(VarTypeComponent(VarTypeComponent::VECTOR_COMPONENT, 0));
301 DE_ASSERT(false); // Can't expand scalars - IsExpanded() is buggy.
303 else if (curType.isArrayType())
304 m_path.push_back(VarTypeComponent(VarTypeComponent::ARRAY_ELEMENT, 0));
305 else if (curType.isStructType())
306 m_path.push_back(VarTypeComponent(VarTypeComponent::STRUCT_MEMBER, 0));
312 template <typename Iterator>
313 bool isValidTypePath (const VarType& type, Iterator begin, Iterator end)
315 const VarType* curType = &type;
316 Iterator pathIter = begin;
318 // Process struct member and array element parts of path.
319 while (pathIter != end)
321 if (pathIter->type == VarTypeComponent::STRUCT_MEMBER)
323 if (!curType->isStructType() || !de::inBounds(pathIter->index, 0, curType->getStructPtr()->getNumMembers()))
326 curType = &curType->getStructPtr()->getMember(pathIter->index).getType();
328 else if (pathIter->type == VarTypeComponent::ARRAY_ELEMENT)
330 if (!curType->isArrayType() || (curType->getArraySize() != VarType::UNSIZED_ARRAY && !de::inBounds(pathIter->index, 0, curType->getArraySize())))
333 curType = &curType->getElementType();
343 DE_ASSERT(pathIter->type == VarTypeComponent::MATRIX_COLUMN || pathIter->type == VarTypeComponent::VECTOR_COMPONENT);
345 // Current type should be basic type.
346 if (!curType->isBasicType())
349 DataType basicType = curType->getBasicType();
351 if (pathIter->type == VarTypeComponent::MATRIX_COLUMN)
353 if (!isDataTypeMatrix(basicType))
356 basicType = getDataTypeFloatVec(getDataTypeMatrixNumRows(basicType));
360 if (pathIter != end && pathIter->type == VarTypeComponent::VECTOR_COMPONENT)
362 if (!isDataTypeVector(basicType))
365 basicType = getDataTypeScalarType(basicType);
370 return pathIter == end;
373 template <typename Iterator>
374 VarType getVarType (const VarType& type, Iterator begin, Iterator end)
376 TCU_CHECK(isValidTypePath(type, begin, end));
378 const VarType* curType = &type;
379 Iterator pathIter = begin;
381 // Process struct member and array element parts of path.
382 while (pathIter != end)
384 if (pathIter->type == VarTypeComponent::STRUCT_MEMBER)
385 curType = &curType->getStructPtr()->getMember(pathIter->index).getType();
386 else if (pathIter->type == VarTypeComponent::ARRAY_ELEMENT)
387 curType = &curType->getElementType();
396 DataType basicType = curType->getBasicType();
397 Precision precision = curType->getPrecision();
399 if (pathIter->type == VarTypeComponent::MATRIX_COLUMN)
401 basicType = getDataTypeFloatVec(getDataTypeMatrixNumRows(basicType));
405 if (pathIter != end && pathIter->type == VarTypeComponent::VECTOR_COMPONENT)
407 basicType = getDataTypeScalarType(basicType);
411 DE_ASSERT(pathIter == end);
412 return VarType(basicType, precision);
415 return VarType(*curType);
420 #endif // _GLUVARTYPEUTIL_HPP