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 operator =(const VariableType & other)32VariableType &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 VariableType(const VariableType & other)53VariableType::VariableType(const VariableType &other) : m_elementType(DE_NULL) 54 { 55 *this = other; 56 } 57 operator !=(const VariableType & other) const58bool VariableType::operator!=(const VariableType &other) const 59 { 60 if (m_baseType != other.m_baseType) 61 return true; 62 if (m_precision != other.m_precision) 63 return true; 64 if (m_numElements != other.m_numElements) 65 return true; 66 if (!!m_elementType != !!other.m_elementType) 67 return true; 68 if (m_elementType && *m_elementType != *other.m_elementType) 69 return true; 70 if (m_members != other.m_members) 71 return true; 72 return false; 73 } 74 operator ==(const VariableType & other) const75bool VariableType::operator==(const VariableType &other) const 76 { 77 return !(*this != other); 78 } 79 getScalarSize(void) const80int VariableType::getScalarSize(void) const 81 { 82 switch (m_baseType) 83 { 84 case TYPE_VOID: 85 case TYPE_FLOAT: 86 case TYPE_INT: 87 case TYPE_BOOL: 88 case TYPE_SAMPLER_2D: 89 case TYPE_SAMPLER_CUBE: 90 return m_numElements; 91 92 case TYPE_STRUCT: 93 { 94 int sum = 0; 95 for (vector<Member>::const_iterator i = m_members.begin(); i != m_members.end(); i++) 96 sum += i->getType().getScalarSize(); 97 return sum; 98 } 99 100 case TYPE_ARRAY: 101 { 102 DE_ASSERT(m_elementType); 103 return m_elementType->getScalarSize() * m_numElements; 104 } 105 106 default: 107 DE_ASSERT(false); 108 return 0; 109 } 110 } 111 getMemberScalarOffset(int memberNdx) const112int VariableType::getMemberScalarOffset(int memberNdx) const 113 { 114 DE_ASSERT(isStruct()); 115 116 int curOffset = 0; 117 for (vector<Member>::const_iterator i = m_members.begin(); i != m_members.begin() + memberNdx; i++) 118 curOffset += i->getType().getScalarSize(); 119 120 return curOffset; 121 } 122 getElementScalarOffset(int elementNdx) const123int VariableType::getElementScalarOffset(int elementNdx) const 124 { 125 DE_ASSERT(isArray()); 126 return elementNdx * getElementType().getScalarSize(); 127 } 128 getScalarType(Type baseType)129const VariableType &VariableType::getScalarType(Type baseType) 130 { 131 switch (baseType) 132 { 133 case TYPE_FLOAT: 134 { 135 static const VariableType s_floatTypes[] = { 136 VariableType(TYPE_FLOAT, 1) 137 // \todo [pyry] Extend with different precision variants? 138 }; 139 return s_floatTypes[0]; 140 } 141 142 case TYPE_INT: 143 { 144 static const VariableType s_intTypes[] = {VariableType(TYPE_INT, 1)}; 145 return s_intTypes[0]; 146 } 147 148 case TYPE_BOOL: 149 { 150 static const VariableType s_boolTypes[] = {VariableType(TYPE_BOOL, 1)}; 151 return s_boolTypes[0]; 152 } 153 154 case TYPE_SAMPLER_2D: 155 { 156 static const VariableType sampler2DType = VariableType(TYPE_SAMPLER_2D, 1); 157 return sampler2DType; 158 } 159 160 case TYPE_SAMPLER_CUBE: 161 { 162 static const VariableType samplerCubeType = VariableType(TYPE_SAMPLER_CUBE, 1); 163 return samplerCubeType; 164 } 165 166 default: 167 DE_ASSERT(false); 168 throw Exception("VariableType::getScalarType(): unsupported type"); 169 } 170 } 171 getElementType(void) const172const VariableType &VariableType::getElementType(void) const 173 { 174 DE_ASSERT(m_precision == PRECISION_NONE); // \todo [pyry] Precision 175 switch (m_baseType) 176 { 177 case TYPE_FLOAT: 178 case TYPE_INT: 179 case TYPE_BOOL: 180 case TYPE_SAMPLER_2D: 181 case TYPE_SAMPLER_CUBE: 182 return getScalarType(m_baseType); 183 184 case TYPE_ARRAY: 185 { 186 DE_ASSERT(m_elementType); 187 return *m_elementType; 188 } 189 190 default: 191 DE_ASSERT(false); 192 throw Exception("VariableType::getElementType(): unsupported type"); 193 } 194 } 195 tokenizeShortType(TokenStream & str) const196void VariableType::tokenizeShortType(TokenStream &str) const 197 { 198 switch (m_precision) 199 { 200 case PRECISION_LOW: 201 str << Token::LOW_PRECISION; 202 break; 203 case PRECISION_MEDIUM: 204 str << Token::MEDIUM_PRECISION; 205 break; 206 case PRECISION_HIGH: 207 str << Token::HIGH_PRECISION; 208 break; 209 default: /* nothing */ 210 break; 211 } 212 213 switch (m_baseType) 214 { 215 case TYPE_VOID: 216 str << Token::VOID; 217 break; 218 219 case TYPE_FLOAT: 220 switch (m_numElements) 221 { 222 case 1: 223 str << Token::FLOAT; 224 break; 225 case 2: 226 str << Token::VEC2; 227 break; 228 case 3: 229 str << Token::VEC3; 230 break; 231 case 4: 232 str << Token::VEC4; 233 break; 234 default: 235 DE_ASSERT(false); 236 break; 237 } 238 break; 239 240 case TYPE_INT: 241 switch (m_numElements) 242 { 243 case 1: 244 str << Token::INT; 245 break; 246 case 2: 247 str << Token::IVEC2; 248 break; 249 case 3: 250 str << Token::IVEC3; 251 break; 252 case 4: 253 str << Token::IVEC4; 254 break; 255 default: 256 DE_ASSERT(false); 257 break; 258 } 259 break; 260 261 case TYPE_BOOL: 262 switch (m_numElements) 263 { 264 case 1: 265 str << Token::BOOL; 266 break; 267 case 2: 268 str << Token::BVEC2; 269 break; 270 case 3: 271 str << Token::BVEC3; 272 break; 273 case 4: 274 str << Token::BVEC4; 275 break; 276 default: 277 DE_ASSERT(false); 278 break; 279 } 280 break; 281 282 case TYPE_SAMPLER_2D: 283 str << Token::SAMPLER2D; 284 break; 285 case TYPE_SAMPLER_CUBE: 286 str << Token::SAMPLERCUBE; 287 break; 288 289 case TYPE_STRUCT: 290 DE_ASSERT(m_typeName != ""); 291 str << Token(m_typeName.c_str()); 292 break; 293 294 case TYPE_ARRAY: 295 DE_ASSERT(m_elementType); 296 m_elementType->tokenizeShortType(str); 297 str << Token::LEFT_BRACKET << Token(m_numElements) << Token::RIGHT_BRACKET; 298 break; 299 300 default: 301 DE_ASSERT(false); 302 break; 303 } 304 } 305 306 } // namespace rsg 307