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