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