Use an internal version of StorageTextureBindingLayout.

Bug: TBD
Change-Id: Ice2ebfd68b06f27acf863d9c7830ecc0e9f5cb3e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/182921
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/generator/templates/dawn/native/api_absl_format.cpp b/generator/templates/dawn/native/api_absl_format.cpp
index d488d8b..13c2b1c 100644
--- a/generator/templates/dawn/native/api_absl_format.cpp
+++ b/generator/templates/dawn/native/api_absl_format.cpp
@@ -80,7 +80,6 @@
         {% if type.name.get() in [
              "sampler binding layout",
              "texture binding layout",
-             "storage texture binding layout"
            ]
         %}
         absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
diff --git a/generator/templates/dawn/native/api_absl_format.h b/generator/templates/dawn/native/api_absl_format.h
index 00c8ed8..6e5294d 100644
--- a/generator/templates/dawn/native/api_absl_format.h
+++ b/generator/templates/dawn/native/api_absl_format.h
@@ -70,7 +70,6 @@
         {% if type.name.get() in [
              "sampler binding layout",
              "texture binding layout",
-             "storage texture binding layout"
            ]
         %}
         absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp
index a122b86..1c1fcaf 100644
--- a/src/dawn/native/BindGroup.cpp
+++ b/src/dawn/native/BindGroup.cpp
@@ -198,7 +198,7 @@
 
 MaybeError ValidateStorageTextureBinding(DeviceBase* device,
                                          const BindGroupEntry& entry,
-                                         const StorageTextureBindingLayout& layout,
+                                         const StorageTextureBindingInfo& layout,
                                          UsageValidationMode mode) {
     DAWN_TRY(ValidateTextureBindGroupEntry(device, entry));
 
@@ -382,7 +382,7 @@
                                  i, layout);
                 return {};
             },
