• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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/Format.h"
16 
17 #include "dawn_native/Device.h"
18 #include "dawn_native/EnumMaskIterator.h"
19 #include "dawn_native/Features.h"
20 #include "dawn_native/Texture.h"
21 
22 #include <bitset>
23 
24 namespace dawn_native {
25 
26     // Format
27 
28     // TODO(dawn:527): Remove when unused.
ToSampleTypeBit(wgpu::TextureComponentType type)29     SampleTypeBit ToSampleTypeBit(wgpu::TextureComponentType type) {
30         switch (type) {
31             case wgpu::TextureComponentType::Float:
32                 return SampleTypeBit::Float;
33             case wgpu::TextureComponentType::Sint:
34                 return SampleTypeBit::Sint;
35             case wgpu::TextureComponentType::Uint:
36                 return SampleTypeBit::Uint;
37             case wgpu::TextureComponentType::DepthComparison:
38                 return SampleTypeBit::Depth;
39         }
40         UNREACHABLE();
41     }
42 
SampleTypeToSampleTypeBit(wgpu::TextureSampleType sampleType)43     SampleTypeBit SampleTypeToSampleTypeBit(wgpu::TextureSampleType sampleType) {
44         switch (sampleType) {
45             case wgpu::TextureSampleType::Float:
46             case wgpu::TextureSampleType::UnfilterableFloat:
47             case wgpu::TextureSampleType::Sint:
48             case wgpu::TextureSampleType::Uint:
49             case wgpu::TextureSampleType::Depth:
50             case wgpu::TextureSampleType::Undefined:
51                 // When the compiler complains that you need to add a case statement here, please
52                 // also add a corresponding static assert below!
53                 break;
54         }
55 
56         static_assert(static_cast<uint32_t>(wgpu::TextureSampleType::Undefined) == 0, "");
57         if (sampleType == wgpu::TextureSampleType::Undefined) {
58             return SampleTypeBit::None;
59         }
60 
61         // Check that SampleTypeBit bits are in the same position / order as the respective
62         // wgpu::TextureSampleType value.
63         static_assert(SampleTypeBit::Float ==
64                           static_cast<SampleTypeBit>(
65                               1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Float) - 1)),
66                       "");
67         static_assert(
68             SampleTypeBit::UnfilterableFloat ==
69                 static_cast<SampleTypeBit>(
70                     1 << (static_cast<uint32_t>(wgpu::TextureSampleType::UnfilterableFloat) - 1)),
71             "");
72         static_assert(SampleTypeBit::Uint ==
73                           static_cast<SampleTypeBit>(
74                               1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Uint) - 1)),
75                       "");
76         static_assert(SampleTypeBit::Sint ==
77                           static_cast<SampleTypeBit>(
78                               1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Sint) - 1)),
79                       "");
80         static_assert(SampleTypeBit::Depth ==
81                           static_cast<SampleTypeBit>(
82                               1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Depth) - 1)),
83                       "");
84         return static_cast<SampleTypeBit>(1 << (static_cast<uint32_t>(sampleType) - 1));
85     }
86 
IsColor() const87     bool Format::IsColor() const {
88         return aspects == Aspect::Color;
89     }
90 
HasDepth() const91     bool Format::HasDepth() const {
92         return (aspects & Aspect::Depth) != 0;
93     }
94 
HasStencil() const95     bool Format::HasStencil() const {
96         return (aspects & Aspect::Stencil) != 0;
97     }
98 
HasDepthOrStencil() const99     bool Format::HasDepthOrStencil() const {
100         return (aspects & (Aspect::Depth | Aspect::Stencil)) != 0;
101     }
102 
IsMultiPlanar() const103     bool Format::IsMultiPlanar() const {
104         return (aspects & (Aspect::Plane0 | Aspect::Plane1)) != 0;
105     }
106 
GetAspectInfo(wgpu::TextureAspect aspect) const107     const AspectInfo& Format::GetAspectInfo(wgpu::TextureAspect aspect) const {
108         return GetAspectInfo(SelectFormatAspects(*this, aspect));
109     }
110 
GetAspectInfo(Aspect aspect) const111     const AspectInfo& Format::GetAspectInfo(Aspect aspect) const {
112         ASSERT(HasOneBit(aspect));
113         ASSERT(aspects & aspect);
114         const size_t aspectIndex = GetAspectIndex(aspect);
115         ASSERT(aspectIndex < GetAspectCount(aspects));
116         return aspectInfo[aspectIndex];
117     }
118 
GetIndex() const119     size_t Format::GetIndex() const {
120         return ComputeFormatIndex(format);
121     }
122 
123     // Implementation details of the format table of the DeviceBase
124 
125     // For the enum for formats are packed but this might change when we have a broader feature
126     // mechanism for webgpu.h. Formats start at 1 because 0 is the undefined format.
ComputeFormatIndex(wgpu::TextureFormat format)127     size_t ComputeFormatIndex(wgpu::TextureFormat format) {
128         // This takes advantage of overflows to make the index of TextureFormat::Undefined outside
129         // of the range of the FormatTable.
130         static_assert(static_cast<uint32_t>(wgpu::TextureFormat::Undefined) - 1 > kKnownFormatCount,
131                       "");
132         return static_cast<size_t>(static_cast<uint32_t>(format) - 1);
133     }
134 
BuildFormatTable(const DeviceBase * device)135     FormatTable BuildFormatTable(const DeviceBase* device) {
136         FormatTable table;
137         std::bitset<kKnownFormatCount> formatsSet;
138 
139         static constexpr SampleTypeBit kAnyFloat =
140             SampleTypeBit::Float | SampleTypeBit::UnfilterableFloat;
141 
142         auto AddFormat = [&table, &formatsSet](Format format) {
143             size_t index = ComputeFormatIndex(format.format);
144             ASSERT(index < table.size());
145 
146             // This checks that each format is set at most once, the first part of checking that all
147             // formats are set exactly once.
148             ASSERT(!formatsSet[index]);
149 
150             // Vulkan describes bytesPerRow in units of texels. If there's any format for which this
151             // ASSERT isn't true, then additional validation on bytesPerRow must be added.
152             const bool hasMultipleAspects = !HasOneBit(format.aspects);
153             ASSERT(hasMultipleAspects ||
154                    (kTextureBytesPerRowAlignment % format.aspectInfo[0].block.byteSize) == 0);
155 
156             table[index] = format;
157             formatsSet.set(index);
158         };
159 
160         auto AddColorFormat = [&AddFormat](wgpu::TextureFormat format, bool renderable,
161                                            bool supportsStorageUsage, uint32_t byteSize,
162                                            SampleTypeBit sampleTypes, uint8_t componentCount) {
163             Format internalFormat;
164             internalFormat.format = format;
165             internalFormat.isRenderable = renderable;
166             internalFormat.isCompressed = false;
167             internalFormat.isSupported = true;
168             internalFormat.supportsStorageUsage = supportsStorageUsage;
169             internalFormat.aspects = Aspect::Color;
170             internalFormat.componentCount = componentCount;
171             AspectInfo* firstAspect = internalFormat.aspectInfo.data();
172             firstAspect->block.byteSize = byteSize;
173             firstAspect->block.width = 1;
174             firstAspect->block.height = 1;
175             if (HasOneBit(sampleTypes)) {
176                 switch (sampleTypes) {
177                     case SampleTypeBit::Float:
178                     case SampleTypeBit::UnfilterableFloat:
179                         firstAspect->baseType = wgpu::TextureComponentType::Float;
180                         break;
181                     case SampleTypeBit::Sint:
182                         firstAspect->baseType = wgpu::TextureComponentType::Sint;
183                         break;
184                     case SampleTypeBit::Uint:
185                         firstAspect->baseType = wgpu::TextureComponentType::Uint;
186                         break;
187                     default:
188                         UNREACHABLE();
189                 }
190             } else {
191                 ASSERT((sampleTypes & SampleTypeBit::Float) != 0);
192                 firstAspect->baseType = wgpu::TextureComponentType::Float;
193             }
194             firstAspect->supportedSampleTypes = sampleTypes;
195             firstAspect->format = format;
196             AddFormat(internalFormat);
197         };
198 
199         auto AddDepthFormat = [&AddFormat](wgpu::TextureFormat format, uint32_t byteSize,
200                                            bool isSupported) {
201             Format internalFormat;
202             internalFormat.format = format;
203             internalFormat.isRenderable = true;
204             internalFormat.isCompressed = false;
205             internalFormat.isSupported = isSupported;
206             internalFormat.supportsStorageUsage = false;
207             internalFormat.aspects = Aspect::Depth;
208             internalFormat.componentCount = 1;
209             AspectInfo* firstAspect = internalFormat.aspectInfo.data();
210             firstAspect->block.byteSize = byteSize;
211             firstAspect->block.width = 1;
212             firstAspect->block.height = 1;
213             firstAspect->baseType = wgpu::TextureComponentType::Float;
214             firstAspect->supportedSampleTypes = SampleTypeBit::Depth;
215             firstAspect->format = format;
216             AddFormat(internalFormat);
217         };
218 
219         auto AddStencilFormat = [&AddFormat](wgpu::TextureFormat format, bool isSupported) {
220             Format internalFormat;
221             internalFormat.format = format;
222             internalFormat.isRenderable = true;
223             internalFormat.isCompressed = false;
224             internalFormat.isSupported = isSupported;
225             internalFormat.supportsStorageUsage = false;
226             internalFormat.aspects = Aspect::Stencil;
227             internalFormat.componentCount = 1;
228             AspectInfo* firstAspect = internalFormat.aspectInfo.data();
229             firstAspect->block.byteSize = 1;
230             firstAspect->block.width = 1;
231             firstAspect->block.height = 1;
232             firstAspect->baseType = wgpu::TextureComponentType::Uint;
233             firstAspect->supportedSampleTypes = SampleTypeBit::Uint;
234             firstAspect->format = format;
235             AddFormat(internalFormat);
236         };
237 
238         auto AddCompressedFormat = [&AddFormat](wgpu::TextureFormat format, uint32_t byteSize,
239                                                 uint32_t width, uint32_t height, bool isSupported,
240                                                 uint8_t componentCount) {
241             Format internalFormat;
242             internalFormat.format = format;
243             internalFormat.isRenderable = false;
244             internalFormat.isCompressed = true;
245             internalFormat.isSupported = isSupported;
246             internalFormat.supportsStorageUsage = false;
247             internalFormat.aspects = Aspect::Color;
248             internalFormat.componentCount = componentCount;
249             AspectInfo* firstAspect = internalFormat.aspectInfo.data();
250             firstAspect->block.byteSize = byteSize;
251             firstAspect->block.width = width;
252             firstAspect->block.height = height;
253             firstAspect->baseType = wgpu::TextureComponentType::Float;
254             firstAspect->supportedSampleTypes = kAnyFloat;
255             firstAspect->format = format;
256             AddFormat(internalFormat);
257         };
258 
259         auto AddMultiAspectFormat =
260             [&AddFormat, &table](wgpu::TextureFormat format, Aspect aspects,
261                                  wgpu::TextureFormat firstFormat, wgpu::TextureFormat secondFormat,
262                                  bool isRenderable, bool isSupported, uint8_t componentCount) {
263                 Format internalFormat;
264                 internalFormat.format = format;
265                 internalFormat.isRenderable = isRenderable;
266                 internalFormat.isCompressed = false;
267                 internalFormat.isSupported = isSupported;
268                 internalFormat.supportsStorageUsage = false;
269                 internalFormat.aspects = aspects;
270                 internalFormat.componentCount = componentCount;
271                 const size_t firstFormatIndex = ComputeFormatIndex(firstFormat);
272                 const size_t secondFormatIndex = ComputeFormatIndex(secondFormat);
273 
274                 internalFormat.aspectInfo[0] = table[firstFormatIndex].aspectInfo[0];
275                 internalFormat.aspectInfo[1] = table[secondFormatIndex].aspectInfo[0];
276 
277                 AddFormat(internalFormat);
278             };
279 
280         // clang-format off
281         // 1 byte color formats
282         AddColorFormat(wgpu::TextureFormat::R8Unorm, true, false, 1, kAnyFloat, 1);
283         AddColorFormat(wgpu::TextureFormat::R8Snorm, false, false, 1, kAnyFloat, 1);
284         AddColorFormat(wgpu::TextureFormat::R8Uint, true, false, 1, SampleTypeBit::Uint, 1);
285         AddColorFormat(wgpu::TextureFormat::R8Sint, true, false, 1, SampleTypeBit::Sint, 1);
286 
287         // 2 bytes color formats
288         AddColorFormat(wgpu::TextureFormat::R16Uint, true, false, 2, SampleTypeBit::Uint, 1);
289         AddColorFormat(wgpu::TextureFormat::R16Sint, true, false, 2, SampleTypeBit::Sint, 1);
290         AddColorFormat(wgpu::TextureFormat::R16Float, true, false, 2, kAnyFloat, 1);
291         AddColorFormat(wgpu::TextureFormat::RG8Unorm, true, false, 2, kAnyFloat, 2);
292         AddColorFormat(wgpu::TextureFormat::RG8Snorm, false, false, 2, kAnyFloat, 2);
293         AddColorFormat(wgpu::TextureFormat::RG8Uint, true, false, 2, SampleTypeBit::Uint, 2);
294         AddColorFormat(wgpu::TextureFormat::RG8Sint, true, false, 2, SampleTypeBit::Sint, 2);
295 
296         // 4 bytes color formats
297         AddColorFormat(wgpu::TextureFormat::R32Uint, true, true, 4, SampleTypeBit::Uint, 1);
298         AddColorFormat(wgpu::TextureFormat::R32Sint, true, true, 4, SampleTypeBit::Sint, 1);
299         AddColorFormat(wgpu::TextureFormat::R32Float, true, true, 4, SampleTypeBit::UnfilterableFloat, 1);
300         AddColorFormat(wgpu::TextureFormat::RG16Uint, true, false, 4, SampleTypeBit::Uint, 2);
301         AddColorFormat(wgpu::TextureFormat::RG16Sint, true, false, 4, SampleTypeBit::Sint, 2);
302         AddColorFormat(wgpu::TextureFormat::RG16Float, true, false, 4, kAnyFloat, 2);
303         AddColorFormat(wgpu::TextureFormat::RGBA8Unorm, true, true, 4, kAnyFloat, 4);
304         AddColorFormat(wgpu::TextureFormat::RGBA8UnormSrgb, true, false, 4, kAnyFloat, 4);
305         AddColorFormat(wgpu::TextureFormat::RGBA8Snorm, false, true, 4, kAnyFloat, 4);
306         AddColorFormat(wgpu::TextureFormat::RGBA8Uint, true, true, 4, SampleTypeBit::Uint, 4);
307         AddColorFormat(wgpu::TextureFormat::RGBA8Sint, true, true, 4, SampleTypeBit::Sint, 4);
308         AddColorFormat(wgpu::TextureFormat::BGRA8Unorm, true, false, 4, kAnyFloat, 4);
309         AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, 4, kAnyFloat, 4);
310         AddColorFormat(wgpu::TextureFormat::RGB10A2Unorm, true, false, 4, kAnyFloat, 4);
311 
312         AddColorFormat(wgpu::TextureFormat::RG11B10Ufloat, false, false, 4, kAnyFloat, 3);
313         AddColorFormat(wgpu::TextureFormat::RGB9E5Ufloat, false, false, 4, kAnyFloat, 3);
314 
315         // 8 bytes color formats
316         AddColorFormat(wgpu::TextureFormat::RG32Uint, true, true, 8, SampleTypeBit::Uint, 2);
317         AddColorFormat(wgpu::TextureFormat::RG32Sint, true, true, 8, SampleTypeBit::Sint, 2);
318         AddColorFormat(wgpu::TextureFormat::RG32Float, true, true, 8, SampleTypeBit::UnfilterableFloat, 2);
319         AddColorFormat(wgpu::TextureFormat::RGBA16Uint, true, true, 8, SampleTypeBit::Uint, 4);
320         AddColorFormat(wgpu::TextureFormat::RGBA16Sint, true, true, 8, SampleTypeBit::Sint, 4);
321         AddColorFormat(wgpu::TextureFormat::RGBA16Float, true, true, 8, kAnyFloat, 4);
322 
323         // 16 bytes color formats
324         AddColorFormat(wgpu::TextureFormat::RGBA32Uint, true, true, 16, SampleTypeBit::Uint, 4);
325         AddColorFormat(wgpu::TextureFormat::RGBA32Sint, true, true, 16, SampleTypeBit::Sint, 4);
326         AddColorFormat(wgpu::TextureFormat::RGBA32Float, true, true, 16, SampleTypeBit::UnfilterableFloat, 4);
327 
328         // Depth-stencil formats
329         // TODO(dawn:666): Implement the stencil8 format
330         AddStencilFormat(wgpu::TextureFormat::Stencil8, false);
331         AddDepthFormat(wgpu::TextureFormat::Depth16Unorm, 2, true);
332         // TODO(crbug.com/dawn/843): This is 4 because we read this to perform zero initialization,
333         // and textures are always use depth32float. We should improve this to be more robust. Perhaps,
334         // using 0 here to mean "unsized" and adding a backend-specific query for the block size.
335         AddDepthFormat(wgpu::TextureFormat::Depth24Plus, 4, true);
336         AddMultiAspectFormat(wgpu::TextureFormat::Depth24PlusStencil8,
337                               Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, true, 2);
338         bool isD24S8Supported = device->IsFeatureEnabled(Feature::Depth24UnormStencil8);
339         AddMultiAspectFormat(wgpu::TextureFormat::Depth24UnormStencil8,
340                               Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, isD24S8Supported, 2);
341         AddDepthFormat(wgpu::TextureFormat::Depth32Float, 4, true);
342         bool isD32S8Supported = device->IsFeatureEnabled(Feature::Depth32FloatStencil8);
343         AddMultiAspectFormat(wgpu::TextureFormat::Depth32FloatStencil8,
344                               Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Stencil8, true, isD32S8Supported, 2);
345 
346         // BC compressed formats
347         bool isBCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionBC);
348         AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnorm, 8, 4, 4, isBCFormatSupported, 4);
349         AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, 8, 4, 4, isBCFormatSupported, 4);
350         AddCompressedFormat(wgpu::TextureFormat::BC4RSnorm, 8, 4, 4, isBCFormatSupported, 1);
351         AddCompressedFormat(wgpu::TextureFormat::BC4RUnorm, 8, 4, 4, isBCFormatSupported, 1);
352         AddCompressedFormat(wgpu::TextureFormat::BC2RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
353         AddCompressedFormat(wgpu::TextureFormat::BC2RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4);
354         AddCompressedFormat(wgpu::TextureFormat::BC3RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
355         AddCompressedFormat(wgpu::TextureFormat::BC3RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4);
356         AddCompressedFormat(wgpu::TextureFormat::BC5RGSnorm, 16, 4, 4, isBCFormatSupported, 2);
357         AddCompressedFormat(wgpu::TextureFormat::BC5RGUnorm, 16, 4, 4, isBCFormatSupported, 2);
358         AddCompressedFormat(wgpu::TextureFormat::BC6HRGBFloat, 16, 4, 4, isBCFormatSupported, 3);
359         AddCompressedFormat(wgpu::TextureFormat::BC6HRGBUfloat, 16, 4, 4, isBCFormatSupported, 3);
360         AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
361         AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4);
362 
363         // ETC2/EAC compressed formats
364         bool isETC2FormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionETC2);
365         AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8Unorm, 8, 4, 4, isETC2FormatSupported, 3);
366         AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, 8, 4, 4, isETC2FormatSupported, 3);
367         AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1Unorm, 8, 4, 4, isETC2FormatSupported, 4);
368         AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1UnormSrgb, 8, 4, 4, isETC2FormatSupported, 4);
369         AddCompressedFormat(wgpu::TextureFormat::ETC2RGBA8Unorm, 16, 4, 4, isETC2FormatSupported, 4);
370         AddCompressedFormat(wgpu::TextureFormat::ETC2RGBA8UnormSrgb, 16, 4, 4, isETC2FormatSupported, 4);
371         AddCompressedFormat(wgpu::TextureFormat::EACR11Unorm, 8, 4, 4, isETC2FormatSupported, 1);
372         AddCompressedFormat(wgpu::TextureFormat::EACR11Snorm, 8, 4, 4, isETC2FormatSupported, 1);
373         AddCompressedFormat(wgpu::TextureFormat::EACRG11Unorm, 16, 4, 4, isETC2FormatSupported, 2);
374         AddCompressedFormat(wgpu::TextureFormat::EACRG11Snorm, 16, 4, 4, isETC2FormatSupported, 2);
375 
376         // ASTC compressed formats
377         bool isASTCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionASTC);
378         AddCompressedFormat(wgpu::TextureFormat::ASTC4x4Unorm, 16, 4, 4, isASTCFormatSupported, 4);
379         AddCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, 16, 4, 4, isASTCFormatSupported, 4);
380         AddCompressedFormat(wgpu::TextureFormat::ASTC5x4Unorm, 16, 5, 4, isASTCFormatSupported, 4);
381         AddCompressedFormat(wgpu::TextureFormat::ASTC5x4UnormSrgb, 16, 5, 4, isASTCFormatSupported, 4);
382         AddCompressedFormat(wgpu::TextureFormat::ASTC5x5Unorm, 16, 5, 5, isASTCFormatSupported, 4);
383         AddCompressedFormat(wgpu::TextureFormat::ASTC5x5UnormSrgb, 16, 5, 5, isASTCFormatSupported, 4);
384         AddCompressedFormat(wgpu::TextureFormat::ASTC6x5Unorm, 16, 6, 5, isASTCFormatSupported, 4);
385         AddCompressedFormat(wgpu::TextureFormat::ASTC6x5UnormSrgb, 16, 6, 5, isASTCFormatSupported, 4);
386         AddCompressedFormat(wgpu::TextureFormat::ASTC6x6Unorm, 16, 6, 6, isASTCFormatSupported, 4);
387         AddCompressedFormat(wgpu::TextureFormat::ASTC6x6UnormSrgb, 16, 6, 6, isASTCFormatSupported, 4);
388         AddCompressedFormat(wgpu::TextureFormat::ASTC8x5Unorm, 16, 8, 5, isASTCFormatSupported, 4);
389         AddCompressedFormat(wgpu::TextureFormat::ASTC8x5UnormSrgb, 16, 8, 5, isASTCFormatSupported, 4);
390         AddCompressedFormat(wgpu::TextureFormat::ASTC8x6Unorm, 16, 8, 6, isASTCFormatSupported, 4);
391         AddCompressedFormat(wgpu::TextureFormat::ASTC8x6UnormSrgb, 16, 8, 6, isASTCFormatSupported, 4);
392         AddCompressedFormat(wgpu::TextureFormat::ASTC8x8Unorm, 16, 8, 8, isASTCFormatSupported, 4);
393         AddCompressedFormat(wgpu::TextureFormat::ASTC8x8UnormSrgb, 16, 8, 8, isASTCFormatSupported, 4);
394         AddCompressedFormat(wgpu::TextureFormat::ASTC10x5Unorm, 16, 10, 5, isASTCFormatSupported, 4);
395         AddCompressedFormat(wgpu::TextureFormat::ASTC10x5UnormSrgb, 16, 10, 5, isASTCFormatSupported, 4);
396         AddCompressedFormat(wgpu::TextureFormat::ASTC10x6Unorm, 16, 10, 6, isASTCFormatSupported, 4);
397         AddCompressedFormat(wgpu::TextureFormat::ASTC10x6UnormSrgb, 16, 10, 6, isASTCFormatSupported, 4);
398         AddCompressedFormat(wgpu::TextureFormat::ASTC10x8Unorm, 16, 10, 8, isASTCFormatSupported, 4);
399         AddCompressedFormat(wgpu::TextureFormat::ASTC10x8UnormSrgb, 16, 10, 8, isASTCFormatSupported, 4);
400         AddCompressedFormat(wgpu::TextureFormat::ASTC10x10Unorm, 16, 10, 10, isASTCFormatSupported, 4);
401         AddCompressedFormat(wgpu::TextureFormat::ASTC10x10UnormSrgb, 16, 10, 10, isASTCFormatSupported, 4);
402         AddCompressedFormat(wgpu::TextureFormat::ASTC12x10Unorm, 16, 12, 10, isASTCFormatSupported, 4);
403         AddCompressedFormat(wgpu::TextureFormat::ASTC12x10UnormSrgb, 16, 12, 10, isASTCFormatSupported, 4);
404         AddCompressedFormat(wgpu::TextureFormat::ASTC12x12Unorm, 16, 12, 12, isASTCFormatSupported, 4);
405         AddCompressedFormat(wgpu::TextureFormat::ASTC12x12UnormSrgb, 16, 12, 12, isASTCFormatSupported, 4);
406 
407         // multi-planar formats
408         const bool isMultiPlanarFormatSupported = device->IsFeatureEnabled(Feature::MultiPlanarFormats);
409         AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar420Unorm, Aspect::Plane0 | Aspect::Plane1,
410             wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, false, isMultiPlanarFormatSupported, 3);
411 
412         // clang-format on
413 
414         // This checks that each format is set at least once, the second part of checking that all
415         // formats are checked exactly once.
416         ASSERT(formatsSet.all());
417 
418         return table;
419     }
420 
421 }  // namespace dawn_native
422