Use GLSLANG_ANGLE to strip features to what ANGLE requires
[platform/upstream/glslang.git] / glslang / MachineIndependent / reflection.h
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) && !defined(GLSLANG_ANGLE)
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:
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
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
73     int getNumUniforms() { return (int)indexToUniform.size(); }
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
83     int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); }
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
93     int getNumPipeInputs() { return (int)indexToPipeInput.size(); }
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
103     int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); }
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
113     int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); }
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
123     int getNumBufferVariables() { return (int)indexToBufferVariable.size(); }
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
133     int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); }
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)
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*)
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)
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)
167     int getPipeIOIndex(const TString& name, const bool inOrOut) const { return getPipeIOIndex(name.c_str(), inOrOut); }
168
169     // Thread local size
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
186     TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage)
187     {
188         if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
189             return indexToBufferBlock;
190         return indexToUniformBlock;
191     }
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 && !GLSLANG_ANGLE