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