• 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 #if !defined(GLSLANG_WEB)
37 
38 #ifndef _REFLECTION_INCLUDED
39 #define _REFLECTION_INCLUDED
40 
41 #include "../Public/ShaderLang.h"
42 #include "../Include/Types.h"
43 
44 #include <list>
45 #include <set>
46 
47 //
48 // A reflection database and its interface, consistent with the OpenGL API reflection queries.
49 //
50 
51 namespace glslang {
52 
53 class TIntermediate;
54 class TIntermAggregate;
55 class TReflectionTraverser;
56 
57 // The full reflection database
58 class TReflection {
59 public:
TReflection(EShReflectionOptions opts,EShLanguage first,EShLanguage last)60     TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last)
61         : options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection())
62     {
63         for (int dim=0; dim<3; ++dim)
64             localSize[dim] = 0;
65     }
66 
~TReflection()67     virtual ~TReflection() {}
68 
69     // grow the reflection stage by stage
70     bool addStage(EShLanguage, const TIntermediate&);
71 
72     // for mapping a uniform index to a uniform object's description
getNumUniforms()73     int getNumUniforms() { return (int)indexToUniform.size(); }
getUniform(int i)74     const TObjectReflection& getUniform(int i) const
75     {
76         if (i >= 0 && i < (int)indexToUniform.size())
77             return indexToUniform[i];
78         else
79             return badReflection;
80     }
81 
82     // for mapping a block index to the block's description
getNumUniformBlocks()83     int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); }
getUniformBlock(int i)84     const TObjectReflection& getUniformBlock(int i) const
85     {
86         if (i >= 0 && i < (int)indexToUniformBlock.size())
87             return indexToUniformBlock[i];
88         else
89             return badReflection;
90     }
91 
92     // for mapping an pipeline input index to the input's description
getNumPipeInputs()93     int getNumPipeInputs() { return (int)indexToPipeInput.size(); }
getPipeInput(int i)94     const TObjectReflection& getPipeInput(int i) const
95     {
96         if (i >= 0 && i < (int)indexToPipeInput.size())
97             return indexToPipeInput[i];
98         else
99             return badReflection;
100     }
101 
102     // for mapping an pipeline output index to the output's description
getNumPipeOutputs()103     int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); }
getPipeOutput(int i)104     const TObjectReflection& getPipeOutput(int i) const
105     {
106         if (i >= 0 && i < (int)indexToPipeOutput.size())
107             return indexToPipeOutput[i];
108         else
109             return badReflection;
110     }
111 
112     // for mapping from an atomic counter to the uniform index
getNumAtomicCounters()113     int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); }
getAtomicCounter(int i)114     const TObjectReflection& getAtomicCounter(int i) const
115     {
116         if (i >= 0 && i < (int)atomicCounterUniformIndices.size())
117             return getUniform(atomicCounterUniformIndices[i]);
118         else
119             return badReflection;
120     }
121 
122     // for mapping a buffer variable index to a buffer variable object's description
getNumBufferVariables()123     int getNumBufferVariables() { return (int)indexToBufferVariable.size(); }
getBufferVariable(int i)124     const TObjectReflection& getBufferVariable(int i) const
125     {
126         if (i >= 0 && i < (int)indexToBufferVariable.size())
127             return indexToBufferVariable[i];
128         else
129             return badReflection;
130     }
131 
132     // for mapping a storage block index to the storage block's description
getNumStorageBuffers()133     int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); }
getStorageBufferBlock(int i)134     const TObjectReflection&  getStorageBufferBlock(int i) const
135     {
136         if (i >= 0 && i < (int)indexToBufferBlock.size())
137             return indexToBufferBlock[i];
138         else
139             return badReflection;
140     }
141 
142     // for mapping any name to its index (block names, uniform names and input/output names)
getIndex(const char * name)143     int getIndex(const char* name) const
144     {
145         TNameToIndex::const_iterator it = nameToIndex.find(name);
146         if (it == nameToIndex.end())
147             return -1;
148         else
149             return it->second;
150     }
151 
152     // see getIndex(const char*)
getIndex(const TString & name)153     int getIndex(const TString& name) const { return getIndex(name.c_str()); }
154 
155 
156     // for mapping any name to its index (only pipe input/output names)
getPipeIOIndex(const char * name,const bool inOrOut)157     int getPipeIOIndex(const char* name, const bool inOrOut) const
158     {
159         TNameToIndex::const_iterator it = inOrOut ? pipeInNameToIndex.find(name) : pipeOutNameToIndex.find(name);
160         if (it == (inOrOut ? pipeInNameToIndex.end() : pipeOutNameToIndex.end()))
161             return -1;
162         else
163             return it->second;
164     }
165 
166     // see gePipeIOIndex(const char*, const bool)
getPipeIOIndex(const TString & name,const bool inOrOut)167     int getPipeIOIndex(const TString& name, const bool inOrOut) const { return getPipeIOIndex(name.c_str(), inOrOut); }
168 
169     // Thread local size
getLocalSize(int dim)170     unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
171 
172     void dump();
173 
174 protected:
175     friend class glslang::TReflectionTraverser;
176 
177     void buildCounterIndices(const TIntermediate&);
178     void buildUniformStageMask(const TIntermediate& intermediate);
179     void buildAttributeReflection(EShLanguage, const TIntermediate&);
180 
181     // Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
182     typedef std::map<std::string, int> TNameToIndex;
183     typedef std::vector<TObjectReflection> TMapIndexToReflection;
184     typedef std::vector<int> TIndices;
185 
GetBlockMapForStorage(TStorageQualifier storage)186     TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage)
187     {
188         if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
189             return indexToBufferBlock;
190         return indexToUniformBlock;
191     }
GetVariableMapForStorage(TStorageQualifier storage)192     TMapIndexToReflection& GetVariableMapForStorage(TStorageQualifier storage)
193     {
194         if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
195             return indexToBufferVariable;
196         return indexToUniform;
197     }
198 
199     EShReflectionOptions options;
200 
201     EShLanguage firstStage;
202     EShLanguage lastStage;
203 
204     TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
205     TNameToIndex nameToIndex;        // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
206     TNameToIndex pipeInNameToIndex;  // maps pipe in names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
207     TNameToIndex pipeOutNameToIndex; // maps pipe out names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
208     TMapIndexToReflection indexToUniform;
209     TMapIndexToReflection indexToUniformBlock;
210     TMapIndexToReflection indexToBufferVariable;
211     TMapIndexToReflection indexToBufferBlock;
212     TMapIndexToReflection indexToPipeInput;
213     TMapIndexToReflection indexToPipeOutput;
214     TIndices atomicCounterUniformIndices;
215 
216     unsigned int localSize[3];
217 };
218 
219 } // end namespace glslang
220 
221 #endif // _REFLECTION_INCLUDED
222 
223 #endif // !GLSLANG_WEB
224