15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/*-------------------------------------------------------------------------
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * drawElements Quality Program Random Shader Generator
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * ----------------------------------------------------
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Copyright 2014 The Android Open Source Project
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * you may not use this file except in compliance with the License.
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * You may obtain a copy of the License at
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Unless required by applicable law or agreed to in writing, software
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * See the License for the specific language governing permissions and
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * limitations under the License.
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *//*!
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * \file
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * \brief Variable Type class.
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *//*--------------------------------------------------------------------*/
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "rsgVariableType.hpp"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "rsgToken.hpp"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::vector;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace rsg
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VariableType& VariableType::operator= (const VariableType& other)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (this == &other)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		return *this;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	delete m_elementType;
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	m_elementType	= DE_NULL;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	m_baseType		= other.m_baseType;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	m_precision		= other.m_precision;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	m_typeName		= other.m_typeName;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	m_numElements	= other.m_numElements;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	m_members		= other.m_members;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	m_elementType	= DE_NULL;
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (other.m_elementType)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		m_elementType = new VariableType(*other.m_elementType);
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	return *this;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VariableType::VariableType (const VariableType& other)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	: m_elementType(DE_NULL)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	*this = other;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool VariableType::operator!= (const VariableType& other) const
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	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
76bool VariableType::operator== (const VariableType& other) const
77{
78	return !(*this != other);
79}
80
81int 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
113int 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
124int VariableType::getElementScalarOffset (int elementNdx) const
125{
126	DE_ASSERT(isArray());
127	return elementNdx * getElementType().getScalarSize();
128}
129
130const 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
180const 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
204void 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
274