1 // 2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 //Copyright (C) 2013 LunarG, Inc. 4 // 5 //All rights reserved. 6 // 7 //Redistribution and use in source and binary forms, with or without 8 //modification, are permitted provided that the following conditions 9 //are met: 10 // 11 // Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // 14 // Redistributions in binary form must reproduce the above 15 // copyright notice, this list of conditions and the following 16 // disclaimer in the documentation and/or other materials provided 17 // with the distribution. 18 // 19 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 20 // contributors may be used to endorse or promote products derived 21 // from this software without specific prior written permission. 22 // 23 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 //POSSIBILITY OF SUCH DAMAGE. 35 // 36 37 #ifndef _CONSTANT_UNION_INCLUDED_ 38 #define _CONSTANT_UNION_INCLUDED_ 39 40 namespace glslang { 41 42 class TConstUnion { 43 public: 44 POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) 45 46 TConstUnion() : iConst(0), type(EbtInt) { } 47 48 void setIConst(int i) 49 { 50 iConst = i; 51 type = EbtInt; 52 } 53 54 void setUConst(unsigned int u) 55 { 56 uConst = u; 57 type = EbtUint; 58 } 59 60 void setI64Const(long long i64) 61 { 62 i64Const = i64; 63 type = EbtInt64; 64 } 65 66 void setU64Const(unsigned long long u64) 67 { 68 u64Const = u64; 69 type = EbtUint64; 70 } 71 72 void setDConst(double d) 73 { 74 dConst = d; 75 type = EbtDouble; 76 } 77 78 void setBConst(bool b) 79 { 80 bConst = b; 81 type = EbtBool; 82 } 83 84 int getIConst() const { return iConst; } 85 unsigned int getUConst() const { return uConst; } 86 long long getI64Const() const { return i64Const; } 87 unsigned long long getU64Const() const { return u64Const; } 88 double getDConst() const { return dConst; } 89 bool getBConst() const { return bConst; } 90 91 bool operator==(const int i) const 92 { 93 if (i == iConst) 94 return true; 95 96 return false; 97 } 98 99 bool operator==(const unsigned int u) const 100 { 101 if (u == uConst) 102 return true; 103 104 return false; 105 } 106 107 bool operator==(const long long i64) const 108 { 109 if (i64 == i64Const) 110 return true; 111 112 return false; 113 } 114 115 bool operator==(const unsigned long long u64) const 116 { 117 if (u64 == u64Const) 118 return true; 119 120 return false; 121 } 122 123 bool operator==(const double d) const 124 { 125 if (d == dConst) 126 return true; 127 128 return false; 129 } 130 131 bool operator==(const bool b) const 132 { 133 if (b == bConst) 134 return true; 135 136 return false; 137 } 138 139 bool operator==(const TConstUnion& constant) const 140 { 141 if (constant.type != type) 142 return false; 143 144 switch (type) { 145 case EbtInt: 146 if (constant.iConst == iConst) 147 return true; 148 149 break; 150 case EbtUint: 151 if (constant.uConst == uConst) 152 return true; 153 154 break; 155 case EbtInt64: 156 if (constant.i64Const == i64Const) 157 return true; 158 159 break; 160 case EbtUint64: 161 if (constant.u64Const == u64Const) 162 return true; 163 164 break; 165 case EbtDouble: 166 if (constant.dConst == dConst) 167 return true; 168 169 break; 170 case EbtBool: 171 if (constant.bConst == bConst) 172 return true; 173 174 break; 175 default: 176 assert(false && "Default missing"); 177 } 178 179 return false; 180 } 181 182 bool operator!=(const int i) const 183 { 184 return !operator==(i); 185 } 186 187 bool operator!=(const unsigned int u) const 188 { 189 return !operator==(u); 190 } 191 192 bool operator!=(const long long i) const 193 { 194 return !operator==(i); 195 } 196 197 bool operator!=(const unsigned long long u) const 198 { 199 return !operator==(u); 200 } 201 202 bool operator!=(const float f) const 203 { 204 return !operator==(f); 205 } 206 207 bool operator!=(const bool b) const 208 { 209 return !operator==(b); 210 } 211 212 bool operator!=(const TConstUnion& constant) const 213 { 214 return !operator==(constant); 215 } 216 217 bool operator>(const TConstUnion& constant) const 218 { 219 assert(type == constant.type); 220 switch (type) { 221 case EbtInt: 222 if (iConst > constant.iConst) 223 return true; 224 225 return false; 226 case EbtUint: 227 if (uConst > constant.uConst) 228 return true; 229 230 return false; 231 case EbtInt64: 232 if (i64Const > constant.i64Const) 233 return true; 234 235 return false; 236 case EbtUint64: 237 if (u64Const > constant.u64Const) 238 return true; 239 240 return false; 241 case EbtDouble: 242 if (dConst > constant.dConst) 243 return true; 244 245 return false; 246 default: 247 assert(false && "Default missing"); 248 return false; 249 } 250 } 251 252 bool operator<(const TConstUnion& constant) const 253 { 254 assert(type == constant.type); 255 switch (type) { 256 case EbtInt: 257 if (iConst < constant.iConst) 258 return true; 259 260 return false; 261 case EbtUint: 262 if (uConst < constant.uConst) 263 return true; 264 265 return false; 266 case EbtInt64: 267 if (i64Const < constant.i64Const) 268 return true; 269 270 return false; 271 case EbtUint64: 272 if (u64Const < constant.u64Const) 273 return true; 274 275 return false; 276 case EbtDouble: 277 if (dConst < constant.dConst) 278 return true; 279 280 return false; 281 default: 282 assert(false && "Default missing"); 283 return false; 284 } 285 } 286 287 TConstUnion operator+(const TConstUnion& constant) const 288 { 289 TConstUnion returnValue; 290 assert(type == constant.type); 291 switch (type) { 292 case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; 293 case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; 294 case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; 295 case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break; 296 case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; 297 default: assert(false && "Default missing"); 298 } 299 300 return returnValue; 301 } 302 303 TConstUnion operator-(const TConstUnion& constant) const 304 { 305 TConstUnion returnValue; 306 assert(type == constant.type); 307 switch (type) { 308 case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; 309 case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; 310 case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; 311 case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break; 312 case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; 313 default: assert(false && "Default missing"); 314 } 315 316 return returnValue; 317 } 318 319 TConstUnion operator*(const TConstUnion& constant) const 320 { 321 TConstUnion returnValue; 322 assert(type == constant.type); 323 switch (type) { 324 case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; 325 case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; 326 case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; 327 case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break; 328 case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; 329 default: assert(false && "Default missing"); 330 } 331 332 return returnValue; 333 } 334 335 TConstUnion operator%(const TConstUnion& constant) const 336 { 337 TConstUnion returnValue; 338 assert(type == constant.type); 339 switch (type) { 340 case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; 341 case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; 342 case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; 343 case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break; 344 default: assert(false && "Default missing"); 345 } 346 347 return returnValue; 348 } 349 350 TConstUnion operator>>(const TConstUnion& constant) const 351 { 352 TConstUnion returnValue; 353 switch (type) { 354 case EbtInt: 355 switch (constant.type) { 356 case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; 357 case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break; 358 case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break; 359 case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break; 360 default: assert(false && "Default missing"); 361 } 362 break; 363 case EbtUint: 364 switch (constant.type) { 365 case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break; 366 case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break; 367 case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break; 368 case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break; 369 default: assert(false && "Default missing"); 370 } 371 break; 372 case EbtInt64: 373 switch (constant.type) { 374 case EbtInt: returnValue.setI64Const(i64Const >> constant.iConst); break; 375 case EbtUint: returnValue.setI64Const(i64Const >> constant.uConst); break; 376 case EbtInt64: returnValue.setI64Const(i64Const >> constant.i64Const); break; 377 case EbtUint64: returnValue.setI64Const(i64Const >> constant.u64Const); break; 378 default: assert(false && "Default missing"); 379 } 380 break; 381 case EbtUint64: 382 switch (constant.type) { 383 case EbtInt: returnValue.setU64Const(u64Const >> constant.iConst); break; 384 case EbtUint: returnValue.setU64Const(u64Const >> constant.uConst); break; 385 case EbtInt64: returnValue.setU64Const(u64Const >> constant.i64Const); break; 386 case EbtUint64: returnValue.setU64Const(u64Const >> constant.u64Const); break; 387 default: assert(false && "Default missing"); 388 } 389 break; 390 default: assert(false && "Default missing"); 391 } 392 393 return returnValue; 394 } 395 396 TConstUnion operator<<(const TConstUnion& constant) const 397 { 398 TConstUnion returnValue; 399 switch (type) { 400 case EbtInt: 401 switch (constant.type) { 402 case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; 403 case EbtUint: returnValue.setIConst(iConst << constant.uConst); break; 404 case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break; 405 case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break; 406 default: assert(false && "Default missing"); 407 } 408 break; 409 case EbtUint: 410 switch (constant.type) { 411 case EbtInt: returnValue.setUConst(uConst << constant.iConst); break; 412 case EbtUint: returnValue.setUConst(uConst << constant.uConst); break; 413 case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break; 414 case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break; 415 default: assert(false && "Default missing"); 416 } 417 break; 418 case EbtInt64: 419 switch (constant.type) { 420 case EbtInt: returnValue.setI64Const(i64Const << constant.iConst); break; 421 case EbtUint: returnValue.setI64Const(i64Const << constant.uConst); break; 422 case EbtInt64: returnValue.setI64Const(i64Const << constant.i64Const); break; 423 case EbtUint64: returnValue.setI64Const(i64Const << constant.u64Const); break; 424 default: assert(false && "Default missing"); 425 } 426 break; 427 case EbtUint64: 428 switch (constant.type) { 429 case EbtInt: returnValue.setU64Const(u64Const << constant.iConst); break; 430 case EbtUint: returnValue.setU64Const(u64Const << constant.uConst); break; 431 case EbtInt64: returnValue.setU64Const(u64Const << constant.i64Const); break; 432 case EbtUint64: returnValue.setU64Const(u64Const << constant.u64Const); break; 433 default: assert(false && "Default missing"); 434 } 435 break; 436 default: assert(false && "Default missing"); 437 } 438 439 return returnValue; 440 } 441 442 TConstUnion operator&(const TConstUnion& constant) const 443 { 444 TConstUnion returnValue; 445 assert(type == constant.type); 446 switch (type) { 447 case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; 448 case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; 449 case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break; 450 case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break; 451 default: assert(false && "Default missing"); 452 } 453 454 return returnValue; 455 } 456 457 TConstUnion operator|(const TConstUnion& constant) const 458 { 459 TConstUnion returnValue; 460 assert(type == constant.type); 461 switch (type) { 462 case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; 463 case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; 464 case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break; 465 case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break; 466 default: assert(false && "Default missing"); 467 } 468 469 return returnValue; 470 } 471 472 TConstUnion operator^(const TConstUnion& constant) const 473 { 474 TConstUnion returnValue; 475 assert(type == constant.type); 476 switch (type) { 477 case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; 478 case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; 479 case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break; 480 case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break; 481 default: assert(false && "Default missing"); 482 } 483 484 return returnValue; 485 } 486 487 TConstUnion operator~() const 488 { 489 TConstUnion returnValue; 490 switch (type) { 491 case EbtInt: returnValue.setIConst(~iConst); break; 492 case EbtUint: returnValue.setUConst(~uConst); break; 493 case EbtInt64: returnValue.setI64Const(~i64Const); break; 494 case EbtUint64: returnValue.setU64Const(~u64Const); break; 495 default: assert(false && "Default missing"); 496 } 497 498 return returnValue; 499 } 500 501 TConstUnion operator&&(const TConstUnion& constant) const 502 { 503 TConstUnion returnValue; 504 assert(type == constant.type); 505 switch (type) { 506 case EbtBool: returnValue.setBConst(bConst && constant.bConst); break; 507 default: assert(false && "Default missing"); 508 } 509 510 return returnValue; 511 } 512 513 TConstUnion operator||(const TConstUnion& constant) const 514 { 515 TConstUnion returnValue; 516 assert(type == constant.type); 517 switch (type) { 518 case EbtBool: returnValue.setBConst(bConst || constant.bConst); break; 519 default: assert(false && "Default missing"); 520 } 521 522 return returnValue; 523 } 524 525 TBasicType getType() const { return type; } 526 527 private: 528 union { 529 int iConst; // used for ivec, scalar ints 530 unsigned int uConst; // used for uvec, scalar uints 531 long long i64Const; // used for i64vec, scalar int64s 532 unsigned long long u64Const; // used for u64vec, scalar uint64s 533 bool bConst; // used for bvec, scalar bools 534 double dConst; // used for vec, dvec, mat, dmat, scalar floats and doubles 535 }; 536 537 TBasicType type; 538 }; 539 540 // Encapsulate having a pointer to an array of TConstUnion, 541 // which only needs to be allocated if it's size is going to be 542 // bigger than 0. 543 // 544 // One convenience is being able to use [] to go inside the array, instead 545 // of C++ assuming it as an array of pointers to vectors. 546 // 547 // General usage is that the size is known up front, and it is 548 // created once with the proper size. 549 // 550 class TConstUnionArray { 551 public: 552 POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) 553 554 TConstUnionArray() : unionArray(nullptr) { } 555 virtual ~TConstUnionArray() { } 556 557 explicit TConstUnionArray(int size) 558 { 559 if (size == 0) 560 unionArray = nullptr; 561 else 562 unionArray = new TConstUnionVector(size); 563 } 564 TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { } 565 TConstUnionArray(const TConstUnionArray& a, int start, int size) 566 { 567 unionArray = new TConstUnionVector(size); 568 for (int i = 0; i < size; ++i) 569 (*unionArray)[i] = a[start + i]; 570 } 571 572 // Use this constructor for a smear operation 573 TConstUnionArray(int size, const TConstUnion& val) 574 { 575 unionArray = new TConstUnionVector(size, val); 576 } 577 578 int size() const { return unionArray ? (int)unionArray->size() : 0; } 579 TConstUnion& operator[](size_t index) { return (*unionArray)[index]; } 580 const TConstUnion& operator[](size_t index) const { return (*unionArray)[index]; } 581 bool operator==(const TConstUnionArray& rhs) const 582 { 583 // this includes the case that both are unallocated 584 if (unionArray == rhs.unionArray) 585 return true; 586 587 if (! unionArray || ! rhs.unionArray) 588 return false; 589 590 if (! unionArray || ! rhs.unionArray) 591 return false; 592 593 return *unionArray == *rhs.unionArray; 594 } 595 bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); } 596 597 double dot(const TConstUnionArray& rhs) 598 { 599 assert(rhs.unionArray->size() == unionArray->size()); 600 double sum = 0.0; 601 602 for (size_t comp = 0; comp < unionArray->size(); ++comp) 603 sum += (*this)[comp].getDConst() * rhs[comp].getDConst(); 604 605 return sum; 606 } 607 608 bool empty() const { return unionArray == nullptr; } 609 610 protected: 611 typedef TVector<TConstUnion> TConstUnionVector; 612 TConstUnionVector* unionArray; 613 }; 614 615 } // end namespace glslang 616 617 #endif // _CONSTANT_UNION_INCLUDED_ 618