Home | History | Annotate | Download | only in randomshaders
      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
    274