Coverage Report

Created: 2025-07-18 06:47

/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