• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2013-2016 LunarG, Inc.
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions
8 // are met:
9 //
10 //    Redistributions of source code must retain the above copyright
11 //    notice, this list of conditions and the following disclaimer.
12 //
13 //    Redistributions in binary form must reproduce the above
14 //    copyright notice, this list of conditions and the following
15 //    disclaimer in the documentation and/or other materials provided
16 //    with the distribution.
17 //
18 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
19 //    contributors may be used to endorse or promote products derived
20 //    from this software without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 // POSSIBILITY OF SUCH DAMAGE.
34 //
35 
36 #ifndef _REFLECTION_INCLUDED
37 #define _REFLECTION_INCLUDED
38 
39 #include "../Public/ShaderLang.h"
40 #include "../Include/Types.h"
41 
42 #include <list>
43 #include <set>
44 
45 //
46 // A reflection database and its interface, consistent with the OpenGL API reflection queries.
47 //
48 
49 namespace glslang {
50 
51 class TIntermediate;
52 class TIntermAggregate;
53 class TReflectionTraverser;
54 
55 // Data needed for just a single object at the granularity exchanged by the reflection API
56 class TObjectReflection {
57 public:
TObjectReflection(const TString & pName,const TType & pType,int pOffset,int pGLDefineType,int pSize,int pIndex)58     TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
59         name(pName), offset(pOffset),
60         glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), stages(EShLanguageMask(0)), type(pType.clone()) { }
61 
getType()62     const TType* getType() const { return type; }
getBinding()63     int getBinding() const
64     {
65         if (type == nullptr || !type->getQualifier().hasBinding())
66             return -1;
67         return type->getQualifier().layoutBinding;
68     }
dump()69     void dump() const
70     {
71         printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d",
72                name.c_str(), offset, glDefineType, size, index, getBinding(), stages );
73 
74         if (counterIndex != -1)
75             printf(", counter %d", counterIndex);
76 
77         printf("\n");
78     }
badReflection()79     static TObjectReflection badReflection() { return TObjectReflection(); }
80 
81     TString name;
82     int offset;
83     int glDefineType;
84     int size;         // data size in bytes for a block, array size for a (non-block) object that's an array
85     int index;
86     int counterIndex;
87     EShLanguageMask stages;
88 
89 protected:
TObjectReflection()90     TObjectReflection() : offset(-1), glDefineType(-1), size(-1), index(-1), type(nullptr) { }
91 
92     const TType* type;
93 };
94 
95 // The full reflection database
96 class TReflection {
97 public:
TReflection()98     TReflection() : badReflection(TObjectReflection::badReflection())
99     {
100         for (int dim=0; dim<3; ++dim)
101             localSize[dim] = 0;
102     }
103 
~TReflection()104     virtual ~TReflection() {}
105 
106     // grow the reflection stage by stage
107     bool addStage(EShLanguage, const TIntermediate&);
108 
109     // for mapping a uniform index to a uniform object's description
getNumUniforms()110     int getNumUniforms() { return (int)indexToUniform.size(); }
getUniform(int i)111     const TObjectReflection& getUniform(int i) const
112     {
113         if (i >= 0 && i < (int)indexToUniform.size())
114             return indexToUniform[i];
115         else
116             return badReflection;
117     }
118 
119     // for mapping a block index to the block's description
getNumUniformBlocks()120     int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); }
getUniformBlock(int i)121     const TObjectReflection& getUniformBlock(int i) const
122     {
123         if (i >= 0 && i < (int)indexToUniformBlock.size())
124             return indexToUniformBlock[i];
125         else
126             return badReflection;
127     }
128 
129     // for mapping an attribute index to the attribute's description
getNumAttributes()130     int getNumAttributes() { return (int)indexToAttribute.size(); }
getAttribute(int i)131     const TObjectReflection& getAttribute(int i) const
132     {
133         if (i >= 0 && i < (int)indexToAttribute.size())
134             return indexToAttribute[i];
135         else
136             return badReflection;
137     }
138 
139     // for mapping any name to its index (block names, uniform names and attribute names)
getIndex(const char * name)140     int getIndex(const char* name) const
141     {
142         TNameToIndex::const_iterator it = nameToIndex.find(name);
143         if (it == nameToIndex.end())
144             return -1;
145         else
146             return it->second;
147     }
148 
149     // see getIndex(const char*)
getIndex(const TString & name)150     int getIndex(const TString& name) const { return getIndex(name.c_str()); }
151 
152     // Thread local size
getLocalSize(int dim)153     unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
154 
155     void dump();
156 
157 protected:
158     friend class glslang::TReflectionTraverser;
159 
160     void buildCounterIndices(const TIntermediate&);
161     void buildUniformStageMask(const TIntermediate& intermediate);
162     void buildAttributeReflection(EShLanguage, const TIntermediate&);
163 
164     // Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
165     typedef std::map<TString, int> TNameToIndex;
166     typedef std::vector<TObjectReflection> TMapIndexToReflection;
167 
168     TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
169     TNameToIndex nameToIndex;        // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
170     TMapIndexToReflection indexToUniform;
171     TMapIndexToReflection indexToUniformBlock;
172     TMapIndexToReflection indexToAttribute;
173 
174     unsigned int localSize[3];
175 };
176 
177 } // end namespace glslang
178 
179 #endif // _REFLECTION_INCLUDED
180