13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _GLUVARTYPEUTIL_HPP
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _GLUVARTYPEUTIL_HPP
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES Utilities
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------------
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shader variable type utilities.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarType.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iterator>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace glu
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Variable path tokenizer
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VarTokenizer
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Token
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TOKEN_IDENTIFIER = 0,
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TOKEN_LEFT_BRACKET,
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TOKEN_RIGHT_BRACKET,
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TOKEN_PERIOD,
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TOKEN_NUMBER,
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TOKEN_END,
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TOKEN_LAST
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					VarTokenizer					(const char* str);
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~VarTokenizer					(void) {}
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Token			getToken						(void) const { return m_token;															}
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string		getIdentifier					(void) const { return std::string(m_str+m_tokenStart, m_str+m_tokenStart+m_tokenLen);	}
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				getNumber						(void) const;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				getCurrentTokenStartLocation	(void) const { return m_tokenStart;														}
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				getCurrentTokenEndLocation		(void) const { return m_tokenStart + m_tokenLen;										}
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			advance							(void);
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		m_str;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Token			m_token;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				m_tokenStart;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				m_tokenLen;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// VarType subtype path utilities.
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VarTypeComponent
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Type
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STRUCT_MEMBER = 0,
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ARRAY_ELEMENT,
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MATRIX_COLUMN,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VECTOR_COMPONENT,
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_LAST
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				VarTypeComponent	(Type type_, int index_)	: type(type_), index(index_) {}
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				VarTypeComponent	(void)						: type(TYPE_LAST), index(0) {}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		operator==			(const VarTypeComponent& other) const { return type == other.type && index == other.index; }
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		operator!=			(const VarTypeComponent& other) const { return type != other.type || index != other.index; }
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Type		type;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			index;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef std::vector<VarTypeComponent> TypeComponentVector;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TypeComponentVector utilties.
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Iterator>
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool			isValidTypePath		(const VarType& type, Iterator begin, Iterator end);
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Iterator>
1033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVarType			getVarType			(const VarType& type, Iterator begin, Iterator end);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool		isValidTypePath		(const VarType& type, const TypeComponentVector& path) { return isValidTypePath(type, path.begin(), path.end()); }
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline VarType	getVarType			(const VarType& type, const TypeComponentVector& path) { return getVarType(type, path.begin(), path.end()); }
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string		parseVariableName	(const char* nameWithPath);
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid			parseTypePath		(const char* nameWithPath, const VarType& type, TypeComponentVector& path);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Type path formatter.
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct TypeAccessFormat
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TypeAccessFormat (const VarType& type_, const TypeComponentVector& path_) : type(type_), path(path_) {}
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VarType&					type;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TypeComponentVector&		path;
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream&		operator<<		(std::ostream& str, const TypeAccessFormat& format);
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Subtype path builder.
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SubTypeAccess
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								SubTypeAccess		(const VarType& type);
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess&				member				(int ndx)	{ m_path.push_back(VarTypeComponent(VarTypeComponent::STRUCT_MEMBER,	ndx)); DE_ASSERT(isValid()); return *this; } //!< Access struct element.
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess&				element				(int ndx)	{ m_path.push_back(VarTypeComponent(VarTypeComponent::ARRAY_ELEMENT,	ndx)); DE_ASSERT(isValid()); return *this; } //!< Access array element.
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess&				column				(int ndx)	{ m_path.push_back(VarTypeComponent(VarTypeComponent::MATRIX_COLUMN,	ndx)); DE_ASSERT(isValid()); return *this; } //!< Access column.
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess&				component			(int ndx)	{ m_path.push_back(VarTypeComponent(VarTypeComponent::VECTOR_COMPONENT,	ndx)); DE_ASSERT(isValid()); return *this; } //!< Access component.
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess&				parent				(void)		{ DE_ASSERT(!m_path.empty()); m_path.pop_back(); return *this; }
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess				member				(int ndx) const { return SubTypeAccess(*this).member(ndx);		}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess				element				(int ndx) const { return SubTypeAccess(*this).element(ndx);		}
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess				column				(int ndx) const { return SubTypeAccess(*this).column(ndx);		}
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess				component			(int ndx) const { return SubTypeAccess(*this).component(ndx);	}
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeAccess				parent				(void) const	{ return SubTypeAccess(*this).parent();			}
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						isValid				(void) const	{ return isValidTypePath(m_type, m_path);		}
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarType						getType				(void) const	{ return getVarType(m_type, m_path);			}
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TypeComponentVector&	getPath				(void) const	{ return m_path;								}
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						empty				(void) const { return m_path.empty(); }
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						operator==			(const SubTypeAccess& other) const { return m_path == other.m_path && m_type == other.m_type; }
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						operator!=			(const SubTypeAccess& other) const { return m_path != other.m_path || m_type != other.m_type; }
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarType						m_type;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TypeComponentVector			m_path;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Subtype iterator.
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note VarType must be live during iterator usage.
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class IsExpanded>
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SubTypeIterator : public std::iterator<std::forward_iterator_tag, VarType>
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static SubTypeIterator<IsExpanded>	begin				(const VarType* type) { return SubTypeIterator(type);						}
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static SubTypeIterator<IsExpanded>	end					(const VarType* type) { DE_UNREF(type); return SubTypeIterator(DE_NULL);	}
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool								operator==			(const SubTypeIterator<IsExpanded>& other) const { return m_type == other.m_type && m_path == other.m_path; }
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool								operator!=			(const SubTypeIterator<IsExpanded>& other) const { return m_type != other.m_type || m_path != other.m_path; }
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeIterator<IsExpanded>&		operator++			(void);
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SubTypeIterator<IsExpanded>			operator++			(int)	{ SubTypeIterator<IsExpanded> copy(*this); ++(*this); return copy; }
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								toStream			(std::ostream& str) const { str << TypeAccessFormat(*m_type, m_path); }
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarType								getType				(void) const { return getVarType(*m_type, m_path.begin(), m_path.end()); }
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TypeComponentVector&			getPath				(void) const { return m_path; }
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarType								operator*			(void) const { return getType(); }
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										SubTypeIterator		(const VarType* type);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								removeTraversed		(void);
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								findNext			(void);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VarType*						m_type;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TypeComponentVector					m_path;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct IsBasicType			{ bool operator() (const VarType& type) const { return type.isBasicType(); } };
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct IsScalarType			{ bool operator() (const VarType& type) const { return type.isBasicType() && isDataTypeScalar(type.getBasicType()); } };
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct IsVectorOrScalarType	{ bool operator() (const VarType& type) const { return type.isBasicType() && isDataTypeScalarOrVector(type.getBasicType()); } };
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef SubTypeIterator<IsBasicType>			BasicTypeIterator;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef SubTypeIterator<IsVectorOrScalarType>	VectorTypeIterator;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef SubTypeIterator<IsScalarType>			ScalarTypeIterator;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class IsExpanded>
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const SubTypeIterator<IsExpanded>& iter)
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	iter.toStream(str);
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class IsExpanded>
2043c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySubTypeIterator<IsExpanded>::SubTypeIterator (const VarType* type)
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type(type)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_type)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		findNext();
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class IsExpanded>
2123c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySubTypeIterator<IsExpanded>& SubTypeIterator<IsExpanded>::operator++ (void)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_path.empty())
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Remove traversed nodes.
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		removeTraversed();
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_path.empty())
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			findNext();
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_type = DE_NULL; // Unset type to signal end.
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// First type was already expanded.
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(IsExpanded()(getVarType(*m_type, m_path)));
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_type = DE_NULL;
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class IsExpanded>
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SubTypeIterator<IsExpanded>::removeTraversed (void)
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_type && !m_path.empty());
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Pop traversed nodes.
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (!m_path.empty())
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarTypeComponent&	curComp		= m_path.back();
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarType				parentType	= getVarType(*m_type, m_path.begin(), m_path.end()-1);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (curComp.type == VarTypeComponent::MATRIX_COLUMN)
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(isDataTypeMatrix(parentType.getBasicType()));
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (curComp.index+1 < getDataTypeMatrixNumColumns(parentType.getBasicType()))
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (curComp.type == VarTypeComponent::VECTOR_COMPONENT)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(isDataTypeVector(parentType.getBasicType()));
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (curComp.index+1 < getDataTypeScalarSize(parentType.getBasicType()))
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (curComp.type == VarTypeComponent::ARRAY_ELEMENT)
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(parentType.isArrayType());
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (curComp.index+1 < parentType.getArraySize())
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (curComp.type == VarTypeComponent::STRUCT_MEMBER)
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(parentType.isStructType());
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (curComp.index+1 < parentType.getStructPtr()->getNumMembers())
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_path.pop_back();
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class IsExpanded>
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SubTypeIterator<IsExpanded>::findNext (void)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_path.empty())
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Increment child counter in current level.
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarTypeComponent& curComp = m_path.back();
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curComp.index += 1;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (;;)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarType curType = getVarType(*m_type, m_path);
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (IsExpanded()(curType))
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Recurse into child type.
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (curType.isBasicType())
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DataType basicType = curType.getBasicType();
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDataTypeMatrix(basicType))
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_path.push_back(VarTypeComponent(VarTypeComponent::MATRIX_COLUMN, 0));
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (isDataTypeVector(basicType))
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_path.push_back(VarTypeComponent(VarTypeComponent::VECTOR_COMPONENT, 0));
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false); // Can't expand scalars - IsExpanded() is buggy.
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (curType.isArrayType())
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_path.push_back(VarTypeComponent(VarTypeComponent::ARRAY_ELEMENT, 0));
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (curType.isStructType())
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_path.push_back(VarTypeComponent(VarTypeComponent::STRUCT_MEMBER, 0));
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Iterator>
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isValidTypePath (const VarType& type, Iterator begin, Iterator end)
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VarType*	curType		= &type;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Iterator		pathIter	= begin;
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Process struct member and array element parts of path.
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (pathIter != end)
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pathIter->type == VarTypeComponent::STRUCT_MEMBER)
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!curType->isStructType() || !de::inBounds(pathIter->index, 0, curType->getStructPtr()->getNumMembers()))
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			curType = &curType->getStructPtr()->getMember(pathIter->index).getType();
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (pathIter->type == VarTypeComponent::ARRAY_ELEMENT)
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!curType->isArrayType() || (curType->getArraySize() != VarType::UNSIZED_ARRAY && !de::inBounds(pathIter->index, 0, curType->getArraySize())))
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			curType = &curType->getElementType();
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		++pathIter;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (pathIter != end)
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(pathIter->type == VarTypeComponent::MATRIX_COLUMN || pathIter->type == VarTypeComponent::VECTOR_COMPONENT);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Current type should be basic type.
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!curType->isBasicType())
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataType basicType = curType->getBasicType();
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pathIter->type == VarTypeComponent::MATRIX_COLUMN)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isDataTypeMatrix(basicType))
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicType = getDataTypeFloatVec(getDataTypeMatrixNumRows(basicType));
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			++pathIter;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pathIter != end && pathIter->type == VarTypeComponent::VECTOR_COMPONENT)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isDataTypeVector(basicType))
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicType = getDataTypeScalarType(basicType);
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			++pathIter;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return pathIter == end;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Iterator>
3743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVarType getVarType (const VarType& type, Iterator begin, Iterator end)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(isValidTypePath(type, begin, end));
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VarType*	curType		= &type;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Iterator		pathIter	= begin;
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Process struct member and array element parts of path.
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (pathIter != end)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pathIter->type == VarTypeComponent::STRUCT_MEMBER)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			curType = &curType->getStructPtr()->getMember(pathIter->index).getType();
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (pathIter->type == VarTypeComponent::ARRAY_ELEMENT)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			curType = &curType->getElementType();
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		++pathIter;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (pathIter != end)
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataType	basicType	= curType->getBasicType();
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Precision	precision	= curType->getPrecision();
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pathIter->type == VarTypeComponent::MATRIX_COLUMN)
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicType = getDataTypeFloatVec(getDataTypeMatrixNumRows(basicType));
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			++pathIter;
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pathIter != end && pathIter->type == VarTypeComponent::VECTOR_COMPONENT)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicType = getDataTypeScalarType(basicType);
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			++pathIter;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(pathIter == end);
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return VarType(basicType, precision);
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return VarType(*curType);
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // glu
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _GLUVARTYPEUTIL_HPP
421