• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Dawn 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 "dawn_native/BindingInfo.h"
16 
17 #include "dawn_native/ChainUtils_autogen.h"
18 
19 namespace dawn_native {
20 
AbslFormatConvert(BindingInfoType value,const absl::FormatConversionSpec & spec,absl::FormatSink * s)21     absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
22         BindingInfoType value,
23         const absl::FormatConversionSpec& spec,
24         absl::FormatSink* s) {
25         switch (value) {
26             case BindingInfoType::Buffer:
27                 s->Append("Buffer");
28                 break;
29             case BindingInfoType::Sampler:
30                 s->Append("Sampler");
31                 break;
32             case BindingInfoType::Texture:
33                 s->Append("Texture");
34                 break;
35             case BindingInfoType::StorageTexture:
36                 s->Append("StorageTexture");
37                 break;
38             case BindingInfoType::ExternalTexture:
39                 s->Append("ExternalTexture");
40                 break;
41             default:
42                 UNREACHABLE();
43         }
44         return {true};
45     }
46 
IncrementBindingCounts(BindingCounts * bindingCounts,const BindGroupLayoutEntry & entry)47     void IncrementBindingCounts(BindingCounts* bindingCounts, const BindGroupLayoutEntry& entry) {
48         bindingCounts->totalCount += 1;
49 
50         uint32_t PerStageBindingCounts::*perStageBindingCountMember = nullptr;
51 
52         if (entry.buffer.type != wgpu::BufferBindingType::Undefined) {
53             ++bindingCounts->bufferCount;
54             const BufferBindingLayout& buffer = entry.buffer;
55 
56             if (buffer.minBindingSize == 0) {
57                 ++bindingCounts->unverifiedBufferCount;
58             }
59 
60             switch (buffer.type) {
61                 case wgpu::BufferBindingType::Uniform:
62                     if (buffer.hasDynamicOffset) {
63                         ++bindingCounts->dynamicUniformBufferCount;
64                     }
65                     perStageBindingCountMember = &PerStageBindingCounts::uniformBufferCount;
66                     break;
67 
68                 case wgpu::BufferBindingType::Storage:
69                 case kInternalStorageBufferBinding:
70                 case wgpu::BufferBindingType::ReadOnlyStorage:
71                     if (buffer.hasDynamicOffset) {
72                         ++bindingCounts->dynamicStorageBufferCount;
73                     }
74                     perStageBindingCountMember = &PerStageBindingCounts::storageBufferCount;
75                     break;
76 
77                 case wgpu::BufferBindingType::Undefined:
78                     // Can't get here due to the enclosing if statement.
79                     UNREACHABLE();
80                     break;
81             }
82         } else if (entry.sampler.type != wgpu::SamplerBindingType::Undefined) {
83             perStageBindingCountMember = &PerStageBindingCounts::samplerCount;
84         } else if (entry.texture.sampleType != wgpu::TextureSampleType::Undefined) {
85             perStageBindingCountMember = &PerStageBindingCounts::sampledTextureCount;
86         } else if (entry.storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
87             perStageBindingCountMember = &PerStageBindingCounts::storageTextureCount;
88         } else {
89             const ExternalTextureBindingLayout* externalTextureBindingLayout;
90             FindInChain(entry.nextInChain, &externalTextureBindingLayout);
91             if (externalTextureBindingLayout != nullptr) {
92                 perStageBindingCountMember = &PerStageBindingCounts::externalTextureCount;
93             }
94         }
95 
96         ASSERT(perStageBindingCountMember != nullptr);
97         for (SingleShaderStage stage : IterateStages(entry.visibility)) {
98             ++(bindingCounts->perStage[stage].*perStageBindingCountMember);
99         }
100     }
101 
AccumulateBindingCounts(BindingCounts * bindingCounts,const BindingCounts & rhs)102     void AccumulateBindingCounts(BindingCounts* bindingCounts, const BindingCounts& rhs) {
103         bindingCounts->totalCount += rhs.totalCount;
104         bindingCounts->bufferCount += rhs.bufferCount;
105         bindingCounts->unverifiedBufferCount += rhs.unverifiedBufferCount;
106         bindingCounts->dynamicUniformBufferCount += rhs.dynamicUniformBufferCount;
107         bindingCounts->dynamicStorageBufferCount += rhs.dynamicStorageBufferCount;
108 
109         for (SingleShaderStage stage : IterateStages(kAllStages)) {
110             bindingCounts->perStage[stage].sampledTextureCount +=
111                 rhs.perStage[stage].sampledTextureCount;
112             bindingCounts->perStage[stage].samplerCount += rhs.perStage[stage].samplerCount;
113             bindingCounts->perStage[stage].storageBufferCount +=
114                 rhs.perStage[stage].storageBufferCount;
115             bindingCounts->perStage[stage].storageTextureCount +=
116                 rhs.perStage[stage].storageTextureCount;
117             bindingCounts->perStage[stage].uniformBufferCount +=
118                 rhs.perStage[stage].uniformBufferCount;
119             bindingCounts->perStage[stage].externalTextureCount +=
120                 rhs.perStage[stage].externalTextureCount;
121         }
122     }
123 
ValidateBindingCounts(const BindingCounts & bindingCounts)124     MaybeError ValidateBindingCounts(const BindingCounts& bindingCounts) {
125         DAWN_INVALID_IF(
126             bindingCounts.dynamicUniformBufferCount > kMaxDynamicUniformBuffersPerPipelineLayout,
127             "The number of dynamic uniform buffers (%u) exceeds the maximum per-pipeline-layout "
128             "limit (%u).",
129             bindingCounts.dynamicUniformBufferCount, kMaxDynamicUniformBuffersPerPipelineLayout);
130 
131         DAWN_INVALID_IF(
132             bindingCounts.dynamicStorageBufferCount > kMaxDynamicStorageBuffersPerPipelineLayout,
133             "The number of dynamic storage buffers (%u) exceeds the maximum per-pipeline-layout "
134             "limit (%u).",
135             bindingCounts.dynamicStorageBufferCount, kMaxDynamicStorageBuffersPerPipelineLayout);
136 
137         for (SingleShaderStage stage : IterateStages(kAllStages)) {
138             DAWN_INVALID_IF(
139                 bindingCounts.perStage[stage].sampledTextureCount >
140                     kMaxSampledTexturesPerShaderStage,
141                 "The number of sampled textures (%u) in the %s stage exceeds the maximum "
142                 "per-stage limit (%u).",
143                 bindingCounts.perStage[stage].sampledTextureCount, stage,
144                 kMaxSampledTexturesPerShaderStage);
145 
146             // The per-stage number of external textures is bound by the maximum sampled textures
147             // per stage.
148             DAWN_INVALID_IF(
149                 bindingCounts.perStage[stage].externalTextureCount >
150                     kMaxSampledTexturesPerShaderStage / kSampledTexturesPerExternalTexture,
151                 "The number of external textures (%u) in the %s stage exceeds the maximum "
152                 "per-stage limit (%u).",
153                 bindingCounts.perStage[stage].externalTextureCount, stage,
154                 kMaxSampledTexturesPerShaderStage / kSampledTexturesPerExternalTexture);
155 
156             DAWN_INVALID_IF(
157                 bindingCounts.perStage[stage].sampledTextureCount +
158                         (bindingCounts.perStage[stage].externalTextureCount *
159                          kSampledTexturesPerExternalTexture) >
160                     kMaxSampledTexturesPerShaderStage,
161                 "The combination of sampled textures (%u) and external textures (%u) in the %s "
162                 "stage exceeds the maximum per-stage limit (%u).",
163                 bindingCounts.perStage[stage].sampledTextureCount,
164                 bindingCounts.perStage[stage].externalTextureCount, stage,
165                 kMaxSampledTexturesPerShaderStage);
166 
167             DAWN_INVALID_IF(
168                 bindingCounts.perStage[stage].samplerCount > kMaxSamplersPerShaderStage,
169                 "The number of samplers (%u) in the %s stage exceeds the maximum per-stage limit "
170                 "(%u).",
171                 bindingCounts.perStage[stage].samplerCount, stage, kMaxSamplersPerShaderStage);
172 
173             DAWN_INVALID_IF(
174                 bindingCounts.perStage[stage].samplerCount +
175                         (bindingCounts.perStage[stage].externalTextureCount *
176                          kSamplersPerExternalTexture) >
177                     kMaxSamplersPerShaderStage,
178                 "The combination of samplers (%u) and external textures (%u) in the %s stage "
179                 "exceeds the maximum per-stage limit (%u).",
180                 bindingCounts.perStage[stage].samplerCount,
181                 bindingCounts.perStage[stage].externalTextureCount, stage,
182                 kMaxSamplersPerShaderStage);
183 
184             DAWN_INVALID_IF(
185                 bindingCounts.perStage[stage].storageBufferCount > kMaxStorageBuffersPerShaderStage,
186                 "The number of storage buffers (%u) in the %s stage exceeds the maximum per-stage "
187                 "limit (%u).",
188                 bindingCounts.perStage[stage].storageBufferCount, stage,
189                 kMaxStorageBuffersPerShaderStage);
190 
191             DAWN_INVALID_IF(
192                 bindingCounts.perStage[stage].storageTextureCount >
193                     kMaxStorageTexturesPerShaderStage,
194                 "The number of storage textures (%u) in the %s stage exceeds the maximum per-stage "
195                 "limit (%u).",
196                 bindingCounts.perStage[stage].storageTextureCount, stage,
197                 kMaxStorageTexturesPerShaderStage);
198 
199             DAWN_INVALID_IF(
200                 bindingCounts.perStage[stage].uniformBufferCount > kMaxUniformBuffersPerShaderStage,
201                 "The number of uniform buffers (%u) in the %s stage exceeds the maximum per-stage "
202                 "limit (%u).",
203                 bindingCounts.perStage[stage].uniformBufferCount, stage,
204                 kMaxUniformBuffersPerShaderStage);
205 
206             DAWN_INVALID_IF(
207                 bindingCounts.perStage[stage].uniformBufferCount +
208                         (bindingCounts.perStage[stage].externalTextureCount *
209                          kUniformsPerExternalTexture) >
210                     kMaxUniformBuffersPerShaderStage,
211                 "The combination of uniform buffers (%u) and external textures (%u) in the %s "
212                 "stage exceeds the maximum per-stage limit (%u).",
213                 bindingCounts.perStage[stage].uniformBufferCount,
214                 bindingCounts.perStage[stage].externalTextureCount, stage,
215                 kMaxUniformBuffersPerShaderStage);
216         }
217 
218         return {};
219     }
220 
221 }  // namespace dawn_native
222