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