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