-            [&](const StorageTextureBindingLayout& layout) -> MaybeError {
+            [&](const StorageTextureBindingInfo& layout) -> MaybeError {
                 DAWN_TRY_CONTEXT(ValidateStorageTextureBinding(device, entry, layout, mode),
                                  "validating entries[%u] as a Storage Texture."
                                  "\nExpected entry layout: %s",
@@ -591,7 +591,7 @@
     DAWN_ASSERT(bindingIndex < layout->GetBindingCount());
     DAWN_ASSERT(std::holds_alternative<TextureBindingLayout>(
                     layout->GetBindingInfo(bindingIndex).bindingLayout) ||
-                std::holds_alternative<StorageTextureBindingLayout>(
+                std::holds_alternative<StorageTextureBindingInfo>(
                     layout->GetBindingInfo(bindingIndex).bindingLayout));
     return static_cast<TextureViewBase*>(mBindingData.bindings[bindingIndex].Get());
 }
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index d16f911..35379a1 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -367,9 +367,9 @@
                    layoutA.viewDimension != layoutB.viewDimension ||
                    layoutA.multisampled != layoutB.multisampled;
         },
-        [&](const StorageTextureBindingLayout& layoutA) -> bool {
-            const StorageTextureBindingLayout& layoutB =
-                std::get<StorageTextureBindingLayout>(b.bindingLayout);
+        [&](const StorageTextureBindingInfo& layoutA) -> bool {
+            const StorageTextureBindingInfo& layoutB =
+                std::get<StorageTextureBindingInfo>(b.bindingLayout);
             return layoutA.access != layoutB.access ||
                    layoutA.viewDimension != layoutB.viewDimension ||
                    layoutA.format != layoutB.format;
@@ -408,7 +408,7 @@
         if (binding->storageTexture.viewDimension == wgpu::TextureViewDimension::Undefined) {
             bindingLayout.viewDimension = wgpu::TextureViewDimension::e2D;
         }
-        bindingInfo.bindingLayout = bindingLayout;
+        bindingInfo.bindingLayout = StorageTextureBindingInfo(bindingLayout);
     } else if (auto* staticSamplerBindingLayout = binding.Get<StaticSamplerBindingLayout>()) {
         StaticSamplerHolderBindingLayout bindingLayout;
         bindingLayout.sampler = staticSamplerBindingLayout->sampler;
@@ -498,8 +498,8 @@
             break;
         }
         case BindingInfoType::StorageTexture: {
-            const auto& aLayout = std::get<StorageTextureBindingLayout>(aInfo.bindingLayout);
-            const auto& bLayout = std::get<StorageTextureBindingLayout>(bInfo.bindingLayout);
+            const auto& aLayout = std::get<StorageTextureBindingInfo>(aInfo.bindingLayout);
+            const auto& bLayout = std::get<StorageTextureBindingInfo>(bInfo.bindingLayout);
             if (aLayout.access != bLayout.access) {
                 return aLayout.access < bLayout.access;
             }
@@ -644,7 +644,7 @@
                 recorder.Record(BindingInfoType::Texture, layout.sampleType, layout.viewDimension,
                                 layout.multisampled);
             },
-            [&](const StorageTextureBindingLayout& layout) {
+            [&](const StorageTextureBindingInfo& layout) {
                 recorder.Record(BindingInfoType::StorageTexture, layout.access, layout.format,
                                 layout.viewDimension);
             },
diff --git a/src/dawn/native/BindingInfo.cpp b/src/dawn/native/BindingInfo.cpp
index 1ca7259..582598f 100644
--- a/src/dawn/native/BindingInfo.cpp
+++ b/src/dawn/native/BindingInfo.cpp
@@ -39,7 +39,7 @@
         [](const BufferBindingInfo&) -> BindingInfoType { return BindingInfoType::Buffer; },
         [](const SamplerBindingLayout&) -> BindingInfoType { return BindingInfoType::Sampler; },
         [](const TextureBindingLayout&) -> BindingInfoType { return BindingInfoType::Texture; },
-        [](const StorageTextureBindingLayout&) -> BindingInfoType {
+        [](const StorageTextureBindingInfo&) -> BindingInfoType {
             return BindingInfoType::StorageTexture;
         },
         [](const StaticSamplerHolderBindingLayout&) -> BindingInfoType {
@@ -234,4 +234,7 @@
       minBindingSize(apiLayout.minBindingSize),
       hasDynamicOffset(apiLayout.hasDynamicOffset) {}
 
+StorageTextureBindingInfo::StorageTextureBindingInfo() = default;
+StorageTextureBindingInfo::StorageTextureBindingInfo(const StorageTextureBindingLayout& apiLayout)
+    : format(apiLayout.format), viewDimension(apiLayout.viewDimension), access(apiLayout.access) {}
 }  // namespace dawn::native
diff --git a/src/dawn/native/BindingInfo.h b/src/dawn/native/BindingInfo.h
index c53c6ab..a4c941e 100644
--- a/src/dawn/native/BindingInfo.h
+++ b/src/dawn/native/BindingInfo.h
@@ -82,6 +82,16 @@
     bool hasDynamicOffset = false;
 };
 
+// A mirror of wgpu::StorageTextureBindingLayout for use inside dawn::native.
+struct StorageTextureBindingInfo {
+    StorageTextureBindingInfo();
+    explicit StorageTextureBindingInfo(const StorageTextureBindingLayout& apiLayout);
+
+    wgpu::TextureFormat format;
+    wgpu::TextureViewDimension viewDimension;
+    wgpu::StorageTextureAccess access;
+};
+
 struct BindingInfo {
     BindingNumber binding;
     wgpu::ShaderStage visibility;
@@ -89,7 +99,7 @@
     std::variant<BufferBindingInfo,
                  SamplerBindingLayout,
                  TextureBindingLayout,
-                 StorageTextureBindingLayout,
+                 StorageTextureBindingInfo,
                  StaticSamplerHolderBindingLayout>
         bindingLayout;
 };
diff --git a/src/dawn/native/CommandBufferStateTracker.cpp b/src/dawn/native/CommandBufferStateTracker.cpp
index 83a532a..5b94e78 100644
--- a/src/dawn/native/CommandBufferStateTracker.cpp
+++ b/src/dawn/native/CommandBufferStateTracker.cpp
@@ -163,8 +163,7 @@
              bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
             const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
 
-            const auto* layout =
-                std::get_if<StorageTextureBindingLayout>(&bindingInfo.bindingLayout);
+            const auto* layout = std::get_if<StorageTextureBindingInfo>(&bindingInfo.bindingLayout);
             if (layout == nullptr) {
                 continue;
             }
@@ -363,7 +362,7 @@
         for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
             const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
             if (!std::holds_alternative<TextureBindingLayout>(bindingInfo.bindingLayout) &&
-                !std::holds_alternative<StorageTextureBindingLayout>(bindingInfo.bindingLayout)) {
+                !std::holds_alternative<StorageTextureBindingInfo>(bindingInfo.bindingLayout)) {
                 continue;
             }
 
diff --git a/src/dawn/native/PassResourceUsageTracker.cpp b/src/dawn/native/PassResourceUsageTracker.cpp
index 07ab558..71fb8da 100644
--- a/src/dawn/native/PassResourceUsageTracker.cpp
+++ b/src/dawn/native/PassResourceUsageTracker.cpp
@@ -143,7 +143,7 @@
                         break;
                 }
             },
-            [&](const StorageTextureBindingLayout& layout) {
+            [&](const StorageTextureBindingInfo& layout) {
                 TextureViewBase* view = group->GetBindingAsTextureView(bindingIndex);
                 switch (layout.access) {
                     case wgpu::StorageTextureAccess::WriteOnly:
@@ -222,7 +222,7 @@
                 mUsage.referencedTextures.insert(
                     group->GetBindingAsTextureView(index)->GetTexture());
             },
-            [&](const StorageTextureBindingLayout&) {
+            [&](const StorageTextureBindingInfo&) {
                 mUsage.referencedTextures.insert(
                     group->GetBindingAsTextureView(index)->GetTexture());
             },
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 0702c8f..2450591 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -418,7 +418,7 @@
 }
 
 bool IsShaderCompatibleWithPipelineLayoutOnStorageTextureAccess(
-    const StorageTextureBindingLayout& pipelineBindingLayout,
+    const StorageTextureBindingInfo& pipelineBindingLayout,
     const StorageTextureBindingInfo& shaderBindingInfo) {
     return pipelineBindingLayout.access == shaderBindingInfo.access ||
            (pipelineBindingLayout.access == wgpu::StorageTextureAccess::ReadWrite &&
@@ -525,8 +525,8 @@
             return {};
         },
         [&](const StorageTextureBindingInfo& bindingInfo) -> MaybeError {
-            const StorageTextureBindingLayout& bindingLayout =
-                std::get<StorageTextureBindingLayout>(layoutInfo.bindingLayout);
+            const StorageTextureBindingInfo& bindingLayout =
+                std::get<StorageTextureBindingInfo>(layoutInfo.bindingLayout);
             DAWN_ASSERT(bindingLayout.format != wgpu::TextureFormat::Undefined);
             DAWN_ASSERT(bindingInfo.format != wgpu::TextureFormat::Undefined);
 
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h
index 570f080..e61e825 100644
--- a/src/dawn/native/ShaderModule.h
+++ b/src/dawn/native/ShaderModule.h
@@ -172,13 +172,6 @@
 // Mirrors wgpu::ExternalTextureBindingLayout
 struct ExternalTextureBindingInfo {};
 
-// Mirrors wgpu::StorageTextureBindingLayout
-struct StorageTextureBindingInfo {
-    wgpu::TextureFormat format;
-    wgpu::TextureViewDimension viewDimension;
-    wgpu::StorageTextureAccess access;
-};
-
 // Per-binding shader metadata contains some SPIRV specific information in addition to
 // most of the frontend per-binding information.
 struct ShaderBindingInfo {
diff --git a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
index 5467aad..7a10897 100644
--- a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
+++ b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
@@ -206,7 +206,7 @@
                         }
                         return {};
                     },
-                    [&](const StorageTextureBindingLayout& layout) -> MaybeError {
+                    [&](const StorageTextureBindingInfo& layout) -> MaybeError {
                         switch (layout.access) {
                             case wgpu::StorageTextureAccess::WriteOnly:
                             case wgpu::StorageTextureAccess::ReadWrite: {
@@ -415,7 +415,7 @@
                 }
                 return {};
             },
-            [&](const StorageTextureBindingLayout& layout) -> MaybeError {
+            [&](const StorageTextureBindingInfo& layout) -> MaybeError {
                 TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                 switch (layout.access) {
                     case wgpu::StorageTextureAccess::WriteOnly:
@@ -546,7 +546,7 @@
                     deviceContext->CSSetShaderResources(bindingSlot, 1, &nullSRV);
                 }
             },
-            [&](const StorageTextureBindingLayout& layout) {
+            [&](const StorageTextureBindingInfo& layout) {
                 switch (layout.access) {
                     case wgpu::StorageTextureAccess::WriteOnly:
                     case wgpu::StorageTextureAccess::ReadWrite: {
diff --git a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
index 9da7d26..a1243b3 100644
--- a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
+++ b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
@@ -92,7 +92,7 @@
                 [&](const TextureBindingLayout&) {
                     mIndexInfo[group][bindingIndex] = shaderResourceViewIndex++;
                 },
-                [&](const StorageTextureBindingLayout& layout) {
+                [&](const StorageTextureBindingInfo& layout) {
                     switch (layout.access) {
                         case wgpu::StorageTextureAccess::ReadWrite:
                         case wgpu::StorageTextureAccess::WriteOnly:
diff --git a/src/dawn/native/d3d12/BindGroupD3D12.cpp b/src/dawn/native/d3d12/BindGroupD3D12.cpp
index 00a3ce5..991ef64 100644
--- a/src/dawn/native/d3d12/BindGroupD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupD3D12.cpp
@@ -161,7 +161,7 @@
                     viewAllocation.OffsetFrom(viewSizeIncrement,
                                               descriptorHeapOffsets[bindingIndex]));
             },
-            [&](const StorageTextureBindingLayout& layout) {
+            [&](const StorageTextureBindingInfo& layout) {
                 TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
 
                 ID3D12Resource* resource = ToBackend(view->GetTexture())->GetD3D12Resource();
diff --git a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
index 44d621a..fa3a26e 100644
--- a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
@@ -66,7 +66,7 @@
         [](const TextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
             return D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
         },
-        [](const StorageTextureBindingLayout& layout) -> D3D12_DESCRIPTOR_RANGE_TYPE {
+        [](const StorageTextureBindingInfo& layout) -> D3D12_DESCRIPTOR_RANGE_TYPE {
             switch (layout.access) {
                 case wgpu::StorageTextureAccess::WriteOnly:
                 case wgpu::StorageTextureAccess::ReadWrite:
@@ -154,7 +154,7 @@
             [](const TextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
                 return D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
             },
-            [](const StorageTextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+            [](const StorageTextureBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
                 return D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
             });
 
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm
index baadfcb..849df19 100644
--- a/src/dawn/native/metal/CommandBufferMTL.mm
+++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -642,7 +642,7 @@
                         [compute setTexture:textureView->GetMTLTexture() atIndex:computeIndex];
                     }
                 },
-                [&](const StorageTextureBindingLayout&) {
+                [&](const StorageTextureBindingInfo&) {
                     auto textureView = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                     if (hasVertStage) {
                         [render setVertexTexture:textureView->GetMTLTexture() atIndex:vertIndex];
diff --git a/src/dawn/native/metal/PipelineLayoutMTL.mm b/src/dawn/native/metal/PipelineLayoutMTL.mm
index a597277..0873b2d 100644
--- a/src/dawn/native/metal/PipelineLayoutMTL.mm
+++ b/src/dawn/native/metal/PipelineLayoutMTL.mm
@@ -75,7 +75,7 @@
                         mIndexInfo[stage][group][bindingIndex] = textureIndex;
                         textureIndex++;
                     },
-                    [&](const StorageTextureBindingLayout&) {
+                    [&](const StorageTextureBindingInfo&) {
                         mIndexInfo[stage][group][bindingIndex] = textureIndex;
                         textureIndex++;
                     },
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index 0a8012e..554ce2d 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -369,7 +369,7 @@
                     // internal uniform buffer.
                     UpdateTextureBuiltinsUniformData(gl, view, groupIndex, bindingIndex);
                 },
-                [&](const StorageTextureBindingLayout& layout) {
+                [&](const StorageTextureBindingInfo& layout) {
                     TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                     Texture* texture = ToBackend(view->GetTexture());
                     GLuint handle = texture->GetHandle();
diff --git a/src/dawn/native/opengl/PipelineLayoutGL.cpp b/src/dawn/native/opengl/PipelineLayoutGL.cpp
index 4b2a20d..9486d38 100644
--- a/src/dawn/native/opengl/PipelineLayoutGL.cpp
+++ b/src/dawn/native/opengl/PipelineLayoutGL.cpp
@@ -79,7 +79,7 @@
                     mIndexInfo[group][bindingIndex] = sampledTextureIndex;
                     sampledTextureIndex++;
                 },
-                [&](const StorageTextureBindingLayout&) {
+                [&](const StorageTextureBindingInfo&) {
                     mIndexInfo[group][bindingIndex] = storageTextureIndex;
                     storageTextureIndex++;
                 });
diff --git a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
index fb5f2bd..7918c24 100644
--- a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
@@ -88,7 +88,7 @@
         [](const SamplerBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
         [](const StaticSamplerHolderBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
         [](const TextureBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; },
-        [](const StorageTextureBindingLayout&) { return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; });
+        [](const StorageTextureBindingInfo&) { return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; });
 }
 
 // static
diff --git a/src/dawn/native/vulkan/BindGroupVk.cpp b/src/dawn/native/vulkan/BindGroupVk.cpp
index c9f932d..2388de1 100644
--- a/src/dawn/native/vulkan/BindGroupVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupVk.cpp
@@ -129,7 +129,7 @@
                 write.pImageInfo = &writeImageInfo[numWrites];
                 return true;
             },
-            [&](const StorageTextureBindingLayout&) -> bool {
+            [&](const StorageTextureBindingInfo&) -> bool {
                 TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
 
                 VkImageView handle = VK_NULL_HANDLE;
diff --git a/src/dawn/native/webgpu_absl_format.cpp b/src/dawn/native/webgpu_absl_format.cpp
index f20aca2..c069d88 100644
--- a/src/dawn/native/webgpu_absl_format.cpp
+++ b/src/dawn/native/webgpu_absl_format.cpp
@@ -135,7 +135,7 @@
             s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
                                       BindingInfoType::Texture, layout));
         },
-        [&](const StorageTextureBindingLayout& layout) {
+        [&](const StorageTextureBindingInfo& layout) {
             s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
                                       BindingInfoType::StorageTexture, layout));
         });
@@ -160,6 +160,23 @@
 }
 
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const StorageTextureBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    s->Append(absl::StrFormat("{format: %s, viewDimension: %s, access: %s}", value.format,
+                              value.viewDimension, value.access));
+    return {true};
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const StorageTextureBindingLayout& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    StorageTextureBindingInfo info(value);
+    return AbslFormatConvert(info, spec, s);
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const ImageCopyTexture* value,
     const absl::FormatConversionSpec& spec,
     absl::FormatSink* s) {
diff --git a/src/dawn/native/webgpu_absl_format.h b/src/dawn/native/webgpu_absl_format.h
index c3af2f7..a8656af 100644
--- a/src/dawn/native/webgpu_absl_format.h
+++ b/src/dawn/native/webgpu_absl_format.h
@@ -94,6 +94,18 @@
     const absl::FormatConversionSpec& spec,
     absl::FormatSink* s);
 
+struct StorageTextureBindingInfo;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const StorageTextureBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
+struct StorageTextureBindingLayout;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const StorageTextureBindingLayout& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
 struct ImageCopyTexture;
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const ImageCopyTexture* value,