• 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_SEM_STRUCT_H_
16 #define SRC_SEM_STRUCT_H_
17 
18 #include <stdint.h>
19 
20 #include <string>
21 #include <unordered_set>
22 #include <vector>
23 
24 #include "src/ast/storage_class.h"
25 #include "src/ast/struct.h"
26 #include "src/sem/node.h"
27 #include "src/sem/type.h"
28 #include "src/symbol.h"
29 
30 namespace tint {
31 
32 // Forward declarations
33 namespace ast {
34 class StructMember;
35 }  // namespace ast
36 
37 namespace sem {
38 
39 // Forward declarations
40 class StructMember;
41 class Type;
42 
43 /// A vector of StructMember pointers.
44 using StructMemberList = std::vector<const StructMember*>;
45 
46 /// Metadata to capture how a structure is used in a shader module.
47 enum class PipelineStageUsage {
48   kVertexInput,
49   kVertexOutput,
50   kFragmentInput,
51   kFragmentOutput,
52   kComputeInput,
53   kComputeOutput,
54 };
55 
56 /// Struct holds the semantic information for structures.
57 class Struct : public Castable<Struct, Type> {
58  public:
59   /// Constructor
60   /// @param declaration the AST structure declaration
61   /// @param name the name of the structure
62   /// @param members the structure members
63   /// @param align the byte alignment of the structure
64   /// @param size the byte size of the structure
65   /// @param size_no_padding size of the members without the end of structure
66   /// alignment padding
67   Struct(const ast::Struct* declaration,
68          Symbol name,
69          StructMemberList members,
70          uint32_t align,
71          uint32_t size,
72          uint32_t size_no_padding);
73 
74   /// Destructor
75   ~Struct() override;
76 
77   /// @returns the struct
Declaration()78   const ast::Struct* Declaration() const { return declaration_; }
79 
80   /// @returns the name of the structure
Name()81   Symbol Name() const { return name_; }
82 
83   /// @returns the members of the structure
Members()84   const StructMemberList& Members() const { return members_; }
85 
86   /// @param name the member name to look for
87   /// @returns the member with the given name, or nullptr if it was not found.
88   const StructMember* FindMember(Symbol name) const;
89 
90   /// @returns the byte alignment of the structure
91   /// @note this may differ from the alignment of a structure member of this
92   /// structure type, if the member is annotated with the `[[align(n)]]`
93   /// decoration.
94   uint32_t Align() const override;
95 
96   /// @returns the byte size of the structure
97   /// @note this may differ from the size of a structure member of this
98   /// structure type, if the member is annotated with the `[[size(n)]]`
99   /// decoration.
100   uint32_t Size() const override;
101 
102   /// @returns the byte size of the members without the end of structure
103   /// alignment padding
SizeNoPadding()104   uint32_t SizeNoPadding() const { return size_no_padding_; }
105 
106   /// Adds the StorageClass usage to the structure.
107   /// @param usage the storage usage
AddUsage(ast::StorageClass usage)108   void AddUsage(ast::StorageClass usage) {
109     storage_class_usage_.emplace(usage);
110   }
111 
112   /// @returns the set of storage class uses of this structure
StorageClassUsage()113   const std::unordered_set<ast::StorageClass>& StorageClassUsage() const {
114     return storage_class_usage_;
115   }
116 
117   /// @param usage the ast::StorageClass usage type to query
118   /// @returns true iff this structure has been used as the given storage class
UsedAs(ast::StorageClass usage)119   bool UsedAs(ast::StorageClass usage) const {
120     return storage_class_usage_.count(usage) > 0;
121   }
122 
123   /// @returns true iff this structure has been used by storage class that's
124   /// host-shareable.
IsHostShareable()125   bool IsHostShareable() const {
126     for (auto sc : storage_class_usage_) {
127       if (ast::IsHostShareable(sc)) {
128         return true;
129       }
130     }
131     return false;
132   }
133 
134   /// Adds the pipeline stage usage to the structure.
135   /// @param usage the storage usage
AddUsage(PipelineStageUsage usage)136   void AddUsage(PipelineStageUsage usage) {
137     pipeline_stage_uses_.emplace(usage);
138   }
139 
140   /// @returns the set of entry point uses of this structure
PipelineStageUses()141   const std::unordered_set<PipelineStageUsage>& PipelineStageUses() const {
142     return pipeline_stage_uses_;
143   }
144 
145   /// @returns true if the struct has a block decoration
IsBlockDecorated()146   bool IsBlockDecorated() const { return declaration_->IsBlockDecorated(); }
147 
148   /// @returns the name for the type
149   std::string type_name() const override;
150 
151   /// @param symbols the program's symbol table
152   /// @returns the name for this type that closely resembles how it would be
153   /// declared in WGSL.
154   std::string FriendlyName(const SymbolTable& symbols) const override;
155 
156   /// @returns true if constructible as per
157   /// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
158   bool IsConstructible() const override;
159 
160  private:
161   uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const;
162 
163   ast::Struct const* const declaration_;
164   const Symbol name_;
165   const StructMemberList members_;
166   const uint32_t align_;
167   const uint32_t size_;
168   const uint32_t size_no_padding_;
169   std::unordered_set<ast::StorageClass> storage_class_usage_;
170   std::unordered_set<PipelineStageUsage> pipeline_stage_uses_;
171   bool constructible_;
172 };
173 
174 /// StructMember holds the semantic information for structure members.
175 class StructMember : public Castable<StructMember, Node> {
176  public:
177   /// Constructor
178   /// @param declaration the AST declaration node
179   /// @param name the name of the structure
180   /// @param type the type of the member
181   /// @param index the index of the member in the structure
182   /// @param offset the byte offset from the base of the structure
183   /// @param align the byte alignment of the member
184   /// @param size the byte size of the member
185   StructMember(const ast::StructMember* declaration,
186                Symbol name,
187                sem::Type* type,
188                uint32_t index,
189                uint32_t offset,
190                uint32_t align,
191                uint32_t size);
192 
193   /// Destructor
194   ~StructMember() override;
195 
196   /// @returns the AST declaration node
Declaration()197   const ast::StructMember* Declaration() const { return declaration_; }
198 
199   /// @returns the name of the structure
Name()200   Symbol Name() const { return name_; }
201 
202   /// @returns the type of the member
Type()203   sem::Type* Type() const { return type_; }
204 
205   /// @returns the member index
Index()206   uint32_t Index() const { return index_; }
207 
208   /// @returns byte offset from base of structure
Offset()209   uint32_t Offset() const { return offset_; }
210 
211   /// @returns the alignment of the member in bytes
Align()212   uint32_t Align() const { return align_; }
213 
214   /// @returns byte size
Size()215   uint32_t Size() const { return size_; }
216 
217  private:
218   const ast::StructMember* const declaration_;
219   const Symbol name_;
220   sem::Type* const type_;
221   const uint32_t index_;
222   const uint32_t offset_;
223   const uint32_t align_;
224   const uint32_t size_;
225 };
226 
227 }  // namespace sem
228 }  // namespace tint
229 
230 #endif  // SRC_SEM_STRUCT_H_
231