1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_INSPECTOR_INSPECTOR_H_
16 #define SRC_INSPECTOR_INSPECTOR_H_
17 
18 #include <map>
19 #include <memory>
20 #include <string>
21 #include <tuple>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include "src/inspector/entry_point.h"
26 #include "src/inspector/resource_binding.h"
27 #include "src/inspector/sampler_texture_pair.h"
28 #include "src/inspector/scalar.h"
29 #include "src/program.h"
30 #include "src/utils/unique_vector.h"
31 
32 namespace tint {
33 namespace inspector {
34 
35 /// Extracts information from a program
36 class Inspector {
37  public:
38   /// Constructor
39   /// @param program Shader program to extract information from.
40   explicit Inspector(const Program* program);
41 
42   /// Destructor
43   ~Inspector();
44 
45   /// @returns error messages from the Inspector
error()46   std::string error() { return diagnostics_.str(); }
47   /// @returns true if an error was encountered
has_error() const48   bool has_error() const { return diagnostics_.contains_errors(); }
49 
50   /// @returns vector of entry point information
51   std::vector<EntryPoint> GetEntryPoints();
52 
53   /// @param entry_point name of the entry point to get the remapped version of
54   /// @returns the remapped name of the entry point, or the empty string if it
55   ///          isn't a known entry point.
56   std::string GetRemappedNameForEntryPoint(const std::string& entry_point);
57 
58   /// @returns map of const_id to initial value
59   std::map<uint32_t, Scalar> GetConstantIDs();
60 
61   /// @returns map of module-constant name to pipeline constant ID
62   std::map<std::string, uint32_t> GetConstantNameToIdMap();
63 
64   /// @param entry_point name of the entry point to get information about.
65   /// @returns the total size of shared storage required by an entry point,
66   ///          including all uniform storage buffers.
67   uint32_t GetStorageSize(const std::string& entry_point);
68 
69   /// @param entry_point name of the entry point to get information about.
70   /// @returns vector of all of the resource bindings.
71   std::vector<ResourceBinding> GetResourceBindings(
72       const std::string& entry_point);
73 
74   /// @param entry_point name of the entry point to get information about.
75   /// @returns vector of all of the bindings for uniform buffers.
76   std::vector<ResourceBinding> GetUniformBufferResourceBindings(
77       const std::string& entry_point);
78 
79   /// @param entry_point name of the entry point to get information about.
80   /// @returns vector of all of the bindings for storage buffers.
81   std::vector<ResourceBinding> GetStorageBufferResourceBindings(
82       const std::string& entry_point);
83 
84   /// @param entry_point name of the entry point to get information about.
85   /// @returns vector of all of the bindings for read-only storage buffers.
86   std::vector<ResourceBinding> GetReadOnlyStorageBufferResourceBindings(
87       const std::string& entry_point);
88 
89   /// @param entry_point name of the entry point to get information about.
90   /// @returns vector of all of the bindings for regular samplers.
91   std::vector<ResourceBinding> GetSamplerResourceBindings(
92       const std::string& entry_point);
93 
94   /// @param entry_point name of the entry point to get information about.
95   /// @returns vector of all of the bindings for comparison samplers.
96   std::vector<ResourceBinding> GetComparisonSamplerResourceBindings(
97       const std::string& entry_point);
98 
99   /// @param entry_point name of the entry point to get information about.
100   /// @returns vector of all of the bindings for sampled textures.
101   std::vector<ResourceBinding> GetSampledTextureResourceBindings(
102       const std::string& entry_point);
103 
104   /// @param entry_point name of the entry point to get information about.
105   /// @returns vector of all of the bindings for multisampled textures.
106   std::vector<ResourceBinding> GetMultisampledTextureResourceBindings(
107       const std::string& entry_point);
108 
109   /// @param entry_point name of the entry point to get information about.
110   /// @returns vector of all of the bindings for write-only storage textures.
111   std::vector<ResourceBinding> GetWriteOnlyStorageTextureResourceBindings(
112       const std::string& entry_point);
113 
114   /// @param entry_point name of the entry point to get information about.
115   /// @returns vector of all of the bindings for depth textures.
116   std::vector<ResourceBinding> GetDepthTextureResourceBindings(
117       const std::string& entry_point);
118 
119   /// @param entry_point name of the entry point to get information about.
120   /// @returns vector of all of the bindings for depth textures.
121   std::vector<ResourceBinding> GetDepthMultisampledTextureResourceBindings(
122       const std::string& entry_point);
123 
124   /// @param entry_point name of the entry point to get information about.
125   /// @returns vector of all of the bindings for external textures.
126   std::vector<ResourceBinding> GetExternalTextureResourceBindings(
127       const std::string& entry_point);
128 
129   /// @param entry_point name of the entry point to get information about.
130   /// @returns vector of all of the sampler/texture sampling pairs that are used
131   /// by that entry point.
132   std::vector<SamplerTexturePair> GetSamplerTextureUses(
133       const std::string& entry_point);
134 
135   /// @param entry_point name of the entry point to get information about.
136   /// @returns the total size in bytes of all Workgroup storage-class storage
137   /// referenced transitively by the entry point.
138   uint32_t GetWorkgroupStorageSize(const std::string& entry_point);
139 
140  private:
141   const Program* program_;
142   diag::List diagnostics_;
143   std::unique_ptr<
144       std::unordered_map<std::string, utils::UniqueVector<SamplerTexturePair>>>
145       sampler_targets_;
146 
147   /// @param name name of the entry point to find
148   /// @returns a pointer to the entry point if it exists, otherwise returns
149   ///          nullptr and sets the error string.
150   const ast::Function* FindEntryPointByName(const std::string& name);
151 
152   /// Recursively add entry point IO variables.
153   /// If `type` is a struct, recurse into members, appending the member name.
154   /// Otherwise, add the variable unless it is a builtin.
155   /// @param name the name of the variable being added
156   /// @param type the type of the variable
157   /// @param decorations the variable decorations
158   /// @param variables the list to add the variables to
159   void AddEntryPointInOutVariables(std::string name,
160                                    const sem::Type* type,
161                                    const ast::DecorationList& decorations,
162                                    std::vector<StageVariable>& variables) const;
163 
164   /// Recursively determine if the type contains builtin.
165   /// If `type` is a struct, recurse into members to check for the decoration.
166   /// Otherwise, check `decorations` for the decoration.
167   bool ContainsBuiltin(ast::Builtin builtin,
168                        const sem::Type* type,
169                        const ast::DecorationList& decorations) const;
170 
171   /// Gathers all the texture resource bindings of the given type for the given
172   /// entry point.
173   /// @param entry_point name of the entry point to get information about.
174   /// @param texture_type the type of the textures to gather.
175   /// @param resource_type the ResourceBinding::ResourceType for the given
176   /// texture type.
177   /// @returns vector of all of the bindings for depth textures.
178   std::vector<ResourceBinding> GetTextureResourceBindings(
179       const std::string& entry_point,
180       const tint::TypeInfo& texture_type,
181       ResourceBinding::ResourceType resource_type);
182 
183   /// @param entry_point name of the entry point to get information about.
184   /// @param read_only if true get only read-only bindings, if false get
185   ///                  write-only bindings.
186   /// @returns vector of all of the bindings for the requested storage buffers.
187   std::vector<ResourceBinding> GetStorageBufferResourceBindingsImpl(
188       const std::string& entry_point,
189       bool read_only);
190 
191   /// @param entry_point name of the entry point to get information about.
192   /// @param multisampled_only only get multisampled textures if true, otherwise
193   ///                          only get sampled textures.
194   /// @returns vector of all of the bindings for the request storage buffers.
195   std::vector<ResourceBinding> GetSampledTextureResourceBindingsImpl(
196       const std::string& entry_point,
197       bool multisampled_only);
198 
199   /// @param entry_point name of the entry point to get information about.
200   /// @returns vector of all of the bindings for the requested storage textures.
201   std::vector<ResourceBinding> GetStorageTextureResourceBindingsImpl(
202       const std::string& entry_point);
203 
204   /// Constructs |sampler_targets_| if it hasn't already been instantiated.
205   void GenerateSamplerTargets();
206 
207   /// For a N-uple of expressions, resolve to the appropriate global resources
208   /// and call 'cb'.
209   /// 'cb' may be called multiple times.
210   /// Assumes that not being able to resolve the resources is an error, so will
211   /// invoke TINT_ICE when that occurs.
212   /// @tparam N number of expressions in the n-uple
213   /// @tparam F type of the callback provided.
214   /// @param exprs N-uple of expressions to resolve.
215   /// @param cb is a callback function with the signature:
216   /// `void(std::array<const sem::GlobalVariable*, N>)`, which is invoked
217   /// whenever a set of expressions are resolved to globals.
218   template <size_t N, typename F>
219   void GetOriginatingResources(std::array<const ast::Expression*, N> exprs,
220                                F&& cb);
221 };
222 
223 }  // namespace inspector
224 }  // namespace tint
225 
226 #endif  // SRC_INSPECTOR_INSPECTOR_H_
227