1 #ifndef _RSGVARIABLEVALUE_HPP 2 #define _RSGVARIABLEVALUE_HPP 3 /*------------------------------------------------------------------------- 4 * drawElements Quality Program Random Shader Generator 5 * ---------------------------------------------------- 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Variable Value class. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "rsgDefs.hpp" 27 #include "rsgVariableType.hpp" 28 #include "rsgVariable.hpp" 29 #include "tcuVector.hpp" 30 31 #include <algorithm> 32 33 namespace rsg 34 { 35 36 union Scalar 37 { 38 int intVal; 39 float floatVal; 40 bool boolVal; 41 42 Scalar (void) : intVal (0) {} 43 Scalar (float v) : floatVal (v) {} 44 Scalar (int v) : intVal (v) {} 45 Scalar (bool v) : boolVal (v) {} 46 47 // Bit-exact compare 48 bool operator== (Scalar other) const { return intVal == other.intVal; } 49 bool operator!= (Scalar other) const { return intVal != other.intVal; } 50 51 template <typename T> static Scalar min (void); 52 template <typename T> static Scalar max (void); 53 54 template <typename T> T as (void) const; 55 template <typename T> T& as (void); 56 }; 57 DE_STATIC_ASSERT(sizeof(Scalar) == sizeof(deUint32)); 58 59 template <> inline Scalar Scalar::min<float> (void) { return Scalar((int)0xff800000); } 60 template <> inline Scalar Scalar::max<float> (void) { return Scalar((int)0x7f800000); } 61 template <> inline Scalar Scalar::min<int> (void) { return Scalar((int)0x80000000); } 62 template <> inline Scalar Scalar::max<int> (void) { return Scalar((int)0x7fffffff); } 63 template <> inline Scalar Scalar::min<bool> (void) { return Scalar(false); } 64 template <> inline Scalar Scalar::max<bool> (void) { return Scalar(true); } 65 66 template <> inline float Scalar::as<float> (void) const { return floatVal; } 67 template <> inline float& Scalar::as<float> (void) { return floatVal; } 68 template <> inline int Scalar::as<int> (void) const { return intVal; } 69 template <> inline int& Scalar::as<int> (void) { return intVal; } 70 template <> inline bool Scalar::as<bool> (void) const { return boolVal; } 71 template <> inline bool& Scalar::as<bool> (void) { return boolVal; } 72 73 template <int Stride> 74 class StridedValueRead 75 { 76 public: 77 StridedValueRead (const VariableType& type, const Scalar* value) : m_type(type), m_value(value) {} 78 79 const VariableType& getType (void) const { return m_type; } 80 const Scalar* getValuePtr (void) const { return m_value; } 81 82 private: 83 const VariableType& m_type; 84 const Scalar* m_value; 85 }; 86 87 template <int Stride> 88 class ConstStridedValueAccess 89 { 90 public: 91 ConstStridedValueAccess (void) : m_type(DE_NULL), m_value(DE_NULL) {} 92 ConstStridedValueAccess (const VariableType& type, const Scalar* valuePtr) : m_type(&type), m_value(const_cast<Scalar*>(valuePtr)) {} 93 94 const VariableType& getType (void) const { return *m_type; } 95 96 // Read-only access 97 ConstStridedValueAccess component (int compNdx) const { return ConstStridedValueAccess(getType().getElementType(), m_value + Stride*compNdx); } 98 ConstStridedValueAccess arrayElement (int elementNdx) const { return ConstStridedValueAccess(getType().getElementType(), m_value + Stride*getType().getElementScalarOffset(elementNdx)); } 99 ConstStridedValueAccess member (int memberNdx) const { return ConstStridedValueAccess(getType().getMembers()[memberNdx].getType(), m_value + Stride*getType().getMemberScalarOffset(memberNdx)); } 100 101 float asFloat (void) const { DE_STATIC_ASSERT(Stride == 1); return m_value->floatVal; } 102 int asInt (void) const { DE_STATIC_ASSERT(Stride == 1); return m_value->intVal; } 103 bool asBool (void) const { DE_STATIC_ASSERT(Stride == 1); return m_value->boolVal; } 104 Scalar asScalar (void) const { DE_STATIC_ASSERT(Stride == 1); return *m_value; } 105 106 float asFloat (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx].floatVal; } 107 int asInt (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx].intVal; } 108 bool asBool (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx].boolVal; } 109 Scalar asScalar (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx]; } 110 111 template <typename T> 112 T as (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].template as<T>(); } 113 114 // For assignment: b = a.value() 115 StridedValueRead<Stride> value (void) const { return StridedValueRead<Stride>(getType(), m_value); } 116 117 protected: 118 const VariableType* m_type; 119 Scalar* m_value; // \note Non-const internal pointer is used so that ValueAccess can extend this class with RW access 120 }; 121 122 template <int Stride> 123 class StridedValueAccess : public ConstStridedValueAccess<Stride> 124 { 125 public: 126 StridedValueAccess (void) {} 127 StridedValueAccess (const VariableType& type, Scalar* valuePtr) : ConstStridedValueAccess<Stride>(type, valuePtr) {} 128 129 // Read-write access 130 StridedValueAccess component (int compNdx) { return StridedValueAccess(this->getType().getElementType(), this->m_value + Stride*compNdx); } 131 StridedValueAccess arrayElement (int elementNdx) { return StridedValueAccess(this->getType().getElementType(), this->m_value + Stride*this->getType().getElementScalarOffset(elementNdx)); } 132 StridedValueAccess member (int memberNdx) { return StridedValueAccess(this->getType().getMembers()[memberNdx].getType(), this->m_value + Stride*this->getType().getMemberScalarOffset(memberNdx)); } 133 134 float& asFloat (void) { DE_STATIC_ASSERT(Stride == 1); return this->m_value->floatVal; } 135 int& asInt (void) { DE_STATIC_ASSERT(Stride == 1); return this->m_value->intVal; } 136 bool& asBool (void) { DE_STATIC_ASSERT(Stride == 1); return this->m_value->boolVal; } 137 Scalar& asScalar (void) { DE_STATIC_ASSERT(Stride == 1); return *this->m_value; } 138 139 float& asFloat (int ndx) { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].floatVal; } 140 int& asInt (int ndx) { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].intVal; } 141 bool& asBool (int ndx) { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].boolVal; } 142 Scalar& asScalar (int ndx) { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx]; } 143 144 template <typename T> 145 T& as (int ndx) { DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].template as<T>(); } 146 147 template <int SrcStride> 148 StridedValueAccess& operator= (const StridedValueRead<SrcStride>& value); 149 150 // Helpers, work only in Stride == 1 case 151 template <int Size> 152 StridedValueAccess& operator= (const tcu::Vector<float, Size>& vec); 153 StridedValueAccess& operator= (float floatVal) { asFloat() = floatVal; return *this; } 154 StridedValueAccess& operator= (int intVal) { asInt() = intVal; return *this; } 155 StridedValueAccess& operator= (bool boolVal) { asBool() = boolVal; return *this; } 156 StridedValueAccess& operator= (Scalar val) { asScalar() = val; return *this; } 157 }; 158 159 template <int Stride> 160 template <int SrcStride> 161 StridedValueAccess<Stride>& StridedValueAccess<Stride>::operator= (const StridedValueRead<SrcStride>& valueRead) 162 { 163 DE_STATIC_ASSERT(SrcStride == Stride || SrcStride == 1); 164 DE_ASSERT(this->getType() == valueRead.getType()); 165 166 int scalarSize = this->getType().getScalarSize(); 167 168 if (scalarSize == 0) 169 return *this; // Happens when void value range is copied 170 171 if (Stride == SrcStride) 172 std::copy(valueRead.getValuePtr(), valueRead.getValuePtr() + scalarSize*Stride, this->m_value); 173 else 174 { 175 for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 176 std::fill(this->m_value + scalarNdx*Stride, this->m_value + (scalarNdx+1)*Stride, valueRead.getValuePtr()[scalarNdx]); 177 } 178 179 return *this; 180 } 181 182 template <int Stride> 183 template <int Size> 184 StridedValueAccess<Stride>& StridedValueAccess<Stride>::operator= (const tcu::Vector<float, Size>& vec) 185 { 186 DE_ASSERT(this->getType() == VariableType(VariableType::TYPE_FLOAT, Size)); 187 for (int comp = 0; comp < 4; comp++) 188 component(comp).asFloat() = vec.getPtr()[comp]; 189 190 return *this; 191 } 192 193 // Typedefs for stride == 1 case 194 typedef ConstStridedValueAccess<1> ConstValueAccess; 195 typedef StridedValueAccess<1> ValueAccess; 196 197 class ConstValueRangeAccess 198 { 199 public: 200 ConstValueRangeAccess (void) : m_type(DE_NULL), m_min(DE_NULL), m_max(DE_NULL) {} 201 ConstValueRangeAccess (const VariableType& type, const Scalar* minVal, const Scalar* maxVal) : m_type(&type), m_min(const_cast<Scalar*>(minVal)), m_max(const_cast<Scalar*>(maxVal)) {} 202 203 const VariableType& getType (void) const { return *m_type; } 204 ConstValueAccess getMin (void) const { return ConstValueAccess(*m_type, m_min); } 205 ConstValueAccess getMax (void) const { return ConstValueAccess(*m_type, m_max); } 206 207 // Read-only access 208 ConstValueRangeAccess component (int compNdx) const; 209 ConstValueRangeAccess arrayElement (int elementNdx) const; 210 ConstValueRangeAccess member (int memberNdx) const; 211 212 // Set operations - tests condition for all elements 213 bool intersects (const ConstValueRangeAccess& other) const; 214 bool isSupersetOf (const ConstValueRangeAccess& other) const; 215 bool isSubsetOf (const ConstValueRangeAccess& other) const; 216 217 protected: 218 const VariableType* m_type; 219 Scalar* m_min; // \note See note in ConstValueAccess 220 Scalar* m_max; 221 }; 222 223 inline ConstValueRangeAccess ConstValueRangeAccess::component (int compNdx) const 224 { 225 return ConstValueRangeAccess(m_type->getElementType(), m_min + compNdx, m_max + compNdx); 226 } 227 228 inline ConstValueRangeAccess ConstValueRangeAccess::arrayElement (int elementNdx) const 229 { 230 int offset = m_type->getElementScalarOffset(elementNdx); 231 return ConstValueRangeAccess(m_type->getElementType(), m_min + offset, m_max + offset); 232 } 233 234 inline ConstValueRangeAccess ConstValueRangeAccess::member (int memberNdx) const 235 { 236 int offset = m_type->getMemberScalarOffset(memberNdx); 237 return ConstValueRangeAccess(m_type->getMembers()[memberNdx].getType(), m_min + offset, m_max + offset); 238 } 239 240 class ValueRangeAccess : public ConstValueRangeAccess 241 { 242 public: 243 ValueRangeAccess (const VariableType& type, Scalar* minVal, Scalar* maxVal) : ConstValueRangeAccess(type, minVal, maxVal) {} 244 245 // Read-write access 246 ValueAccess getMin (void) { return ValueAccess(*m_type, m_min); } 247 ValueAccess getMax (void) { return ValueAccess(*m_type, m_max); } 248 249 ValueRangeAccess component (int compNdx); 250 ValueRangeAccess arrayElement (int elementNdx); 251 ValueRangeAccess member (int memberNdx); 252 }; 253 254 inline ValueRangeAccess ValueRangeAccess::component (int compNdx) 255 { 256 return ValueRangeAccess(m_type->getElementType(), m_min + compNdx, m_max + compNdx); 257 } 258 259 inline ValueRangeAccess ValueRangeAccess::arrayElement (int elementNdx) 260 { 261 int offset = m_type->getElementScalarOffset(elementNdx); 262 return ValueRangeAccess(m_type->getElementType(), m_min + offset, m_max + offset); 263 } 264 265 inline ValueRangeAccess ValueRangeAccess::member (int memberNdx) 266 { 267 int offset = m_type->getMemberScalarOffset(memberNdx); 268 return ValueRangeAccess(m_type->getMembers()[memberNdx].getType(), m_min + offset, m_max + offset); 269 } 270 271 class ValueRange 272 { 273 public: 274 ValueRange (const VariableType& type); 275 ValueRange (const VariableType& type, const ConstValueAccess& minVal, const ConstValueAccess& maxVal); 276 ValueRange (const VariableType& type, const Scalar* minVal, const Scalar* maxVal); 277 ValueRange (ConstValueRangeAccess other); 278 ~ValueRange (void); 279 280 const VariableType& getType (void) const { return m_type; } 281 282 ValueAccess getMin (void) { return ValueAccess(m_type, getMinPtr()); } 283 ValueAccess getMax (void) { return ValueAccess(m_type, getMaxPtr()); } 284 285 ConstValueAccess getMin (void) const { return ConstValueAccess(m_type, getMinPtr()); } 286 ConstValueAccess getMax (void) const { return ConstValueAccess(m_type, getMaxPtr()); } 287 288 ValueRangeAccess asAccess (void) { return ValueRangeAccess(m_type, getMinPtr(), getMaxPtr()); } 289 ConstValueRangeAccess asAccess (void) const { return ConstValueRangeAccess(m_type, getMinPtr(), getMaxPtr()); } 290 291 operator ConstValueRangeAccess (void) const { return asAccess(); } 292 operator ValueRangeAccess (void) { return asAccess(); } 293 294 static void computeIntersection (ValueRangeAccess dst, const ConstValueRangeAccess& a, const ConstValueRangeAccess& b); 295 static void computeIntersection (ValueRange& dst, const ConstValueRangeAccess& a, const ConstValueRangeAccess& b); 296 297 private: 298 const Scalar* getMinPtr (void) const { return m_min.empty() ? DE_NULL : &m_min[0]; } 299 const Scalar* getMaxPtr (void) const { return m_max.empty() ? DE_NULL : &m_max[0]; } 300 301 Scalar* getMinPtr (void) { return m_min.empty() ? DE_NULL : &m_min[0]; } 302 Scalar* getMaxPtr (void) { return m_max.empty() ? DE_NULL : &m_max[0]; } 303 304 VariableType m_type; 305 std::vector<Scalar> m_min; 306 std::vector<Scalar> m_max; 307 }; 308 309 template <int Stride> 310 class ValueStorage 311 { 312 public: 313 ValueStorage (void); 314 ValueStorage (const VariableType& type); 315 316 void setStorage (const VariableType& type); 317 318 StridedValueAccess<Stride> getValue (const VariableType& type) { return StridedValueAccess<Stride>(type, &m_value[0]); } 319 ConstStridedValueAccess<Stride> getValue (const VariableType& type) const { return ConstStridedValueAccess<Stride>(type, &m_value[0]); } 320 321 private: 322 ValueStorage (const ValueStorage& other); 323 ValueStorage operator= (const ValueStorage& other); 324 325 std::vector<Scalar> m_value; 326 }; 327 328 template <int Stride> 329 ValueStorage<Stride>::ValueStorage (void) 330 { 331 } 332 333 template <int Stride> 334 ValueStorage<Stride>::ValueStorage (const VariableType& type) 335 { 336 setStorage(type); 337 } 338 339 template <int Stride> 340 void ValueStorage<Stride>::setStorage (const VariableType& type) 341 { 342 m_value.resize(type.getScalarSize() * Stride); 343 } 344 345 class VariableValue 346 { 347 public: 348 VariableValue (const Variable* variable) : m_variable(variable), m_storage(m_variable->getType()) {} 349 ~VariableValue (void) {} 350 351 const Variable* getVariable (void) const { return m_variable; } 352 ValueAccess getValue (void) { return m_storage.getValue(m_variable->getType()); } 353 ConstValueAccess getValue (void) const { return m_storage.getValue(m_variable->getType()); } 354 355 VariableValue (const VariableValue& other); 356 VariableValue& operator= (const VariableValue& other); 357 358 private: 359 const VariableType& getType (void) const { return m_variable->getType(); } 360 361 const Variable* m_variable; 362 ValueStorage<1> m_storage; 363 }; 364 365 } // rsg 366 367 #endif // _RSGVARIABLEVALUE_HPP 368