• 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 #include "src/sem/function.h"
16 
17 #include "src/ast/function.h"
18 #include "src/sem/depth_texture_type.h"
19 #include "src/sem/external_texture_type.h"
20 #include "src/sem/multisampled_texture_type.h"
21 #include "src/sem/sampled_texture_type.h"
22 #include "src/sem/storage_texture_type.h"
23 #include "src/sem/variable.h"
24 #include "src/utils/to_const_ptr_vec.h"
25 
26 TINT_INSTANTIATE_TYPEINFO(tint::sem::Function);
27 
28 namespace tint {
29 namespace sem {
30 
Function(const ast::Function * declaration,Type * return_type,std::vector<Parameter * > parameters)31 Function::Function(const ast::Function* declaration,
32                    Type* return_type,
33                    std::vector<Parameter*> parameters)
34     : Base(return_type, utils::ToConstPtrVec(parameters)),
35       declaration_(declaration),
36       workgroup_size_{WorkgroupDimension{1}, WorkgroupDimension{1},
37                       WorkgroupDimension{1}} {
38   for (auto* parameter : parameters) {
39     parameter->SetOwner(this);
40   }
41 }  // namespace sem
42 
43 Function::~Function() = default;
44 
45 std::vector<std::pair<const Variable*, const ast::LocationDecoration*>>
TransitivelyReferencedLocationVariables() const46 Function::TransitivelyReferencedLocationVariables() const {
47   std::vector<std::pair<const Variable*, const ast::LocationDecoration*>> ret;
48 
49   for (auto* var : TransitivelyReferencedGlobals()) {
50     for (auto* deco : var->Declaration()->decorations) {
51       if (auto* location = deco->As<ast::LocationDecoration>()) {
52         ret.push_back({var, location});
53         break;
54       }
55     }
56   }
57   return ret;
58 }
59 
TransitivelyReferencedUniformVariables() const60 Function::VariableBindings Function::TransitivelyReferencedUniformVariables()
61     const {
62   VariableBindings ret;
63 
64   for (auto* var : TransitivelyReferencedGlobals()) {
65     if (var->StorageClass() != ast::StorageClass::kUniform) {
66       continue;
67     }
68 
69     if (auto binding_point = var->Declaration()->BindingPoint()) {
70       ret.push_back({var, binding_point});
71     }
72   }
73   return ret;
74 }
75 
76 Function::VariableBindings
TransitivelyReferencedStorageBufferVariables() const77 Function::TransitivelyReferencedStorageBufferVariables() const {
78   VariableBindings ret;
79 
80   for (auto* var : TransitivelyReferencedGlobals()) {
81     if (var->StorageClass() != ast::StorageClass::kStorage) {
82       continue;
83     }
84 
85     if (auto binding_point = var->Declaration()->BindingPoint()) {
86       ret.push_back({var, binding_point});
87     }
88   }
89   return ret;
90 }
91 
92 std::vector<std::pair<const Variable*, const ast::BuiltinDecoration*>>
TransitivelyReferencedBuiltinVariables() const93 Function::TransitivelyReferencedBuiltinVariables() const {
94   std::vector<std::pair<const Variable*, const ast::BuiltinDecoration*>> ret;
95 
96   for (auto* var : TransitivelyReferencedGlobals()) {
97     for (auto* deco : var->Declaration()->decorations) {
98       if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
99         ret.push_back({var, builtin});
100         break;
101       }
102     }
103   }
104   return ret;
105 }
106 
TransitivelyReferencedSamplerVariables() const107 Function::VariableBindings Function::TransitivelyReferencedSamplerVariables()
108     const {
109   return TransitivelyReferencedSamplerVariablesImpl(ast::SamplerKind::kSampler);
110 }
111 
112 Function::VariableBindings
TransitivelyReferencedComparisonSamplerVariables() const113 Function::TransitivelyReferencedComparisonSamplerVariables() const {
114   return TransitivelyReferencedSamplerVariablesImpl(
115       ast::SamplerKind::kComparisonSampler);
116 }
117 
118 Function::VariableBindings
TransitivelyReferencedSampledTextureVariables() const119 Function::TransitivelyReferencedSampledTextureVariables() const {
120   return TransitivelyReferencedSampledTextureVariablesImpl(false);
121 }
122 
123 Function::VariableBindings
TransitivelyReferencedMultisampledTextureVariables() const124 Function::TransitivelyReferencedMultisampledTextureVariables() const {
125   return TransitivelyReferencedSampledTextureVariablesImpl(true);
126 }
127 
TransitivelyReferencedVariablesOfType(const tint::TypeInfo & type_info) const128 Function::VariableBindings Function::TransitivelyReferencedVariablesOfType(
129     const tint::TypeInfo& type_info) const {
130   VariableBindings ret;
131   for (auto* var : TransitivelyReferencedGlobals()) {
132     auto* unwrapped_type = var->Type()->UnwrapRef();
133     if (unwrapped_type->TypeInfo().Is(type_info)) {
134       if (auto binding_point = var->Declaration()->BindingPoint()) {
135         ret.push_back({var, binding_point});
136       }
137     }
138   }
139   return ret;
140 }
141 
HasAncestorEntryPoint(Symbol symbol) const142 bool Function::HasAncestorEntryPoint(Symbol symbol) const {
143   for (const auto* point : ancestor_entry_points_) {
144     if (point->Declaration()->symbol == symbol) {
145       return true;
146     }
147   }
148   return false;
149 }
150 
TransitivelyReferencedSamplerVariablesImpl(ast::SamplerKind kind) const151 Function::VariableBindings Function::TransitivelyReferencedSamplerVariablesImpl(
152     ast::SamplerKind kind) const {
153   VariableBindings ret;
154 
155   for (auto* var : TransitivelyReferencedGlobals()) {
156     auto* unwrapped_type = var->Type()->UnwrapRef();
157     auto* sampler = unwrapped_type->As<sem::Sampler>();
158     if (sampler == nullptr || sampler->kind() != kind) {
159       continue;
160     }
161 
162     if (auto binding_point = var->Declaration()->BindingPoint()) {
163       ret.push_back({var, binding_point});
164     }
165   }
166   return ret;
167 }
168 
169 Function::VariableBindings
TransitivelyReferencedSampledTextureVariablesImpl(bool multisampled) const170 Function::TransitivelyReferencedSampledTextureVariablesImpl(
171     bool multisampled) const {
172   VariableBindings ret;
173 
174   for (auto* var : TransitivelyReferencedGlobals()) {
175     auto* unwrapped_type = var->Type()->UnwrapRef();
176     auto* texture = unwrapped_type->As<sem::Texture>();
177     if (texture == nullptr) {
178       continue;
179     }
180 
181     auto is_multisampled = texture->Is<sem::MultisampledTexture>();
182     auto is_sampled = texture->Is<sem::SampledTexture>();
183 
184     if ((multisampled && !is_multisampled) || (!multisampled && !is_sampled)) {
185       continue;
186     }
187 
188     if (auto binding_point = var->Declaration()->BindingPoint()) {
189       ret.push_back({var, binding_point});
190     }
191   }
192 
193   return ret;
194 }
195 
196 }  // namespace sem
197 }  // namespace tint
198