• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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_TEST_INSPECTOR_BUILDER_H_
16 #define SRC_INSPECTOR_TEST_INSPECTOR_BUILDER_H_
17 
18 #include <memory>
19 #include <string>
20 #include <tuple>
21 #include <vector>
22 
23 #include "src/ast/call_statement.h"
24 #include "src/ast/disable_validation_decoration.h"
25 #include "src/ast/override_decoration.h"
26 #include "src/ast/stage_decoration.h"
27 #include "src/ast/struct_block_decoration.h"
28 #include "src/ast/workgroup_decoration.h"
29 #include "src/program_builder.h"
30 #include "src/sem/depth_texture_type.h"
31 #include "src/sem/external_texture_type.h"
32 #include "src/sem/multisampled_texture_type.h"
33 #include "src/sem/sampled_texture_type.h"
34 #include "src/sem/variable.h"
35 #include "tint/tint.h"
36 
37 namespace tint {
38 namespace inspector {
39 
40 /// Utility class for building programs in inspector tests
41 class InspectorBuilder : public ProgramBuilder {
42  public:
43   InspectorBuilder();
44   ~InspectorBuilder() override;
45 
46   /// Generates an empty function
47   /// @param name name of the function created
48   /// @param decorations the function decorations
49   void MakeEmptyBodyFunction(std::string name, ast::DecorationList decorations);
50 
51   /// Generates a function that calls other functions
52   /// @param caller name of the function created
53   /// @param callees names of the functions to be called
54   /// @param decorations the function decorations
55   void MakeCallerBodyFunction(std::string caller,
56                               std::vector<std::string> callees,
57                               ast::DecorationList decorations);
58 
59   /// Generates a struct that contains user-defined IO members
60   /// @param name the name of the generated struct
61   /// @param inout_vars tuples of {name, loc} that will be the struct members
62   /// @returns a structure object
63   const ast::Struct* MakeInOutStruct(
64       std::string name,
65       std::vector<std::tuple<std::string, uint32_t>> inout_vars);
66 
67   // TODO(crbug.com/tint/697): Remove this.
68   /// Add In/Out variables to the global variables
69   /// @param inout_vars tuples of {in, out} that will be added as entries to the
70   ///                   global variables
71   void AddInOutVariables(
72       std::vector<std::tuple<std::string, std::string>> inout_vars);
73 
74   // TODO(crbug.com/tint/697): Remove this.
75   /// Generates a function that references in/out variables
76   /// @param name name of the function created
77   /// @param inout_vars tuples of {in, out} that will be converted into out = in
78   ///                   calls in the function body
79   /// @param decorations the function decorations
80   void MakeInOutVariableBodyFunction(
81       std::string name,
82       std::vector<std::tuple<std::string, std::string>> inout_vars,
83       ast::DecorationList decorations);
84 
85   // TODO(crbug.com/tint/697): Remove this.
86   /// Generates a function that references in/out variables and calls another
87   /// function.
88   /// @param caller name of the function created
89   /// @param callee name of the function to be called
90   /// @param inout_vars tuples of {in, out} that will be converted into out = in
91   ///                   calls in the function body
92   /// @param decorations the function decorations
93   /// @returns a function object
94   const ast::Function* MakeInOutVariableCallerBodyFunction(
95       std::string caller,
96       std::string callee,
97       std::vector<std::tuple<std::string, std::string>> inout_vars,
98       ast::DecorationList decorations);
99 
100   /// Add a pipeline constant to the global variables, with a specific ID.
101   /// @param name name of the variable to add
102   /// @param id id number for the constant id
103   /// @param type type of the variable
104   /// @param constructor val to initialize the constant with, if NULL no
105   ///             constructor will be added.
106   /// @returns the constant that was created
AddOverridableConstantWithID(std::string name,uint32_t id,const ast::Type * type,const ast::Expression * constructor)107   const ast::Variable* AddOverridableConstantWithID(
108       std::string name,
109       uint32_t id,
110       const ast::Type* type,
111       const ast::Expression* constructor) {
112     return GlobalConst(name, type, constructor,
113                        ast::DecorationList{
114                            Override(id),
115                        });
116   }
117 
118   /// Add a pipeline constant to the global variables, without a specific ID.
119   /// @param name name of the variable to add
120   /// @param type type of the variable
121   /// @param constructor val to initialize the constant with, if NULL no
122   ///             constructor will be added.
123   /// @returns the constant that was created
AddOverridableConstantWithoutID(std::string name,const ast::Type * type,const ast::Expression * constructor)124   const ast::Variable* AddOverridableConstantWithoutID(
125       std::string name,
126       const ast::Type* type,
127       const ast::Expression* constructor) {
128     return GlobalConst(name, type, constructor,
129                        ast::DecorationList{
130                            Override(),
131                        });
132   }
133 
134   /// Generates a function that references module-scoped, plain-typed constant
135   /// or variable.
136   /// @param func name of the function created
137   /// @param var name of the constant to be reference
138   /// @param type type of the const being referenced
139   /// @param decorations the function decorations
140   /// @returns a function object
141   const ast::Function* MakePlainGlobalReferenceBodyFunction(
142       std::string func,
143       std::string var,
144       const ast::Type* type,
145       ast::DecorationList decorations);
146 
147   /// @param vec Vector of StageVariable to be searched
148   /// @param name Name to be searching for
149   /// @returns true if name is in vec, otherwise false
150   bool ContainsName(const std::vector<StageVariable>& vec,
151                     const std::string& name);
152 
153   /// Builds a string for accessing a member in a generated struct
154   /// @param idx index of member
155   /// @param type type of member
156   /// @returns a string for the member
157   std::string StructMemberName(size_t idx, const ast::Type* type);
158 
159   /// Generates a struct type
160   /// @param name name for the type
161   /// @param member_types a vector of member types
162   /// @param is_block whether or not to decorate as a Block
163   /// @returns a struct type
164   const ast::Struct* MakeStructType(const std::string& name,
165                                     std::vector<const ast::Type*> member_types,
166                                     bool is_block);
167 
168   /// Generates a struct type from a list of member nodes.
169   /// @param name name for the struct type
170   /// @param members a vector of members
171   /// @param is_block whether or not to decorate as a Block
172   /// @returns a struct type
173   const ast::Struct* MakeStructTypeFromMembers(const std::string& name,
174                                                ast::StructMemberList members,
175                                                bool is_block);
176 
177   /// Generates a struct member with a specified index and type.
178   /// @param index index of the field within the struct
179   /// @param type the type of the member field
180   /// @param decorations a list of decorations to apply to the member field
181   /// @returns a struct member
182   const ast::StructMember* MakeStructMember(size_t index,
183                                             const ast::Type* type,
184                                             ast::DecorationList decorations);
185 
186   /// Generates types appropriate for using in an uniform buffer
187   /// @param name name for the type
188   /// @param member_types a vector of member types
189   /// @returns a struct type that has the layout for an uniform buffer.
190   const ast::Struct* MakeUniformBufferType(
191       const std::string& name,
192       std::vector<const ast::Type*> member_types);
193 
194   /// Generates types appropriate for using in a storage buffer
195   /// @param name name for the type
196   /// @param member_types a vector of member types
197   /// @returns a function that returns the created structure.
198   std::function<const ast::TypeName*()> MakeStorageBufferTypes(
199       const std::string& name,
200       std::vector<const ast::Type*> member_types);
201 
202   /// Adds an uniform buffer variable to the program
203   /// @param name the name of the variable
204   /// @param type the type to use
205   /// @param group the binding/group/ to use for the uniform buffer
206   /// @param binding the binding number to use for the uniform buffer
207   void AddUniformBuffer(const std::string& name,
208                         const ast::Type* type,
209                         uint32_t group,
210                         uint32_t binding);
211 
212   /// Adds a workgroup storage variable to the program
213   /// @param name the name of the variable
214   /// @param type the type of the variable
215   void AddWorkgroupStorage(const std::string& name, const ast::Type* type);
216 
217   /// Adds a storage buffer variable to the program
218   /// @param name the name of the variable
219   /// @param type the type to use
220   /// @param access the storage buffer access control
221   /// @param group the binding/group to use for the storage buffer
222   /// @param binding the binding number to use for the storage buffer
223   void AddStorageBuffer(const std::string& name,
224                         const ast::Type* type,
225                         ast::Access access,
226                         uint32_t group,
227                         uint32_t binding);
228 
229   /// Generates a function that references a specific struct variable
230   /// @param func_name name of the function created
231   /// @param struct_name name of the struct variabler to be accessed
232   /// @param members list of members to access, by index and type
233   void MakeStructVariableReferenceBodyFunction(
234       std::string func_name,
235       std::string struct_name,
236       std::vector<std::tuple<size_t, const ast::Type*>> members);
237 
238   /// Adds a regular sampler variable to the program
239   /// @param name the name of the variable
240   /// @param group the binding/group to use for the storage buffer
241   /// @param binding the binding number to use for the storage buffer
242   void AddSampler(const std::string& name, uint32_t group, uint32_t binding);
243 
244   /// Adds a comparison sampler variable to the program
245   /// @param name the name of the variable
246   /// @param group the binding/group to use for the storage buffer
247   /// @param binding the binding number to use for the storage buffer
248   void AddComparisonSampler(const std::string& name,
249                             uint32_t group,
250                             uint32_t binding);
251 
252   /// Adds a sampler or texture variable to the program
253   /// @param name the name of the variable
254   /// @param type the type to use
255   /// @param group the binding/group to use for the resource
256   /// @param binding the binding number to use for the resource
257   void AddResource(const std::string& name,
258                    const ast::Type* type,
259                    uint32_t group,
260                    uint32_t binding);
261 
262   /// Add a module scope private variable to the progames
263   /// @param name the name of the variable
264   /// @param type the type to use
265   void AddGlobalVariable(const std::string& name, const ast::Type* type);
266 
267   /// Generates a function that references a specific sampler variable
268   /// @param func_name name of the function created
269   /// @param texture_name name of the texture to be sampled
270   /// @param sampler_name name of the sampler to use
271   /// @param coords_name name of the coords variable to use
272   /// @param base_type sampler base type
273   /// @param decorations the function decorations
274   /// @returns a function that references all of the values specified
275   const ast::Function* MakeSamplerReferenceBodyFunction(
276       const std::string& func_name,
277       const std::string& texture_name,
278       const std::string& sampler_name,
279       const std::string& coords_name,
280       const ast::Type* base_type,
281       ast::DecorationList decorations);
282 
283   /// Generates a function that references a specific sampler variable
284   /// @param func_name name of the function created
285   /// @param texture_name name of the texture to be sampled
286   /// @param sampler_name name of the sampler to use
287   /// @param coords_name name of the coords variable to use
288   /// @param array_index name of the array index variable to use
289   /// @param base_type sampler base type
290   /// @param decorations the function decorations
291   /// @returns a function that references all of the values specified
292   const ast::Function* MakeSamplerReferenceBodyFunction(
293       const std::string& func_name,
294       const std::string& texture_name,
295       const std::string& sampler_name,
296       const std::string& coords_name,
297       const std::string& array_index,
298       const ast::Type* base_type,
299       ast::DecorationList decorations);
300 
301   /// Generates a function that references a specific comparison sampler
302   /// variable.
303   /// @param func_name name of the function created
304   /// @param texture_name name of the depth texture to  use
305   /// @param sampler_name name of the sampler to use
306   /// @param coords_name name of the coords variable to use
307   /// @param depth_name name of the depth reference to use
308   /// @param base_type sampler base type
309   /// @param decorations the function decorations
310   /// @returns a function that references all of the values specified
311   const ast::Function* MakeComparisonSamplerReferenceBodyFunction(
312       const std::string& func_name,
313       const std::string& texture_name,
314       const std::string& sampler_name,
315       const std::string& coords_name,
316       const std::string& depth_name,
317       const ast::Type* base_type,
318       ast::DecorationList decorations);
319 
320   /// Gets an appropriate type for the data in a given texture type.
321   /// @param sampled_kind type of in the texture
322   /// @returns a pointer to a type appropriate for the coord param
323   const ast::Type* GetBaseType(ResourceBinding::SampledKind sampled_kind);
324 
325   /// Gets an appropriate type for the coords parameter depending the the
326   /// dimensionality of the texture being sampled.
327   /// @param dim dimensionality of the texture being sampled
328   /// @param scalar the scalar type
329   /// @returns a pointer to a type appropriate for the coord param
330   const ast::Type* GetCoordsType(ast::TextureDimension dim,
331                                  const ast::Type* scalar);
332 
333   /// Generates appropriate types for a Read-Only StorageTexture
334   /// @param dim the texture dimension of the storage texture
335   /// @param format the image format of the storage texture
336   /// @returns the storage texture type
337   const ast::Type* MakeStorageTextureTypes(ast::TextureDimension dim,
338                                            ast::ImageFormat format);
339 
340   /// Adds a storage texture variable to the program
341   /// @param name the name of the variable
342   /// @param type the type to use
343   /// @param group the binding/group to use for the sampled texture
344   /// @param binding the binding57 number to use for the sampled texture
345   void AddStorageTexture(const std::string& name,
346                          const ast::Type* type,
347                          uint32_t group,
348                          uint32_t binding);
349 
350   /// Generates a function that references a storage texture variable.
351   /// @param func_name name of the function created
352   /// @param st_name name of the storage texture to use
353   /// @param dim_type type expected by textureDimensons to return
354   /// @param decorations the function decorations
355   /// @returns a function that references all of the values specified
356   const ast::Function* MakeStorageTextureBodyFunction(
357       const std::string& func_name,
358       const std::string& st_name,
359       const ast::Type* dim_type,
360       ast::DecorationList decorations);
361 
362   /// Get a generator function that returns a type appropriate for a stage
363   /// variable with the given combination of component and composition type.
364   /// @param component component type of the stage variable
365   /// @param composition composition type of the stage variable
366   /// @returns a generator function for the stage variable's type.
367   std::function<const ast::Type*()> GetTypeFunction(
368       ComponentType component,
369       CompositionType composition);
370 
371   /// Build the Program given all of the previous methods called and return an
372   /// Inspector for it.
373   /// Should only be called once per test.
374   /// @returns a reference to the Inspector for the built Program.
375   Inspector& Build();
376 
377   /// @returns the type for a SamplerKind::kSampler
sampler_type()378   const ast::Sampler* sampler_type() {
379     return ty.sampler(ast::SamplerKind::kSampler);
380   }
381 
382   /// @returns the type for a SamplerKind::kComparison
comparison_sampler_type()383   const ast::Sampler* comparison_sampler_type() {
384     return ty.sampler(ast::SamplerKind::kComparisonSampler);
385   }
386 
387  protected:
388   /// Program built by this builder.
389   std::unique_ptr<Program> program_;
390   /// Inspector for |program_|
391   std::unique_ptr<Inspector> inspector_;
392 };
393 
394 }  // namespace inspector
395 }  // namespace tint
396 
397 #endif  // SRC_INSPECTOR_TEST_INSPECTOR_BUILDER_H_
398