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     void setSConst(const TString* s)
     85     {
     86         sConst = s;
     87         type = EbtString;
     88     }
     89 
     90     int                getIConst() const   { return iConst; }
     91     unsigned int       getUConst() const   { return uConst; }
     92     long long          getI64Const() const { return i64Const; }
     93     unsigned long long getU64Const() const { return u64Const; }
     94     double             getDConst() const   { return dConst; }
     95     bool               getBConst() const   { return bConst; }
     96     const TString*     getSConst() const   { return sConst; }
     97 
     98     bool operator==(const int i) const
     99     {
    100         if (i == iConst)
    101             return true;
    102 
    103         return false;
    104     }
    105 
    106     bool operator==(const unsigned int u) const
    107     {
    108         if (u == uConst)
    109             return true;
    110 
    111         return false;
    112     }
    113 
    114     bool operator==(const long long i64) const
    115     {
    116         if (i64 == i64Const)
    117             return true;
    118 
    119         return false;
    120     }
    121 
    122     bool operator==(const unsigned long long u64) const
    123     {
    124         if (u64 == u64Const)
    125             return true;
    126 
    127         return false;
    128     }
    129 
    130     bool operator==(const double d) const
    131     {
    132         if (d == dConst)
    133             return true;
    134 
    135         return false;
    136     }
    137 
    138     bool operator==(const bool b) const
    139     {
    140         if (b == bConst)
    141             return true;
    142 
    143         return false;
    144     }
    145 
    146     bool operator==(const TConstUnion& constant) const
    147     {
    148         if (constant.type != type)
    149             return false;
    150 
    151         switch (type) {
    152         case EbtInt:
    153             if (constant.iConst == iConst)
    154                 return true;
    155 
    156             break;
    157         case EbtUint:
    158             if (constant.uConst == uConst)
    159                 return true;
    160 
    161             break;
    162         case EbtInt64:
    163             if (constant.i64Const == i64Const)
    164                 return true;
    165 
    166             break;
    167         case EbtUint64:
    168             if (constant.u64Const == u64Const)
    169                 return true;
    170 
    171             break;
    172         case EbtDouble:
    173             if (constant.dConst == dConst)
    174                 return true;
    175 
    176             break;
    177         case EbtBool:
    178             if (constant.bConst == bConst)
    179                 return true;
    180 
    181             break;
    182         default:
    183             assert(false && "Default missing");
    184         }
    185 
    186         return false;
    187     }
    188 
    189     bool operator!=(const int i) const
    190     {
    191         return !operator==(i);
    192     }
    193 
    194     bool operator!=(const unsigned int u) const
    195     {
    196         return !operator==(u);
    197     }
    198 
    199     bool operator!=(const long long i) const
    200     {
    201         return !operator==(i);
    202     }
    203 
    204     bool operator!=(const unsigned long long u) const
    205     {
    206         return !operator==(u);
    207     }
    208 
    209     bool operator!=(const float f) const
    210     {
    211         return !operator==(f);
    212     }
    213 
    214     bool operator!=(const bool b) const
    215     {
    216         return !operator==(b);
    217     }
    218 
    219     bool operator!=(const TConstUnion& constant) const
    220     {
    221         return !operator==(constant);
    222     }
    223 
    224     bool operator>(const TConstUnion& constant) const
    225     {
    226         assert(type == constant.type);
    227         switch (type) {
    228         case EbtInt:
    229             if (iConst > constant.iConst)
    230                 return true;
    231 
    232             return false;
    233         case EbtUint:
    234             if (uConst > constant.uConst)
    235                 return true;
    236 
    237             return false;
    238         case EbtInt64:
    239             if (i64Const > constant.i64Const)
    240                 return true;
    241 
    242             return false;
    243         case EbtUint64:
    244             if (u64Const > constant.u64Const)
    245                 return true;
    246 
    247             return false;
    248         case EbtDouble:
    249             if (dConst > constant.dConst)
    250                 return true;
    251 
    252             return false;
    253         default:
    254             assert(false && "Default missing");
    255             return false;
    256         }
    257     }
    258 
    259     bool operator<(const TConstUnion& constant) const
    260     {
    261         assert(type == constant.type);
    262         switch (type) {
    263         case EbtInt:
    264             if (iConst < constant.iConst)
    265                 return true;
    266 
    267             return false;
    268         case EbtUint:
    269             if (uConst < constant.uConst)
    270                 return true;
    271 
    272             return false;
    273         case EbtInt64:
    274             if (i64Const < constant.i64Const)
    275                 return true;
    276 
    277             return false;
    278         case EbtUint64:
    279             if (u64Const < constant.u64Const)
    280                 return true;
    281 
    282             return false;
    283         case EbtDouble:
    284             if (dConst < constant.dConst)
    285                 return true;
    286 
    287             return false;
    288         default:
    289             assert(false && "Default missing");
    290             return false;
    291         }
    292     }
    293 
    294     TConstUnion operator+(const TConstUnion& constant) const
    295     {
    296         TConstUnion returnValue;
    297         assert(type == constant.type);
    298         switch (type) {
    299         case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
    300         case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
    301         case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
    302         case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
    303         case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
    304         default: assert(false && "Default missing");
    305         }
    306 
    307         return returnValue;
    308     }
    309 
    310     TConstUnion operator-(const TConstUnion& constant) const
    311     {
    312         TConstUnion returnValue;
    313         assert(type == constant.type);
    314         switch (type) {
    315         case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
    316         case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
    317         case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
    318         case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
    319         case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
    320         default: assert(false && "Default missing");
    321         }
    322 
    323         return returnValue;
    324     }
    325 
    326     TConstUnion operator*(const TConstUnion& constant) const
    327     {
    328         TConstUnion returnValue;
    329         assert(type == constant.type);
    330         switch (type) {
    331         case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
    332         case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
    333         case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
    334         case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
    335         case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
    336         default: assert(false && "Default missing");
    337         }
    338 
    339         return returnValue;
    340     }
    341 
    342     TConstUnion operator%(const TConstUnion& constant) const
    343     {
    344         TConstUnion returnValue;
    345         assert(type == constant.type);
    346         switch (type) {
    347         case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
    348         case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
    349         case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
    350         case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
    351         default:     assert(false && "Default missing");
    352         }
    353 
    354         return returnValue;
    355     }
    356 
    357     TConstUnion operator>>(const TConstUnion& constant) const
    358     {
    359         TConstUnion returnValue;
    360         switch (type) {
    361         case EbtInt:
    362             switch (constant.type) {
    363             case EbtInt:    returnValue.setIConst(iConst >> constant.iConst);   break;
    364             case EbtUint:   returnValue.setIConst(iConst >> constant.uConst);   break;
    365             case EbtInt64:  returnValue.setIConst(iConst >> constant.i64Const); break;
    366             case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break;
    367             default:       assert(false && "Default missing");
    368             }
    369             break;
    370         case EbtUint:
    371             switch (constant.type) {
    372             case EbtInt:    returnValue.setUConst(uConst >> constant.iConst);   break;
    373             case EbtUint:   returnValue.setUConst(uConst >> constant.uConst);   break;
    374             case EbtInt64:  returnValue.setUConst(uConst >> constant.i64Const); break;
    375             case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break;
    376             default:       assert(false && "Default missing");
    377             }
    378             break;
    379          case EbtInt64:
    380             switch (constant.type) {
    381             case EbtInt:    returnValue.setI64Const(i64Const >> constant.iConst);   break;
    382             case EbtUint:   returnValue.setI64Const(i64Const >> constant.uConst);   break;
    383             case EbtInt64:  returnValue.setI64Const(i64Const >> constant.i64Const); break;
    384             case EbtUint64: returnValue.setI64Const(i64Const >> constant.u64Const); break;
    385             default:       assert(false && "Default missing");
    386             }
    387             break;
    388         case EbtUint64:
    389             switch (constant.type) {
    390             case EbtInt:    returnValue.setU64Const(u64Const >> constant.iConst);   break;
    391             case EbtUint:   returnValue.setU64Const(u64Const >> constant.uConst);   break;
    392             case EbtInt64:  returnValue.setU64Const(u64Const >> constant.i64Const); break;
    393             case EbtUint64: returnValue.setU64Const(u64Const >> constant.u64Const); break;
    394             default:       assert(false && "Default missing");
    395             }
    396             break;
    397         default:     assert(false && "Default missing");
    398         }
    399 
    400         return returnValue;
    401     }
    402 
    403     TConstUnion operator<<(const TConstUnion& constant) const
    404     {
    405         TConstUnion returnValue;
    406         switch (type) {
    407         case EbtInt:
    408             switch (constant.type) {
    409             case EbtInt:    returnValue.setIConst(iConst << constant.iConst);   break;
    410             case EbtUint:   returnValue.setIConst(iConst << constant.uConst);   break;
    411             case EbtInt64:  returnValue.setIConst(iConst << constant.i64Const); break;
    412             case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break;
    413             default:       assert(false && "Default missing");
    414             }
    415             break;
    416         case EbtUint:
    417             switch (constant.type) {
    418             case EbtInt:    returnValue.setUConst(uConst << constant.iConst);   break;
    419             case EbtUint:   returnValue.setUConst(uConst << constant.uConst);   break;
    420             case EbtInt64:  returnValue.setUConst(uConst << constant.i64Const); break;
    421             case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break;
    422             default:       assert(false && "Default missing");
    423             }
    424             break;
    425         case EbtInt64:
    426             switch (constant.type) {
    427             case EbtInt:    returnValue.setI64Const(i64Const << constant.iConst);   break;
    428             case EbtUint:   returnValue.setI64Const(i64Const << constant.uConst);   break;
    429             case EbtInt64:  returnValue.setI64Const(i64Const << constant.i64Const); break;
    430             case EbtUint64: returnValue.setI64Const(i64Const << constant.u64Const); break;
    431             default:       assert(false && "Default missing");
    432             }
    433             break;
    434         case EbtUint64:
    435             switch (constant.type) {
    436             case EbtInt:    returnValue.setU64Const(u64Const << constant.iConst);   break;
    437             case EbtUint:   returnValue.setU64Const(u64Const << constant.uConst);   break;
    438             case EbtInt64:  returnValue.setU64Const(u64Const << constant.i64Const); break;
    439             case EbtUint64: returnValue.setU64Const(u64Const << constant.u64Const); break;
    440             default:       assert(false && "Default missing");
    441             }
    442             break;
    443         default:     assert(false && "Default missing");
    444         }
    445 
    446         return returnValue;
    447     }
    448 
    449     TConstUnion operator&(const TConstUnion& constant) const
    450     {
    451         TConstUnion returnValue;
    452         assert(type == constant.type);
    453         switch (type) {
    454         case EbtInt:  returnValue.setIConst(iConst & constant.iConst); break;
    455         case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
    456         case EbtInt64:  returnValue.setI64Const(i64Const & constant.i64Const); break;
    457         case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break;
    458         default:     assert(false && "Default missing");
    459         }
    460 
    461         return returnValue;
    462     }
    463 
    464     TConstUnion operator|(const TConstUnion& constant) const
    465     {
    466         TConstUnion returnValue;
    467         assert(type == constant.type);
    468         switch (type) {
    469         case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
    470         case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
    471         case EbtInt64:  returnValue.setI64Const(i64Const | constant.i64Const); break;
    472         case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break;
    473         default:     assert(false && "Default missing");
    474         }
    475 
    476         return returnValue;
    477     }
    478 
    479     TConstUnion operator^(const TConstUnion& constant) const
    480     {
    481         TConstUnion returnValue;
    482         assert(type == constant.type);
    483         switch (type) {
    484         case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
    485         case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
    486         case EbtInt64:  returnValue.setI64Const(i64Const ^ constant.i64Const); break;
    487         case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break;
    488         default:     assert(false && "Default missing");
    489         }
    490 
    491         return returnValue;
    492     }
    493 
    494     TConstUnion operator~() const
    495     {
    496         TConstUnion returnValue;
    497         switch (type) {
    498         case EbtInt:  returnValue.setIConst(~iConst); break;
    499         case EbtUint: returnValue.setUConst(~uConst); break;
    500         case EbtInt64:  returnValue.setI64Const(~i64Const); break;
    501         case EbtUint64: returnValue.setU64Const(~u64Const); break;
    502         default:     assert(false && "Default missing");
    503         }
    504 
    505         return returnValue;
    506     }
    507 
    508     TConstUnion operator&&(const TConstUnion& constant) const
    509     {
    510         TConstUnion returnValue;
    511         assert(type == constant.type);
    512         switch (type) {
    513         case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
    514         default:     assert(false && "Default missing");
    515         }
    516 
    517         return returnValue;
    518     }
    519 
    520     TConstUnion operator||(const TConstUnion& constant) const
    521     {
    522         TConstUnion returnValue;
    523         assert(type == constant.type);
    524         switch (type) {
    525         case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
    526         default:     assert(false && "Default missing");
    527         }
    528 
    529         return returnValue;
    530     }
    531 
    532     TBasicType getType() const { return type; }
    533 
    534 private:
    535     union  {
    536         int                iConst;      // used for ivec, scalar ints
    537         unsigned int       uConst;      // used for uvec, scalar uints
    538         long long          i64Const;    // used for i64vec, scalar int64s
    539         unsigned long long u64Const;    // used for u64vec, scalar uint64s
    540         bool               bConst;      // used for bvec, scalar bools
    541         double             dConst;      // used for vec, dvec, mat, dmat, scalar floats and doubles
    542         const TString*     sConst;      // string constant
    543     };
    544 
    545     TBasicType type;
    546 };
    547 
    548 // Encapsulate having a pointer to an array of TConstUnion,
    549 // which only needs to be allocated if its size is going to be
    550 // bigger than 0.
    551 //
    552 // One convenience is being able to use [] to go inside the array, instead
    553 // of C++ assuming it as an array of pointers to vectors.
    554 //
    555 // General usage is that the size is known up front, and it is
    556 // created once with the proper size.
    557 //
    558 class TConstUnionArray {
    559 public:
    560     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
    561 
    562     TConstUnionArray() : unionArray(nullptr) { }
    563     virtual ~TConstUnionArray() { }
    564 
    565     explicit TConstUnionArray(int size)
    566     {
    567         if (size == 0)
    568             unionArray = nullptr;
    569         else
    570             unionArray =  new TConstUnionVector(size);
    571     }
    572     TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { }
    573     TConstUnionArray(const TConstUnionArray& a, int start, int size)
    574     {
    575         unionArray = new TConstUnionVector(size);
    576         for (int i = 0; i < size; ++i)
    577             (*unionArray)[i] = a[start + i];
    578     }
    579 
    580     // Use this constructor for a smear operation
    581     TConstUnionArray(int size, const TConstUnion& val)
    582     {
    583         unionArray = new TConstUnionVector(size, val);
    584     }
    585 
    586     int size() const { return unionArray ? (int)unionArray->size() : 0; }
    587     TConstUnion& operator[](size_t index) { return (*unionArray)[index]; }
    588     const TConstUnion& operator[](size_t index) const { return (*unionArray)[index]; }
    589     bool operator==(const TConstUnionArray& rhs) const
    590     {
    591         // this includes the case that both are unallocated
    592         if (unionArray == rhs.unionArray)
    593             return true;
    594 
    595         if (! unionArray || ! rhs.unionArray)
    596             return false;
    597 
    598         if (! unionArray || ! rhs.unionArray)
    599             return false;
    600 
    601         return *unionArray == *rhs.unionArray;
    602     }
    603     bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); }
    604 
    605     double dot(const TConstUnionArray& rhs)
    606     {
    607         assert(rhs.unionArray->size() == unionArray->size());
    608         double sum = 0.0;
    609 
    610         for (size_t comp = 0; comp < unionArray->size(); ++comp)
    611             sum += (*this)[comp].getDConst() * rhs[comp].getDConst();
    612 
    613         return sum;
    614     }
    615 
    616     bool empty() const { return unionArray == nullptr; }
    617 
    618 protected:
    619     typedef TVector<TConstUnion> TConstUnionVector;
    620     TConstUnionVector* unionArray;
    621 };
    622 
    623 } // end namespace glslang
    624 
    625 #endif // _CONSTANT_UNION_INCLUDED_
    626